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