]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesImpl.c
ModulePkg/DxeHttpLib: Adding Functions to HttpLib
[mirror_edk2.git] / NetworkPkg / HttpUtilitiesDxe / HttpUtilitiesImpl.c
CommitLineData
d933e70a
JW
1/** @file\r
2 The functions for HttpUtilities driver.\r
3\r
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php.\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "HttpUtilitiesDxe.h"\r
17\r
18\r
19/**\r
20 Get the next string, which is distinguished by specified seperator. \r
21\r
22 @param[in] String Pointer to the string.\r
23 @param[in] Seperator Specified seperator used to distinguish where is the beginning \r
24 of next string.\r
25\r
26 @return Pointer to the next string.\r
27 @return NULL if not find or String is NULL.\r
28\r
29**/\r
30CHAR8 *\r
31AsciiStrGetNextToken (\r
32 IN CONST CHAR8 *String,\r
33 IN CHAR8 Seperator\r
34 )\r
35{\r
36 CONST CHAR8 *Token;\r
37\r
38 Token = String;\r
39 while (TRUE) {\r
40 if (*Token == 0) {\r
41 return NULL;\r
42 }\r
43 if (*Token == Seperator) {\r
44 return (CHAR8 *)(Token + 1);\r
45 }\r
46 Token++;\r
47 }\r
48}\r
49\r
50\r
51/**\r
52 Free existing HeaderFields.\r
53\r
54 @param[in] HeaderFields Pointer to array of key/value header pairs waitting for free.\r
55 @param[in] FieldCount The number of header pairs in HeaderFields.\r
56\r
57**/\r
58VOID\r
59FreeHeaderFields (\r
60 IN EFI_HTTP_HEADER *HeaderFields,\r
61 IN UINTN FieldCount\r
62 )\r
63{\r
64 UINTN Index;\r
65 \r
66 if (HeaderFields != NULL) {\r
67 for (Index = 0; Index < FieldCount; Index++) {\r
68 if (HeaderFields[Index].FieldName != NULL) {\r
69 FreePool (HeaderFields[Index].FieldName);\r
70 }\r
71 if (HeaderFields[Index].FieldValue != NULL) {\r
72 FreePool (HeaderFields[Index].FieldValue);\r
73 }\r
74 }\r
75\r
76 FreePool (HeaderFields);\r
77 }\r
78}\r
79\r
80\r
81/**\r
82 Find required header field in HeaderFields.\r
83\r
84 @param[in] HeaderFields Pointer to array of key/value header pairs.\r
85 @param[in] FieldCount The number of header pairs.\r
86 @param[in] FieldName Pointer to header field's name.\r
87\r
88 @return Pointer to the queried header field.\r
89 @return NULL if not find this required header field.\r
90\r
91**/\r
92EFI_HTTP_HEADER *\r
93FindHttpHeader (\r
94 IN EFI_HTTP_HEADER *HeaderFields,\r
95 IN UINTN FieldCount,\r
96 IN CHAR8 *FieldName\r
97 )\r
98{\r
99 UINTN Index;\r
100\r
101 for (Index = 0; Index < FieldCount; Index++) {\r
102 if (AsciiStrCmp (FieldName, HeaderFields[Index].FieldName) == 0) {\r
103 //\r
104 // Find the required header field.\r
105 //\r
106 return &HeaderFields[Index];\r
107 }\r
108 }\r
109 return NULL;\r
110}\r
111\r
112\r
113/**\r
114 Check whether header field called FieldName is in DeleteList.\r
115\r
116 @param[in] DeleteList Pointer to array of key/value header pairs.\r
117 @param[in] DeleteCount The number of header pairs.\r
118 @param[in] FieldName Pointer to header field's name.\r
119\r
120 @return TRUE if FieldName is not in DeleteList, that means this header field is valid.\r
121 @return FALSE if FieldName is in DeleteList, that means this header field is invalid.\r
122\r
123**/\r
124BOOLEAN\r
125IsValidHttpHeader (\r
126 IN CHAR8 *DeleteList[],\r
127 IN UINTN DeleteCount,\r
128 IN CHAR8 *FieldName\r
129 )\r
130{\r
131 UINTN Index;\r
132\r
133 for (Index = 0; Index < DeleteCount; Index++) {\r
134 if (AsciiStrCmp (FieldName, DeleteList[Index]) == 0) {\r
135 return FALSE;\r
136 }\r
137 }\r
138 \r
139 return TRUE;\r
140}\r
141\r
142\r
143/**\r
144 Set FieldName and FieldValue into specified HttpHeader.\r
145\r
146 @param[in] HttpHeader Specified HttpHeader.\r
147 @param[in] FieldName FieldName of this HttpHeader.\r
148 @param[in] FieldValue FieldValue of this HttpHeader.\r
149\r
150\r
151 @retval EFI_SUCCESS The FieldName and FieldValue are set into HttpHeader successfully.\r
152 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.\r
153\r
154**/\r
155EFI_STATUS\r
156SetFieldNameAndValue (\r
157 IN EFI_HTTP_HEADER *HttpHeader,\r
158 IN CHAR8 *FieldName, \r
159 IN CHAR8 *FieldValue\r
160 )\r
161{ \r
162 UINTN FieldNameSize;\r
163 UINTN FieldValueSize;\r
164\r
165 if (HttpHeader->FieldName != NULL) {\r
166 FreePool (HttpHeader->FieldName);\r
167 }\r
168 if (HttpHeader->FieldValue != NULL) {\r
169 FreePool (HttpHeader->FieldValue);\r
170 }\r
171\r
172 FieldNameSize = AsciiStrSize (FieldName);\r
173 HttpHeader->FieldName = AllocateZeroPool (FieldNameSize);\r
174 if (HttpHeader->FieldName == NULL) {\r
175 return EFI_OUT_OF_RESOURCES;\r
176 }\r
177 CopyMem (HttpHeader->FieldName, FieldName, FieldNameSize);\r
178 HttpHeader->FieldName[FieldNameSize - 1] = 0;\r
179\r
180 FieldValueSize = AsciiStrSize (FieldValue);\r
181 HttpHeader->FieldValue = AllocateZeroPool (FieldValueSize);\r
182 if (HttpHeader->FieldValue == NULL) {\r
183 return EFI_OUT_OF_RESOURCES;\r
184 }\r
185 CopyMem (HttpHeader->FieldValue, FieldValue, FieldValueSize);\r
186 HttpHeader->FieldValue[FieldValueSize - 1] = 0;\r
187\r
188 return EFI_SUCCESS;\r
189}\r
190\r
191\r
192/**\r
193 Get one key/value header pair from the raw string.\r
194\r
195 @param[in] String Pointer to the raw string.\r
196 @param[out] FieldName Pointer to header field's name.\r
197 @param[out] FieldValue Pointer to header field's value.\r
198\r
199 @return Pointer to the next raw string.\r
200 @return NULL if no key/value header pair from this raw string.\r
201\r
202**/\r
203CHAR8 *\r
204GetFieldNameAndValue (\r
205 IN CHAR8 *String,\r
206 OUT CHAR8 **FieldName,\r
207 OUT CHAR8 **FieldValue\r
208 )\r
209{\r
210 CHAR8 *FieldNameStr;\r
211 CHAR8 *FieldValueStr;\r
212 CHAR8 *StrPtr;\r
213\r
214 if (String == NULL || FieldName == NULL || FieldValue == NULL) {\r
215 return NULL;\r
216 }\r
217 \r
218 *FieldName = NULL;\r
219 *FieldValue = NULL;\r
220 FieldNameStr = NULL;\r
221 FieldValueStr = NULL;\r
222 StrPtr = NULL;\r
223\r
224 //\r
225 // Each header field consists of a name followed by a colon (":") and the field value.\r
226 //\r
227 FieldNameStr = String;\r
228 FieldValueStr = AsciiStrGetNextToken (FieldNameStr, ':');\r
229 if (FieldValueStr == NULL) {\r
230 return NULL;\r
231 }\r
232 \r
233 //\r
234 // Replace ':' with 0\r
235 //\r
236 *(FieldValueStr - 1) = 0; \r
237 \r
238 //\r
239 // The field value MAY be preceded by any amount of LWS, though a single SP is preferred.\r
240 //\r
241 while (TRUE) {\r
242 if (*FieldValueStr == ' ' || *FieldValueStr == '\t') {\r
243 FieldValueStr ++;\r
244 } else if (*FieldValueStr == '\r' && *(FieldValueStr + 1) == '\n' && \r
245 (*(FieldValueStr + 2) == ' ' || *(FieldValueStr + 2) == '\t')) {\r
246 FieldValueStr = FieldValueStr + 3;\r
247 } else {\r
248 break;\r
249 }\r
250 }\r
251\r
252 //\r
253 // Header fields can be extended over multiple lines by preceding each extra \r
254 // line with at least one SP or HT.\r
255 //\r
256 StrPtr = FieldValueStr;\r
257 do {\r
258 StrPtr = AsciiStrGetNextToken (StrPtr, '\r');\r
259 if (StrPtr == NULL || *StrPtr != '\n') {\r
260 return NULL;\r
261 }\r
262 \r
263 StrPtr++;\r
264 } while (*StrPtr == ' ' || *StrPtr == '\t');\r
265\r
266 //\r
267 // Replace '\r' with 0\r
268 //\r
269 *(StrPtr - 2) = 0; \r
270\r
271 //\r
272 // Get FieldName and FieldValue.\r
273 //\r
274 *FieldName = FieldNameStr;\r
275 *FieldValue = FieldValueStr;\r
276 \r
277 return StrPtr;\r
278}\r
279\r