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 * 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 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 * 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 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 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 * 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