Changeset 99404 in vbox for trunk/src/VBox/Devices/EFI/FirmwareNew/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
- Timestamp:
- Apr 14, 2023 3:17:44 PM (2 years ago)
- svn:sync-xref-src-repo-rev:
- 156854
- Location:
- trunk/src/VBox/Devices/EFI/FirmwareNew
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/FirmwareNew
-
Property svn:mergeinfo
changed from (toggle deleted branches)
to (toggle deleted branches)/vendor/edk2/current 103735-103757,103769-103776,129194-145445 /vendor/edk2/current 103735-103757,103769-103776,129194-156846
-
Property svn:mergeinfo
changed from (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/FirmwareNew/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
r89983 r99404 10 10 11 11 #include "DxeHttpLib.h" 12 13 14 12 15 13 /** … … 32 30 EFIAPI 33 31 UriPercentDecode ( 34 IN CHAR8 35 IN UINT32 36 OUT CHAR8*ResultBuffer,37 OUT UINT32*ResultLength38 ) 39 { 40 UINTN 41 UINTN 42 CHAR8 43 44 if ( Buffer == NULL || BufferLength == 0 || ResultBuffer == NULL) {32 IN CHAR8 *Buffer, 33 IN UINT32 BufferLength, 34 OUT CHAR8 *ResultBuffer, 35 OUT UINT32 *ResultLength 36 ) 37 { 38 UINTN Index; 39 UINTN Offset; 40 CHAR8 HexStr[3]; 41 42 if ((Buffer == NULL) || (BufferLength == 0) || (ResultBuffer == NULL)) { 45 43 return EFI_INVALID_PARAMETER; 46 44 } 47 45 48 Index = 0;49 Offset = 0;46 Index = 0; 47 Offset = 0; 50 48 HexStr[2] = '\0'; 51 49 while (Index < BufferLength) { 52 50 if (Buffer[Index] == '%') { 53 if (Index + 1 >= BufferLength || Index + 2 >= BufferLength || 54 !NET_IS_HEX_CHAR (Buffer[Index+1]) || !NET_IS_HEX_CHAR (Buffer[Index+2])) { 51 if ((Index + 1 >= BufferLength) || (Index + 2 >= BufferLength) || 52 !NET_IS_HEX_CHAR (Buffer[Index+1]) || !NET_IS_HEX_CHAR (Buffer[Index+2])) 53 { 55 54 return EFI_INVALID_PARAMETER; 56 55 } 57 HexStr[0] = Buffer[Index+1]; 58 HexStr[1] = Buffer[Index+2]; 59 ResultBuffer[Offset] = (CHAR8) AsciiStrHexToUintn (HexStr); 60 Index += 3; 56 57 HexStr[0] = Buffer[Index+1]; 58 HexStr[1] = Buffer[Index+2]; 59 ResultBuffer[Offset] = (CHAR8)AsciiStrHexToUintn (HexStr); 60 Index += 3; 61 61 } else { 62 62 ResultBuffer[Offset] = Buffer[Index]; 63 63 Index++; 64 64 } 65 65 66 Offset++; 66 67 } 67 68 68 *ResultLength = (UINT32) 69 *ResultLength = (UINT32)Offset; 69 70 70 71 return EFI_SUCCESS; … … 84 85 HTTP_URL_PARSE_STATE 85 86 NetHttpParseAuthorityChar ( 86 IN CHAR8 Char, 87 IN HTTP_URL_PARSE_STATE State, 88 IN BOOLEAN *IsRightBracket 89 ) 90 { 91 87 IN CHAR8 Char, 88 IN HTTP_URL_PARSE_STATE State, 89 IN BOOLEAN *IsRightBracket 90 ) 91 { 92 92 // 93 93 // RFC 3986: … … 96 96 // sign ("#") character, or by the end of the URI. 97 97 // 98 if ( Char == ' ' || Char == '\r' || Char == '\n') {98 if ((Char == ' ') || (Char == '\r') || (Char == '\n')) { 99 99 return UrlParserStateMax; 100 100 } … … 104 104 // 105 105 switch (State) { 106 case UrlParserUserInfo: 107 if (Char == '@') { 108 return UrlParserHostStart; 109 } 110 break; 111 112 case UrlParserHost: 113 case UrlParserHostStart: 114 if (Char == '[') { 106 case UrlParserUserInfo: 107 if (Char == '@') { 108 return UrlParserHostStart; 109 } 110 111 break; 112 113 case UrlParserHost: 114 case UrlParserHostStart: 115 if (Char == '[') { 116 return UrlParserHostIpv6; 117 } 118 119 if (Char == ':') { 120 return UrlParserPortStart; 121 } 122 123 return UrlParserHost; 124 125 case UrlParserHostIpv6: 126 if (Char == ']') { 127 *IsRightBracket = TRUE; 128 } 129 130 if ((Char == ':') && *IsRightBracket) { 131 return UrlParserPortStart; 132 } 133 115 134 return UrlParserHostIpv6; 116 } 117 118 if (Char == ':') { 119 return UrlParserPortStart; 120 } 121 122 return UrlParserHost; 123 124 case UrlParserHostIpv6: 125 if (Char == ']') { 126 *IsRightBracket = TRUE; 127 } 128 129 if (Char == ':' && *IsRightBracket) { 130 return UrlParserPortStart; 131 } 132 return UrlParserHostIpv6; 133 134 case UrlParserPort: 135 case UrlParserPortStart: 136 return UrlParserPort; 137 138 default: 139 break; 135 136 case UrlParserPort: 137 case UrlParserPortStart: 138 return UrlParserPort; 139 140 default: 141 break; 140 142 } 141 143 … … 156 158 EFI_STATUS 157 159 NetHttpParseAuthority ( 158 IN CHAR8 159 IN BOOLEAN 160 IN OUT HTTP_URL_PARSER 160 IN CHAR8 *Url, 161 IN BOOLEAN FoundAt, 162 IN OUT HTTP_URL_PARSER *UrlParser 161 163 ) 162 164 { … … 181 183 182 184 IsrightBracket = FALSE; 183 Field = HTTP_URI_FIELD_MAX;184 OldField = Field;185 Authority = Url + UrlParser->FieldData[HTTP_URI_FIELD_AUTHORITY].Offset;186 Length = UrlParser->FieldData[HTTP_URI_FIELD_AUTHORITY].Length;185 Field = HTTP_URI_FIELD_MAX; 186 OldField = Field; 187 Authority = Url + UrlParser->FieldData[HTTP_URI_FIELD_AUTHORITY].Offset; 188 Length = UrlParser->FieldData[HTTP_URI_FIELD_AUTHORITY].Length; 187 189 for (Char = Authority; Char < Authority + Length; Char++) { 188 190 State = NetHttpParseAuthorityChar (*Char, State, &IsrightBracket); 189 191 switch (State) { 190 case UrlParserStateMax:191 return EFI_INVALID_PARAMETER;192 193 case UrlParserHostStart:194 case UrlParserPortStart:195 continue;196 197 case UrlParserUserInfo:198 Field = HTTP_URI_FIELD_USERINFO;199 break;200 201 case UrlParserHost:202 Field = HTTP_URI_FIELD_HOST;203 break;204 205 case UrlParserHostIpv6:206 Field = HTTP_URI_FIELD_HOST;207 break;208 209 case UrlParserPort:210 Field = HTTP_URI_FIELD_PORT;211 break;212 213 default:214 ASSERT (FALSE);192 case UrlParserStateMax: 193 return EFI_INVALID_PARAMETER; 194 195 case UrlParserHostStart: 196 case UrlParserPortStart: 197 continue; 198 199 case UrlParserUserInfo: 200 Field = HTTP_URI_FIELD_USERINFO; 201 break; 202 203 case UrlParserHost: 204 Field = HTTP_URI_FIELD_HOST; 205 break; 206 207 case UrlParserHostIpv6: 208 Field = HTTP_URI_FIELD_HOST; 209 break; 210 211 case UrlParserPort: 212 Field = HTTP_URI_FIELD_PORT; 213 break; 214 215 default: 216 ASSERT (FALSE); 215 217 } 216 218 … … 227 229 // New field start 228 230 // 229 UrlParser->FieldBitMap |= BIT (Field);230 UrlParser->FieldData[Field].Offset = (UINT32) 231 UrlParser->FieldBitMap |= BIT (Field); 232 UrlParser->FieldData[Field].Offset = (UINT32)(Char - Url); 231 233 UrlParser->FieldData[Field].Length = 1; 232 OldField = Field;234 OldField = Field; 233 235 } 234 236 … … 247 249 HTTP_URL_PARSE_STATE 248 250 NetHttpParseUrlChar ( 249 IN CHAR8 250 IN HTTP_URL_PARSE_STATE 251 ) 252 { 253 if ( Char == ' ' || Char == '\r' || Char == '\n') {251 IN CHAR8 Char, 252 IN HTTP_URL_PARSE_STATE State 253 ) 254 { 255 if ((Char == ' ') || (Char == '\r') || (Char == '\n')) { 254 256 return UrlParserStateMax; 255 257 } … … 265 267 // 266 268 switch (State) { 267 case UrlParserUrlStart: 268 if (Char == '*' || Char == '/') { 269 return UrlParserPath; 270 } 271 return UrlParserScheme; 272 273 case UrlParserScheme: 274 if (Char == ':') { 275 return UrlParserSchemeColon; 276 } 277 break; 278 279 case UrlParserSchemeColon: 280 if (Char == '/') { 281 return UrlParserSchemeColonSlash; 282 } 283 break; 284 285 case UrlParserSchemeColonSlash: 286 if (Char == '/') { 287 return UrlParserSchemeColonSlashSlash; 288 } 289 break; 290 291 case UrlParserAtInAuthority: 292 if (Char == '@') { 293 return UrlParserStateMax; 294 } 295 296 case UrlParserAuthority: 297 case UrlParserSchemeColonSlashSlash: 298 if (Char == '@') { 299 return UrlParserAtInAuthority; 300 } 301 if (Char == '/') { 302 return UrlParserPath; 303 } 304 if (Char == '?') { 305 return UrlParserQueryStart; 306 } 307 if (Char == '#') { 308 return UrlParserFragmentStart; 309 } 310 return UrlParserAuthority; 311 312 case UrlParserPath: 313 if (Char == '?') { 314 return UrlParserQueryStart; 315 } 316 if (Char == '#') { 317 return UrlParserFragmentStart; 318 } 319 break; 320 321 case UrlParserQuery: 322 case UrlParserQueryStart: 323 if (Char == '#') { 324 return UrlParserFragmentStart; 325 } 326 return UrlParserQuery; 327 328 case UrlParserFragmentStart: 329 return UrlParserFragment; 330 331 default: 332 break; 269 case UrlParserUrlStart: 270 if ((Char == '*') || (Char == '/')) { 271 return UrlParserPath; 272 } 273 274 return UrlParserScheme; 275 276 case UrlParserScheme: 277 if (Char == ':') { 278 return UrlParserSchemeColon; 279 } 280 281 break; 282 283 case UrlParserSchemeColon: 284 if (Char == '/') { 285 return UrlParserSchemeColonSlash; 286 } 287 288 break; 289 290 case UrlParserSchemeColonSlash: 291 if (Char == '/') { 292 return UrlParserSchemeColonSlashSlash; 293 } 294 295 break; 296 297 case UrlParserAtInAuthority: 298 if (Char == '@') { 299 return UrlParserStateMax; 300 } 301 302 case UrlParserAuthority: 303 case UrlParserSchemeColonSlashSlash: 304 if (Char == '@') { 305 return UrlParserAtInAuthority; 306 } 307 308 if (Char == '/') { 309 return UrlParserPath; 310 } 311 312 if (Char == '?') { 313 return UrlParserQueryStart; 314 } 315 316 if (Char == '#') { 317 return UrlParserFragmentStart; 318 } 319 320 return UrlParserAuthority; 321 322 case UrlParserPath: 323 if (Char == '?') { 324 return UrlParserQueryStart; 325 } 326 327 if (Char == '#') { 328 return UrlParserFragmentStart; 329 } 330 331 break; 332 333 case UrlParserQuery: 334 case UrlParserQueryStart: 335 if (Char == '#') { 336 return UrlParserFragmentStart; 337 } 338 339 return UrlParserQuery; 340 341 case UrlParserFragmentStart: 342 return UrlParserFragment; 343 344 default: 345 break; 333 346 } 334 347 335 348 return State; 336 349 } 350 337 351 /** 338 352 Create a URL parser for the input URL string. … … 355 369 EFIAPI 356 370 HttpParseUrl ( 357 IN CHAR8 358 IN UINT32 359 IN BOOLEAN 360 OUT VOID**UrlParser371 IN CHAR8 *Url, 372 IN UINT32 Length, 373 IN BOOLEAN IsConnectMethod, 374 OUT VOID **UrlParser 361 375 ) 362 376 { … … 371 385 Parser = NULL; 372 386 373 if ( Url == NULL || Length == 0 || UrlParser == NULL) {387 if ((Url == NULL) || (Length == 0) || (UrlParser == NULL)) { 374 388 return EFI_INVALID_PARAMETER; 375 389 } … … 389 403 } 390 404 391 Field = HTTP_URI_FIELD_MAX;405 Field = HTTP_URI_FIELD_MAX; 392 406 OldField = Field; 393 FoundAt = FALSE;407 FoundAt = FALSE; 394 408 for (Char = Url; Char < Url + Length; Char++) { 395 409 // … … 399 413 400 414 switch (State) { 401 case UrlParserStateMax:402 FreePool (Parser);403 return EFI_INVALID_PARAMETER;404 405 case UrlParserSchemeColon:406 case UrlParserSchemeColonSlash:407 case UrlParserSchemeColonSlashSlash:408 case UrlParserQueryStart:409 case UrlParserFragmentStart:410 //411 // Skip all the delimiting char: "://" "?" "@"412 //413 continue;414 415 case UrlParserScheme:416 Field = HTTP_URI_FIELD_SCHEME;417 break;418 419 case UrlParserAtInAuthority:420 FoundAt = TRUE;421 case UrlParserAuthority:422 Field = HTTP_URI_FIELD_AUTHORITY;423 break;424 425 case UrlParserPath:426 Field = HTTP_URI_FIELD_PATH;427 break;428 429 case UrlParserQuery:430 Field = HTTP_URI_FIELD_QUERY;431 break;432 433 case UrlParserFragment:434 Field = HTTP_URI_FIELD_FRAGMENT;435 break;436 437 default:438 ASSERT (FALSE);415 case UrlParserStateMax: 416 FreePool (Parser); 417 return EFI_INVALID_PARAMETER; 418 419 case UrlParserSchemeColon: 420 case UrlParserSchemeColonSlash: 421 case UrlParserSchemeColonSlashSlash: 422 case UrlParserQueryStart: 423 case UrlParserFragmentStart: 424 // 425 // Skip all the delimiting char: "://" "?" "@" 426 // 427 continue; 428 429 case UrlParserScheme: 430 Field = HTTP_URI_FIELD_SCHEME; 431 break; 432 433 case UrlParserAtInAuthority: 434 FoundAt = TRUE; 435 case UrlParserAuthority: 436 Field = HTTP_URI_FIELD_AUTHORITY; 437 break; 438 439 case UrlParserPath: 440 Field = HTTP_URI_FIELD_PATH; 441 break; 442 443 case UrlParserQuery: 444 Field = HTTP_URI_FIELD_QUERY; 445 break; 446 447 case UrlParserFragment: 448 Field = HTTP_URI_FIELD_FRAGMENT; 449 break; 450 451 default: 452 ASSERT (FALSE); 439 453 } 440 454 … … 451 465 // New field start 452 466 // 453 Parser->FieldBitMap |= BIT (Field);454 Parser->FieldData[Field].Offset = (UINT32) 467 Parser->FieldBitMap |= BIT (Field); 468 Parser->FieldData[Field].Offset = (UINT32)(Char - Url); 455 469 Parser->FieldData[Field].Length = 1; 456 OldField = Field;470 OldField = Field; 457 471 } 458 472 … … 491 505 EFIAPI 492 506 HttpUrlGetHostName ( 493 IN CHAR8 494 IN VOID 495 OUT CHAR8**HostName496 ) 497 { 498 CHAR8 499 EFI_STATUS 500 UINT32 501 HTTP_URL_PARSER 502 503 if ( Url == NULL || UrlParser == NULL || HostName == NULL) {507 IN CHAR8 *Url, 508 IN VOID *UrlParser, 509 OUT CHAR8 **HostName 510 ) 511 { 512 CHAR8 *Name; 513 EFI_STATUS Status; 514 UINT32 ResultLength; 515 HTTP_URL_PARSER *Parser; 516 517 if ((Url == NULL) || (UrlParser == NULL) || (HostName == NULL)) { 504 518 return EFI_INVALID_PARAMETER; 505 519 } 506 520 507 Parser = (HTTP_URL_PARSER *) 521 Parser = (HTTP_URL_PARSER *)UrlParser; 508 522 509 523 if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) { … … 528 542 529 543 Name[ResultLength] = '\0'; 530 *HostName = Name;544 *HostName = Name; 531 545 return EFI_SUCCESS; 532 546 } 533 534 547 535 548 /** … … 551 564 EFIAPI 552 565 HttpUrlGetIp4 ( 553 IN CHAR8 554 IN VOID 555 OUT EFI_IPv4_ADDRESS*Ip4Address556 ) 557 { 558 CHAR8 559 EFI_STATUS 560 UINT32 561 HTTP_URL_PARSER 562 563 if ( Url == NULL || UrlParser == NULL || Ip4Address == NULL) {566 IN CHAR8 *Url, 567 IN VOID *UrlParser, 568 OUT EFI_IPv4_ADDRESS *Ip4Address 569 ) 570 { 571 CHAR8 *Ip4String; 572 EFI_STATUS Status; 573 UINT32 ResultLength; 574 HTTP_URL_PARSER *Parser; 575 576 if ((Url == NULL) || (UrlParser == NULL) || (Ip4Address == NULL)) { 564 577 return EFI_INVALID_PARAMETER; 565 578 } 566 579 567 Parser = (HTTP_URL_PARSER *) 580 Parser = (HTTP_URL_PARSER *)UrlParser; 568 581 569 582 if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) { … … 588 601 589 602 Ip4String[ResultLength] = '\0'; 590 Status = NetLibAsciiStrToIp4 (Ip4String, Ip4Address);603 Status = NetLibAsciiStrToIp4 (Ip4String, Ip4Address); 591 604 FreePool (Ip4String); 592 605 … … 612 625 EFIAPI 613 626 HttpUrlGetIp6 ( 614 IN CHAR8 615 IN VOID 616 OUT EFI_IPv6_ADDRESS*Ip6Address617 ) 618 { 619 CHAR8 620 CHAR8 621 UINT32 622 EFI_STATUS 623 UINT32 624 HTTP_URL_PARSER 625 626 if ( Url == NULL || UrlParser == NULL || Ip6Address == NULL) {627 IN CHAR8 *Url, 628 IN VOID *UrlParser, 629 OUT EFI_IPv6_ADDRESS *Ip6Address 630 ) 631 { 632 CHAR8 *Ip6String; 633 CHAR8 *Ptr; 634 UINT32 Length; 635 EFI_STATUS Status; 636 UINT32 ResultLength; 637 HTTP_URL_PARSER *Parser; 638 639 if ((Url == NULL) || (UrlParser == NULL) || (Ip6Address == NULL)) { 627 640 return EFI_INVALID_PARAMETER; 628 641 } 629 642 630 Parser = (HTTP_URL_PARSER *) 643 Parser = (HTTP_URL_PARSER *)UrlParser; 631 644 632 645 if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) { … … 642 655 } 643 656 644 Ptr 657 Ptr = Url + Parser->FieldData[HTTP_URI_FIELD_HOST].Offset; 645 658 if ((Ptr[0] != '[') || (Ptr[Length - 1] != ']')) { 646 659 return EFI_INVALID_PARAMETER; … … 664 677 665 678 Ip6String[ResultLength] = '\0'; 666 Status = NetLibAsciiStrToIp6 (Ip6String, Ip6Address);679 Status = NetLibAsciiStrToIp6 (Ip6String, Ip6Address); 667 680 FreePool (Ip6String); 668 681 … … 688 701 EFIAPI 689 702 HttpUrlGetPort ( 690 IN CHAR8 691 IN VOID 692 OUT UINT16*Port693 ) 694 { 695 CHAR8 696 EFI_STATUS 697 UINTN 698 UINTN 699 UINT32 700 HTTP_URL_PARSER 701 702 if ( Url == NULL || UrlParser == NULL || Port == NULL) {703 IN CHAR8 *Url, 704 IN VOID *UrlParser, 705 OUT UINT16 *Port 706 ) 707 { 708 CHAR8 *PortString; 709 EFI_STATUS Status; 710 UINTN Index; 711 UINTN Data; 712 UINT32 ResultLength; 713 HTTP_URL_PARSER *Parser; 714 715 if ((Url == NULL) || (UrlParser == NULL) || (Port == NULL)) { 703 716 return EFI_INVALID_PARAMETER; 704 717 } … … 707 720 Index = 0; 708 721 709 Parser = (HTTP_URL_PARSER *) 722 Parser = (HTTP_URL_PARSER *)UrlParser; 710 723 711 724 if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_PORT)) == 0) { … … 735 748 goto ON_EXIT; 736 749 } 737 Index ++; 738 } 739 740 Status = AsciiStrDecimalToUintnS (Url + Parser->FieldData[HTTP_URI_FIELD_PORT].Offset, (CHAR8 **) NULL, &Data); 750 751 Index++; 752 } 753 754 Status = AsciiStrDecimalToUintnS (Url + Parser->FieldData[HTTP_URI_FIELD_PORT].Offset, (CHAR8 **)NULL, &Data); 741 755 742 756 if (Data > HTTP_URI_PORT_MAX_NUM) { … … 745 759 } 746 760 747 *Port = (UINT16) 761 *Port = (UINT16)Data; 748 762 749 763 ON_EXIT: … … 771 785 EFIAPI 772 786 HttpUrlGetPath ( 773 IN CHAR8 774 IN VOID 775 OUT CHAR8**Path776 ) 777 { 778 CHAR8 779 EFI_STATUS 780 UINT32 781 HTTP_URL_PARSER 782 783 if ( Url == NULL || UrlParser == NULL || Path == NULL) {787 IN CHAR8 *Url, 788 IN VOID *UrlParser, 789 OUT CHAR8 **Path 790 ) 791 { 792 CHAR8 *PathStr; 793 EFI_STATUS Status; 794 UINT32 ResultLength; 795 HTTP_URL_PARSER *Parser; 796 797 if ((Url == NULL) || (UrlParser == NULL) || (Path == NULL)) { 784 798 return EFI_INVALID_PARAMETER; 785 799 } 786 800 787 Parser = (HTTP_URL_PARSER *) 801 Parser = (HTTP_URL_PARSER *)UrlParser; 788 802 789 803 if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_PATH)) == 0) { … … 808 822 809 823 PathStr[ResultLength] = '\0'; 810 *Path = PathStr;824 *Path = PathStr; 811 825 return EFI_SUCCESS; 812 826 } … … 821 835 EFIAPI 822 836 HttpUrlFreeParser ( 823 IN VOID 837 IN VOID *UrlParser 824 838 ) 825 839 { … … 840 854 EFIAPI 841 855 HttpFindHeader ( 842 IN UINTN 843 IN EFI_HTTP_HEADER 844 IN CHAR8 845 ) 846 { 847 UINTN 848 849 if ( HeaderCount == 0 || Headers == NULL || FieldName == NULL) {856 IN UINTN HeaderCount, 857 IN EFI_HTTP_HEADER *Headers, 858 IN CHAR8 *FieldName 859 ) 860 { 861 UINTN Index; 862 863 if ((HeaderCount == 0) || (Headers == NULL) || (FieldName == NULL)) { 850 864 return NULL; 851 865 } 852 866 853 for (Index = 0; Index < HeaderCount; Index++) {867 for (Index = 0; Index < HeaderCount; Index++) { 854 868 // 855 869 // Field names are case-insensitive (RFC 2616). … … 859 873 } 860 874 } 875 861 876 return NULL; 862 877 } … … 880 895 881 896 typedef struct { 882 BOOLEAN IgnoreBody;// "MUST NOT" include a message-body883 BOOLEAN IsChunked;// "chunked" transfer-coding.884 BOOLEAN 885 UINTN ContentLength;// Entity length (not the message-body length), invalid until ContentLengthIsValid is TRUE886 887 HTTP_BODY_PARSER_CALLBACK 888 VOID 889 UINTN 890 HTTP_BODY_PARSE_STATE 891 UINTN 892 UINTN 897 BOOLEAN IgnoreBody; // "MUST NOT" include a message-body 898 BOOLEAN IsChunked; // "chunked" transfer-coding. 899 BOOLEAN ContentLengthIsValid; 900 UINTN ContentLength; // Entity length (not the message-body length), invalid until ContentLengthIsValid is TRUE 901 902 HTTP_BODY_PARSER_CALLBACK Callback; 903 VOID *Context; 904 UINTN ParsedBodyLength; 905 HTTP_BODY_PARSE_STATE State; 906 UINTN CurrentChunkSize; 907 UINTN CurrentChunkParsedSize; 893 908 } HTTP_BODY_PARSER; 894 909 … … 903 918 UINTN 904 919 HttpIoHexCharToUintn ( 905 IN CHAR8 906 ) 907 { 908 if ( Char >= '0' && Char <= '9') {920 IN CHAR8 Char 921 ) 922 { 923 if ((Char >= '0') && (Char <= '9')) { 909 924 return Char - '0'; 910 925 } … … 926 941 EFI_STATUS 927 942 HttpIoParseContentLengthHeader ( 928 IN UINTN 929 IN EFI_HTTP_HEADER 930 OUT UINTN*ContentLength931 ) 932 { 933 EFI_HTTP_HEADER 943 IN UINTN HeaderCount, 944 IN EFI_HTTP_HEADER *Headers, 945 OUT UINTN *ContentLength 946 ) 947 { 948 EFI_HTTP_HEADER *Header; 934 949 935 950 Header = HttpFindHeader (HeaderCount, Headers, HTTP_HEADER_CONTENT_LENGTH); … … 938 953 } 939 954 940 return AsciiStrDecimalToUintnS (Header->FieldValue, (CHAR8 **) 955 return AsciiStrDecimalToUintnS (Header->FieldValue, (CHAR8 **)NULL, ContentLength); 941 956 } 942 957 … … 953 968 BOOLEAN 954 969 HttpIoIsChunked ( 955 IN UINTN HeaderCount, 956 IN EFI_HTTP_HEADER *Headers 957 ) 958 { 959 EFI_HTTP_HEADER *Header; 960 970 IN UINTN HeaderCount, 971 IN EFI_HTTP_HEADER *Headers 972 ) 973 { 974 EFI_HTTP_HEADER *Header; 961 975 962 976 Header = HttpFindHeader (HeaderCount, Headers, HTTP_HEADER_TRANSFER_ENCODING); … … 983 997 BOOLEAN 984 998 HttpIoNoMessageBody ( 985 IN EFI_HTTP_METHOD 986 IN EFI_HTTP_STATUS_CODE 999 IN EFI_HTTP_METHOD Method, 1000 IN EFI_HTTP_STATUS_CODE StatusCode 987 1001 ) 988 1002 { … … 1035 1049 EFIAPI 1036 1050 HttpInitMsgParser ( 1037 IN EFI_HTTP_METHOD 1038 IN EFI_HTTP_STATUS_CODE 1039 IN UINTN 1040 IN EFI_HTTP_HEADER 1041 IN HTTP_BODY_PARSER_CALLBACK 1042 IN VOID 1043 OUT VOID**MsgParser1044 ) 1045 { 1046 EFI_STATUS 1047 HTTP_BODY_PARSER 1048 1049 if ( HeaderCount != 0 && Headers == NULL) {1051 IN EFI_HTTP_METHOD Method, 1052 IN EFI_HTTP_STATUS_CODE StatusCode, 1053 IN UINTN HeaderCount, 1054 IN EFI_HTTP_HEADER *Headers, 1055 IN HTTP_BODY_PARSER_CALLBACK Callback, 1056 IN VOID *Context, 1057 OUT VOID **MsgParser 1058 ) 1059 { 1060 EFI_STATUS Status; 1061 HTTP_BODY_PARSER *Parser; 1062 1063 if ((HeaderCount != 0) && (Headers == NULL)) { 1050 1064 return EFI_INVALID_PARAMETER; 1051 1065 } … … 1070 1084 // 2. Check whether the message using "chunked" transfer-coding. 1071 1085 // 1072 Parser->IsChunked 1086 Parser->IsChunked = HttpIoIsChunked (HeaderCount, Headers); 1073 1087 // 1074 1088 // 3. Check whether the message has a Content-Length header field. … … 1078 1092 Parser->ContentLengthIsValid = TRUE; 1079 1093 } 1094 1080 1095 // 1081 1096 // 4. Range header is not supported now, so we won't meet media type "multipart/byteranges". … … 1115 1130 EFIAPI 1116 1131 HttpParseMessageBody ( 1117 IN OUT VOID 1118 IN UINTN 1119 IN CHAR8 1120 ) 1121 { 1122 CHAR8 1123 UINTN 1124 UINTN 1125 UINTN 1126 EFI_STATUS 1127 HTTP_BODY_PARSER 1128 1129 if ( BodyLength == 0 || Body == NULL) {1132 IN OUT VOID *MsgParser, 1133 IN UINTN BodyLength, 1134 IN CHAR8 *Body 1135 ) 1136 { 1137 CHAR8 *Char; 1138 UINTN RemainderLengthInThis; 1139 UINTN LengthForCallback; 1140 UINTN PortionLength; 1141 EFI_STATUS Status; 1142 HTTP_BODY_PARSER *Parser; 1143 1144 if ((BodyLength == 0) || (Body == NULL)) { 1130 1145 return EFI_INVALID_PARAMETER; 1131 1146 } … … 1135 1150 } 1136 1151 1137 Parser = (HTTP_BODY_PARSER *) 1152 Parser = (HTTP_BODY_PARSER *)MsgParser; 1138 1153 1139 1154 if (Parser->IgnoreBody) { … … 1150 1165 } 1151 1166 } 1167 1152 1168 return EFI_SUCCESS; 1153 1169 } … … 1166 1182 // 1167 1183 for (Char = Body; Char < Body + BodyLength; ) { 1168 1169 1184 switch (Parser->State) { 1170 case BodyParserStateMax: 1171 return EFI_ABORTED; 1172 1173 case BodyParserBodyIdentity: 1174 // 1175 // Identity transfer-coding, just notify user to save the body data. 1176 // 1177 PortionLength = MIN ( 1178 BodyLength, 1179 Parser->ContentLength - Parser->ParsedBodyLength 1180 ); 1181 if (PortionLength == 0) { 1185 case BodyParserStateMax: 1186 return EFI_ABORTED; 1187 1188 case BodyParserBodyIdentity: 1182 1189 // 1183 // Got BodyLength, but no ContentLength. Use BodyLength.1190 // Identity transfer-coding, just notify user to save the body data. 1184 1191 // 1185 PortionLength = BodyLength; 1186 Parser->ContentLength = PortionLength; 1187 } 1188 1189 if (Parser->Callback != NULL) { 1190 Status = Parser->Callback ( 1191 BodyParseEventOnData, 1192 Char, 1193 PortionLength, 1194 Parser->Context 1195 ); 1196 if (EFI_ERROR (Status)) { 1197 return Status; 1192 PortionLength = MIN ( 1193 BodyLength, 1194 Parser->ContentLength - Parser->ParsedBodyLength 1195 ); 1196 if (PortionLength == 0) { 1197 // 1198 // Got BodyLength, but no ContentLength. Use BodyLength. 1199 // 1200 PortionLength = BodyLength; 1201 Parser->ContentLength = PortionLength; 1198 1202 } 1199 } 1200 Char += PortionLength; 1201 Parser->ParsedBodyLength += PortionLength; 1202 if (Parser->ParsedBodyLength == Parser->ContentLength) { 1203 Parser->State = BodyParserComplete; 1203 1204 1204 if (Parser->Callback != NULL) { 1205 1205 Status = Parser->Callback ( 1206 BodyParseEventOn Complete,1206 BodyParseEventOnData, 1207 1207 Char, 1208 0,1208 PortionLength, 1209 1209 Parser->Context 1210 1210 ); … … 1213 1213 } 1214 1214 } 1215 } 1216 break; 1217 1218 case BodyParserChunkSizeStart: 1219 // 1220 // First byte of chunk-size, the chunk-size might be truncated. 1221 // 1222 Parser->CurrentChunkSize = 0; 1223 Parser->State = BodyParserChunkSize; 1224 case BodyParserChunkSize: 1225 if (!NET_IS_HEX_CHAR (*Char)) { 1226 if (*Char == ';') { 1227 Parser->State = BodyParserChunkExtStart; 1215 1216 Char += PortionLength; 1217 Parser->ParsedBodyLength += PortionLength; 1218 if (Parser->ParsedBodyLength == Parser->ContentLength) { 1219 Parser->State = BodyParserComplete; 1220 if (Parser->Callback != NULL) { 1221 Status = Parser->Callback ( 1222 BodyParseEventOnComplete, 1223 Char, 1224 0, 1225 Parser->Context 1226 ); 1227 if (EFI_ERROR (Status)) { 1228 return Status; 1229 } 1230 } 1231 } 1232 1233 break; 1234 1235 case BodyParserChunkSizeStart: 1236 // 1237 // First byte of chunk-size, the chunk-size might be truncated. 1238 // 1239 Parser->CurrentChunkSize = 0; 1240 Parser->State = BodyParserChunkSize; 1241 case BodyParserChunkSize: 1242 if (!NET_IS_HEX_CHAR (*Char)) { 1243 if (*Char == ';') { 1244 Parser->State = BodyParserChunkExtStart; 1245 Char++; 1246 } else if (*Char == '\r') { 1247 Parser->State = BodyParserChunkSizeEndCR; 1248 Char++; 1249 } else { 1250 Parser->State = BodyParserStateMax; 1251 } 1252 1253 break; 1254 } 1255 1256 if (Parser->CurrentChunkSize > (((~((UINTN)0)) - 16) / 16)) { 1257 return EFI_INVALID_PARAMETER; 1258 } 1259 1260 Parser->CurrentChunkSize = Parser->CurrentChunkSize * 16 + HttpIoHexCharToUintn (*Char); 1261 Char++; 1262 break; 1263 1264 case BodyParserChunkExtStart: 1265 // 1266 // Ignore all the chunk extensions. 1267 // 1268 if (*Char == '\r') { 1269 Parser->State = BodyParserChunkSizeEndCR; 1270 } 1271 1272 Char++; 1273 break; 1274 1275 case BodyParserChunkSizeEndCR: 1276 if (*Char != '\n') { 1277 Parser->State = BodyParserStateMax; 1278 break; 1279 } 1280 1281 Char++; 1282 if (Parser->CurrentChunkSize == 0) { 1283 // 1284 // The last chunk has been parsed and now assumed the state 1285 // of HttpBodyParse is ParserLastCRLF. So it need to decide 1286 // whether the rest message is trailer or last CRLF in the next round. 1287 // 1288 Parser->ContentLengthIsValid = TRUE; 1289 Parser->State = BodyParserLastCRLF; 1290 break; 1291 } 1292 1293 Parser->State = BodyParserChunkDataStart; 1294 Parser->CurrentChunkParsedSize = 0; 1295 break; 1296 1297 case BodyParserLastCRLF: 1298 // 1299 // Judge the byte is belong to the Last CRLF or trailer, and then 1300 // configure the state of HttpBodyParse to corresponding state. 1301 // 1302 if (*Char == '\r') { 1228 1303 Char++; 1229 } else if (*Char == '\r') { 1230 Parser->State = BodyParserChunkSizeEndCR; 1304 Parser->State = BodyParserLastCRLFEnd; 1305 break; 1306 } else { 1307 Parser->State = BodyParserTrailer; 1308 break; 1309 } 1310 1311 case BodyParserLastCRLFEnd: 1312 if (*Char == '\n') { 1313 Parser->State = BodyParserComplete; 1231 1314 Char++; 1315 if (Parser->Callback != NULL) { 1316 Status = Parser->Callback ( 1317 BodyParseEventOnComplete, 1318 Char, 1319 0, 1320 Parser->Context 1321 ); 1322 if (EFI_ERROR (Status)) { 1323 return Status; 1324 } 1325 } 1326 1327 break; 1232 1328 } else { 1233 1329 Parser->State = BodyParserStateMax; 1330 break; 1234 1331 } 1235 break; 1236 } 1237 1238 if (Parser->CurrentChunkSize > (((~((UINTN) 0)) - 16) / 16)) { 1239 return EFI_INVALID_PARAMETER; 1240 } 1241 Parser->CurrentChunkSize = Parser->CurrentChunkSize * 16 + HttpIoHexCharToUintn (*Char); 1242 Char++; 1243 break; 1244 1245 case BodyParserChunkExtStart: 1246 // 1247 // Ignore all the chunk extensions. 1248 // 1249 if (*Char == '\r') { 1250 Parser->State = BodyParserChunkSizeEndCR; 1251 } 1252 Char++; 1253 break; 1254 1255 case BodyParserChunkSizeEndCR: 1256 if (*Char != '\n') { 1257 Parser->State = BodyParserStateMax; 1258 break; 1259 } 1260 Char++; 1261 if (Parser->CurrentChunkSize == 0) { 1332 1333 case BodyParserTrailer: 1334 if (*Char == '\r') { 1335 Parser->State = BodyParserChunkSizeEndCR; 1336 } 1337 1338 Char++; 1339 break; 1340 1341 case BodyParserChunkDataStart: 1262 1342 // 1263 // The last chunk has been parsed and now assumed the state 1264 // of HttpBodyParse is ParserLastCRLF. So it need to decide 1265 // whether the rest message is trailer or last CRLF in the next round. 1343 // First byte of chunk-data, the chunk data also might be truncated. 1266 1344 // 1267 Parser->ContentLengthIsValid = TRUE; 1268 Parser->State = BodyParserLastCRLF; 1269 break; 1270 } 1271 Parser->State = BodyParserChunkDataStart; 1272 Parser->CurrentChunkParsedSize = 0; 1273 break; 1274 1275 case BodyParserLastCRLF: 1276 // 1277 // Judge the byte is belong to the Last CRLF or trailer, and then 1278 // configure the state of HttpBodyParse to corresponding state. 1279 // 1280 if (*Char == '\r') { 1281 Char++; 1282 Parser->State = BodyParserLastCRLFEnd; 1283 break; 1284 } else { 1285 Parser->State = BodyParserTrailer; 1286 break; 1287 } 1288 1289 case BodyParserLastCRLFEnd: 1290 if (*Char == '\n') { 1291 Parser->State = BodyParserComplete; 1292 Char++; 1345 RemainderLengthInThis = BodyLength - (Char - Body); 1346 LengthForCallback = MIN (Parser->CurrentChunkSize - Parser->CurrentChunkParsedSize, RemainderLengthInThis); 1293 1347 if (Parser->Callback != NULL) { 1294 1348 Status = Parser->Callback ( 1295 BodyParseEventOn Complete,1349 BodyParseEventOnData, 1296 1350 Char, 1297 0,1351 LengthForCallback, 1298 1352 Parser->Context 1299 1353 ); … … 1302 1356 } 1303 1357 } 1304 break; 1305 } else { 1306 Parser->State = BodyParserStateMax; 1307 break; 1308 } 1309 1310 case BodyParserTrailer: 1311 if (*Char == '\r') { 1312 Parser->State = BodyParserChunkSizeEndCR; 1313 } 1314 Char++; 1315 break; 1316 1317 case BodyParserChunkDataStart: 1318 // 1319 // First byte of chunk-data, the chunk data also might be truncated. 1320 // 1321 RemainderLengthInThis = BodyLength - (Char - Body); 1322 LengthForCallback = MIN (Parser->CurrentChunkSize - Parser->CurrentChunkParsedSize, RemainderLengthInThis); 1323 if (Parser->Callback != NULL) { 1324 Status = Parser->Callback ( 1325 BodyParseEventOnData, 1326 Char, 1327 LengthForCallback, 1328 Parser->Context 1329 ); 1330 if (EFI_ERROR (Status)) { 1331 return Status; 1358 1359 Char += LengthForCallback; 1360 Parser->ContentLength += LengthForCallback; 1361 Parser->CurrentChunkParsedSize += LengthForCallback; 1362 if (Parser->CurrentChunkParsedSize == Parser->CurrentChunkSize) { 1363 Parser->State = BodyParserChunkDataEnd; 1332 1364 } 1333 } 1334 Char += LengthForCallback; 1335 Parser->ContentLength += LengthForCallback; 1336 Parser->CurrentChunkParsedSize += LengthForCallback; 1337 if (Parser->CurrentChunkParsedSize == Parser->CurrentChunkSize) { 1338 Parser->State = BodyParserChunkDataEnd; 1339 } 1340 break; 1341 1342 case BodyParserChunkDataEnd: 1343 if (*Char == '\r') { 1344 Parser->State = BodyParserChunkDataEndCR; 1345 } else { 1346 Parser->State = BodyParserStateMax; 1347 } 1348 Char++; 1349 break; 1350 1351 case BodyParserChunkDataEndCR: 1352 if (*Char != '\n') { 1353 Parser->State = BodyParserStateMax; 1354 break; 1355 } 1356 Char++; 1357 Parser->State = BodyParserChunkSizeStart; 1358 break; 1359 1360 default: 1361 break; 1362 } 1363 1365 1366 break; 1367 1368 case BodyParserChunkDataEnd: 1369 if (*Char == '\r') { 1370 Parser->State = BodyParserChunkDataEndCR; 1371 } else { 1372 Parser->State = BodyParserStateMax; 1373 } 1374 1375 Char++; 1376 break; 1377 1378 case BodyParserChunkDataEndCR: 1379 if (*Char != '\n') { 1380 Parser->State = BodyParserStateMax; 1381 break; 1382 } 1383 1384 Char++; 1385 Parser->State = BodyParserChunkSizeStart; 1386 break; 1387 1388 default: 1389 break; 1390 } 1364 1391 } 1365 1392 … … 1383 1410 EFIAPI 1384 1411 HttpIsMessageComplete ( 1385 IN VOID 1386 ) 1387 { 1388 HTTP_BODY_PARSER 1412 IN VOID *MsgParser 1413 ) 1414 { 1415 HTTP_BODY_PARSER *Parser; 1389 1416 1390 1417 if (MsgParser == NULL) { … … 1392 1419 } 1393 1420 1394 Parser = (HTTP_BODY_PARSER *) 1421 Parser = (HTTP_BODY_PARSER *)MsgParser; 1395 1422 1396 1423 if (Parser->State == BodyParserComplete) { 1397 1424 return TRUE; 1398 1425 } 1426 1399 1427 return FALSE; 1400 1428 } … … 1416 1444 EFIAPI 1417 1445 HttpGetEntityLength ( 1418 IN VOID 1419 OUT UINTN 1420 ) 1421 { 1422 HTTP_BODY_PARSER 1423 1424 if ( MsgParser == NULL || ContentLength == NULL) {1446 IN VOID *MsgParser, 1447 OUT UINTN *ContentLength 1448 ) 1449 { 1450 HTTP_BODY_PARSER *Parser; 1451 1452 if ((MsgParser == NULL) || (ContentLength == NULL)) { 1425 1453 return EFI_INVALID_PARAMETER; 1426 1454 } 1427 1455 1428 Parser = (HTTP_BODY_PARSER *) 1456 Parser = (HTTP_BODY_PARSER *)MsgParser; 1429 1457 1430 1458 if (!Parser->ContentLengthIsValid) { … … 1445 1473 EFIAPI 1446 1474 HttpFreeMsgParser ( 1447 IN VOID 1475 IN VOID *MsgParser 1448 1476 ) 1449 1477 { 1450 1478 FreePool (MsgParser); 1451 1479 } 1452 1453 1480 1454 1481 /** … … 1465 1492 CHAR8 * 1466 1493 AsciiStrGetNextToken ( 1467 IN CONST CHAR8 *String,1468 IN CHAR8 Separator1469 ) 1470 { 1471 CONST CHAR8 *Token;1494 IN CONST CHAR8 *String, 1495 IN CHAR8 Separator 1496 ) 1497 { 1498 CONST CHAR8 *Token; 1472 1499 1473 1500 Token = String; … … 1476 1503 return NULL; 1477 1504 } 1505 1478 1506 if (*Token == Separator) { 1479 1507 return (CHAR8 *)(Token + 1); 1480 1508 } 1509 1481 1510 Token++; 1482 1511 } … … 1499 1528 EFIAPI 1500 1529 HttpSetFieldNameAndValue ( 1501 IN OUT EFI_HTTP_HEADER 1502 IN CONST CHAR8 1503 IN CONST CHAR8 1504 ) 1505 { 1506 UINTN 1507 UINTN 1508 1509 if ( HttpHeader == NULL || FieldName == NULL || FieldValue == NULL) {1530 IN OUT EFI_HTTP_HEADER *HttpHeader, 1531 IN CONST CHAR8 *FieldName, 1532 IN CONST CHAR8 *FieldValue 1533 ) 1534 { 1535 UINTN FieldNameSize; 1536 UINTN FieldValueSize; 1537 1538 if ((HttpHeader == NULL) || (FieldName == NULL) || (FieldValue == NULL)) { 1510 1539 return EFI_INVALID_PARAMETER; 1511 1540 } … … 1514 1543 FreePool (HttpHeader->FieldName); 1515 1544 } 1545 1516 1546 if (HttpHeader->FieldValue != NULL) { 1517 1547 FreePool (HttpHeader->FieldValue); 1518 1548 } 1519 1549 1520 FieldNameSize = AsciiStrSize (FieldName);1550 FieldNameSize = AsciiStrSize (FieldName); 1521 1551 HttpHeader->FieldName = AllocateZeroPool (FieldNameSize); 1522 1552 if (HttpHeader->FieldName == NULL) { 1523 1553 return EFI_OUT_OF_RESOURCES; 1524 1554 } 1555 1525 1556 CopyMem (HttpHeader->FieldName, FieldName, FieldNameSize); 1526 1557 HttpHeader->FieldName[FieldNameSize - 1] = 0; 1527 1558 1528 FieldValueSize = AsciiStrSize (FieldValue);1559 FieldValueSize = AsciiStrSize (FieldValue); 1529 1560 HttpHeader->FieldValue = AllocateZeroPool (FieldValueSize); 1530 1561 if (HttpHeader->FieldValue == NULL) { … … 1532 1563 return EFI_OUT_OF_RESOURCES; 1533 1564 } 1565 1534 1566 CopyMem (HttpHeader->FieldValue, FieldValue, FieldValueSize); 1535 1567 HttpHeader->FieldValue[FieldValueSize - 1] = 0; … … 1552 1584 EFIAPI 1553 1585 HttpGetFieldNameAndValue ( 1554 IN CHAR8 1555 OUT CHAR8**FieldName,1556 OUT CHAR8**FieldValue1586 IN CHAR8 *String, 1587 OUT CHAR8 **FieldName, 1588 OUT CHAR8 **FieldValue 1557 1589 ) 1558 1590 { … … 1562 1594 CHAR8 *EndofHeader; 1563 1595 1564 if ( String == NULL || FieldName == NULL || FieldValue == NULL) {1596 if ((String == NULL) || (FieldName == NULL) || (FieldValue == NULL)) { 1565 1597 return NULL; 1566 1598 } … … 1573 1605 EndofHeader = NULL; 1574 1606 1575 1576 1607 // 1577 1608 // Check whether the raw HTTP header string is valid or not. … … 1597 1628 // HT = '\t' (Tab). 1598 1629 // 1599 FieldNameStr = String;1630 FieldNameStr = String; 1600 1631 FieldValueStr = AsciiStrGetNextToken (FieldNameStr, ':'); 1601 1632 if (FieldValueStr == NULL) { … … 1612 1643 // 1613 1644 while (TRUE) { 1614 if ( *FieldValueStr == ' ' || *FieldValueStr == '\t') {1645 if ((*FieldValueStr == ' ') || (*FieldValueStr == '\t')) { 1615 1646 // 1616 1647 // Boundary condition check. 1617 1648 // 1618 if ((UINTN) EndofHeader - (UINTN)FieldValueStr < 1) {1649 if ((UINTN)EndofHeader - (UINTN)FieldValueStr < 1) { 1619 1650 // 1620 1651 // Wrong String format! … … 1623 1654 } 1624 1655 1625 FieldValueStr 1656 FieldValueStr++; 1626 1657 } else if (*FieldValueStr == '\r') { 1627 1658 // 1628 1659 // Boundary condition check. 1629 1660 // 1630 if ((UINTN) EndofHeader - (UINTN)FieldValueStr < 3) {1661 if ((UINTN)EndofHeader - (UINTN)FieldValueStr < 3) { 1631 1662 // 1632 1663 // No more preceded LWS, so break here. … … 1636 1667 1637 1668 if (*(FieldValueStr + 1) == '\n' ) { 1638 if ( *(FieldValueStr + 2) == ' ' || *(FieldValueStr + 2) == '\t') {1669 if ((*(FieldValueStr + 2) == ' ') || (*(FieldValueStr + 2) == '\t')) { 1639 1670 FieldValueStr = FieldValueStr + 3; 1640 1671 } else { … … 1664 1695 // 1665 1696 StrPtr = AsciiStrGetNextToken (StrPtr, '\r'); 1666 if ( StrPtr == NULL || *StrPtr != '\n') {1697 if ((StrPtr == NULL) || (*StrPtr != '\n')) { 1667 1698 // 1668 1699 // Wrong String format! … … 1682 1713 // Get FieldName and FieldValue. 1683 1714 // 1684 *FieldName = FieldNameStr;1715 *FieldName = FieldNameStr; 1685 1716 *FieldValue = FieldValueStr; 1686 1717 … … 1702 1733 ) 1703 1734 { 1704 UINTN 1735 UINTN Index; 1705 1736 1706 1737 if (HeaderFields != NULL) { … … 1709 1740 FreePool (HeaderFields[Index].FieldName); 1710 1741 } 1742 1711 1743 if (HeaderFields[Index].FieldValue != NULL) { 1712 1744 FreePool (HeaderFields[Index].FieldValue); … … 1742 1774 EFIAPI 1743 1775 HttpGenRequestMessage ( 1744 IN CONST EFI_HTTP_MESSAGE 1745 IN CONST CHAR8 1746 OUT CHAR8**RequestMsg,1747 OUT UINTN*RequestMsgSize1748 ) 1749 { 1750 EFI_STATUS 1751 UINTN 1752 CHAR8 1753 UINTN 1754 UINTN 1755 BOOLEAN 1756 VOID 1757 EFI_HTTP_HEADER 1758 UINTN 1759 EFI_HTTP_UTILITIES_PROTOCOL 1776 IN CONST EFI_HTTP_MESSAGE *Message, 1777 IN CONST CHAR8 *Url, 1778 OUT CHAR8 **RequestMsg, 1779 OUT UINTN *RequestMsgSize 1780 ) 1781 { 1782 EFI_STATUS Status; 1783 UINTN StrLength; 1784 CHAR8 *RequestPtr; 1785 UINTN HttpHdrSize; 1786 UINTN MsgSize; 1787 BOOLEAN Success; 1788 VOID *HttpHdr; 1789 EFI_HTTP_HEADER **AppendList; 1790 UINTN Index; 1791 EFI_HTTP_UTILITIES_PROTOCOL *HttpUtilitiesProtocol; 1760 1792 1761 1793 Status = EFI_SUCCESS; … … 1773 1805 // 4. If we do not have Request and Headers, we need at least a message-body 1774 1806 // 1775 if ((Message == NULL || RequestMsg == NULL || RequestMsgSize == NULL) || 1776 (Message->Data.Request != NULL && Url == NULL) || 1777 (Message->Data.Request != NULL && Message->HeaderCount == 0) || 1778 (Message->Data.Request == NULL && Message->HeaderCount != 0) || 1779 (Message->Data.Request == NULL && Message->HeaderCount == 0 && Message->BodyLength == 0)) { 1807 if (((Message == NULL) || (RequestMsg == NULL) || (RequestMsgSize == NULL)) || 1808 ((Message->Data.Request != NULL) && (Url == NULL)) || 1809 ((Message->Data.Request != NULL) && (Message->HeaderCount == 0)) || 1810 ((Message->Data.Request == NULL) && (Message->HeaderCount != 0)) || 1811 ((Message->Data.Request == NULL) && (Message->HeaderCount == 0) && (Message->BodyLength == 0))) 1812 { 1780 1813 return EFI_INVALID_PARAMETER; 1781 1814 } … … 1788 1821 &gEfiHttpUtilitiesProtocolGuid, 1789 1822 NULL, 1790 (VOID **) 1823 (VOID **)&HttpUtilitiesProtocol 1791 1824 ); 1792 1825 1793 1826 if (EFI_ERROR (Status)) { 1794 DEBUG ((DEBUG_ERROR, "Failed to locate Http Utilities protocol. Status = %r.\n", Status));1827 DEBUG ((DEBUG_ERROR, "Failed to locate Http Utilities protocol. Status = %r.\n", Status)); 1795 1828 return Status; 1796 1829 } … … 1804 1837 } 1805 1838 1806 for (Index = 0; Index < Message->HeaderCount; Index++){1839 for (Index = 0; Index < Message->HeaderCount; Index++) { 1807 1840 AppendList[Index] = &Message->Headers[Index]; 1808 1841 } … … 1825 1858 FreePool (AppendList); 1826 1859 1827 if (EFI_ERROR (Status) || HttpHdr == NULL){1860 if (EFI_ERROR (Status) || (HttpHdr == NULL)) { 1828 1861 return Status; 1829 1862 } … … 1843 1876 MsgSize += HTTP_METHOD_MAXIMUM_LEN + AsciiStrLen (HTTP_VERSION_CRLF_STR) + AsciiStrLen (Url); 1844 1877 } 1845 1846 1878 1847 1879 // … … 1866 1898 if (Message->Data.Request != NULL) { 1867 1899 switch (Message->Data.Request->Method) { 1868 case HttpMethodGet:1869 StrLength = sizeof (HTTP_METHOD_GET) - 1;1870 CopyMem (RequestPtr, HTTP_METHOD_GET, StrLength);1871 RequestPtr += StrLength;1872 break;1873 case HttpMethodPut:1874 StrLength = sizeof (HTTP_METHOD_PUT) - 1;1875 CopyMem (RequestPtr, HTTP_METHOD_PUT, StrLength);1876 RequestPtr += StrLength;1877 break;1878 case HttpMethodPatch:1879 StrLength = sizeof (HTTP_METHOD_PATCH) - 1;1880 CopyMem (RequestPtr, HTTP_METHOD_PATCH, StrLength);1881 RequestPtr += StrLength;1882 break;1883 case HttpMethodPost:1884 StrLength = sizeof (HTTP_METHOD_POST) - 1;1885 CopyMem (RequestPtr, HTTP_METHOD_POST, StrLength);1886 RequestPtr += StrLength;1887 break;1888 case HttpMethodHead:1889 StrLength = sizeof (HTTP_METHOD_HEAD) - 1;1890 CopyMem (RequestPtr, HTTP_METHOD_HEAD, StrLength);1891 RequestPtr += StrLength;1892 break;1893 case HttpMethodDelete:1894 StrLength = sizeof (HTTP_METHOD_DELETE) - 1;1895 CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength);1896 RequestPtr += StrLength;1897 break;1898 default:1899 ASSERT (FALSE);1900 Status = EFI_INVALID_PARAMETER;1901 goto Exit;1902 } 1903 1904 StrLength = AsciiStrLen (EMPTY_SPACE);1900 case HttpMethodGet: 1901 StrLength = sizeof (HTTP_METHOD_GET) - 1; 1902 CopyMem (RequestPtr, HTTP_METHOD_GET, StrLength); 1903 RequestPtr += StrLength; 1904 break; 1905 case HttpMethodPut: 1906 StrLength = sizeof (HTTP_METHOD_PUT) - 1; 1907 CopyMem (RequestPtr, HTTP_METHOD_PUT, StrLength); 1908 RequestPtr += StrLength; 1909 break; 1910 case HttpMethodPatch: 1911 StrLength = sizeof (HTTP_METHOD_PATCH) - 1; 1912 CopyMem (RequestPtr, HTTP_METHOD_PATCH, StrLength); 1913 RequestPtr += StrLength; 1914 break; 1915 case HttpMethodPost: 1916 StrLength = sizeof (HTTP_METHOD_POST) - 1; 1917 CopyMem (RequestPtr, HTTP_METHOD_POST, StrLength); 1918 RequestPtr += StrLength; 1919 break; 1920 case HttpMethodHead: 1921 StrLength = sizeof (HTTP_METHOD_HEAD) - 1; 1922 CopyMem (RequestPtr, HTTP_METHOD_HEAD, StrLength); 1923 RequestPtr += StrLength; 1924 break; 1925 case HttpMethodDelete: 1926 StrLength = sizeof (HTTP_METHOD_DELETE) - 1; 1927 CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength); 1928 RequestPtr += StrLength; 1929 break; 1930 default: 1931 ASSERT (FALSE); 1932 Status = EFI_INVALID_PARAMETER; 1933 goto Exit; 1934 } 1935 1936 StrLength = AsciiStrLen (EMPTY_SPACE); 1905 1937 CopyMem (RequestPtr, EMPTY_SPACE, StrLength); 1906 1938 RequestPtr += StrLength; … … 1935 1967 // 1936 1968 (*RequestMsgSize) = (UINTN)(RequestPtr) - (UINTN)(*RequestMsg); 1937 Success = TRUE;1969 Success = TRUE; 1938 1970 1939 1971 Exit: … … 1943 1975 FreePool (*RequestMsg); 1944 1976 } 1977 1945 1978 *RequestMsg = NULL; 1946 1979 return Status; … … 1966 1999 EFIAPI 1967 2000 HttpMappingToStatusCode ( 1968 IN UINTN 2001 IN UINTN StatusCode 1969 2002 ) 1970 2003 { 1971 2004 switch (StatusCode) { 1972 case 100:1973 return HTTP_STATUS_100_CONTINUE;1974 case 101:1975 return HTTP_STATUS_101_SWITCHING_PROTOCOLS;1976 case 200:1977 return HTTP_STATUS_200_OK;1978 case 201:1979 return HTTP_STATUS_201_CREATED;1980 case 202:1981 return HTTP_STATUS_202_ACCEPTED;1982 case 203:1983 return HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION;1984 case 204:1985 return HTTP_STATUS_204_NO_CONTENT;1986 case 205:1987 return HTTP_STATUS_205_RESET_CONTENT;1988 case 206:1989 return HTTP_STATUS_206_PARTIAL_CONTENT;1990 case 300:1991 return HTTP_STATUS_300_MULTIPLE_CHOICES;1992 case 301:1993 return HTTP_STATUS_301_MOVED_PERMANENTLY;1994 case 302:1995 return HTTP_STATUS_302_FOUND;1996 case 303:1997 return HTTP_STATUS_303_SEE_OTHER;1998 case 304:1999 return HTTP_STATUS_304_NOT_MODIFIED;2000 case 305:2001 return HTTP_STATUS_305_USE_PROXY;2002 case 307:2003 return HTTP_STATUS_307_TEMPORARY_REDIRECT;2004 case 308:2005 return HTTP_STATUS_308_PERMANENT_REDIRECT;2006 case 400:2007 return HTTP_STATUS_400_BAD_REQUEST;2008 case 401:2009 return HTTP_STATUS_401_UNAUTHORIZED;2010 case 402:2011 return HTTP_STATUS_402_PAYMENT_REQUIRED;2012 case 403:2013 return HTTP_STATUS_403_FORBIDDEN;2014 case 404:2015 return HTTP_STATUS_404_NOT_FOUND;2016 case 405:2017 return HTTP_STATUS_405_METHOD_NOT_ALLOWED;2018 case 406:2019 return HTTP_STATUS_406_NOT_ACCEPTABLE;2020 case 407:2021 return HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED;2022 case 408:2023 return HTTP_STATUS_408_REQUEST_TIME_OUT;2024 case 409:2025 return HTTP_STATUS_409_CONFLICT;2026 case 410:2027 return HTTP_STATUS_410_GONE;2028 case 411:2029 return HTTP_STATUS_411_LENGTH_REQUIRED;2030 case 412:2031 return HTTP_STATUS_412_PRECONDITION_FAILED;2032 case 413:2033 return HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE;2034 case 414:2035 return HTTP_STATUS_414_REQUEST_URI_TOO_LARGE;2036 case 415:2037 return HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE;2038 case 416:2039 return HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED;2040 case 417:2041 return HTTP_STATUS_417_EXPECTATION_FAILED;2042 case 500:2043 return HTTP_STATUS_500_INTERNAL_SERVER_ERROR;2044 case 501:2045 return HTTP_STATUS_501_NOT_IMPLEMENTED;2046 case 502:2047 return HTTP_STATUS_502_BAD_GATEWAY;2048 case 503:2049 return HTTP_STATUS_503_SERVICE_UNAVAILABLE;2050 case 504:2051 return HTTP_STATUS_504_GATEWAY_TIME_OUT;2052 case 505:2053 return HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED;2054 2055 default:2056 return HTTP_STATUS_UNSUPPORTED_STATUS;2005 case 100: 2006 return HTTP_STATUS_100_CONTINUE; 2007 case 101: 2008 return HTTP_STATUS_101_SWITCHING_PROTOCOLS; 2009 case 200: 2010 return HTTP_STATUS_200_OK; 2011 case 201: 2012 return HTTP_STATUS_201_CREATED; 2013 case 202: 2014 return HTTP_STATUS_202_ACCEPTED; 2015 case 203: 2016 return HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION; 2017 case 204: 2018 return HTTP_STATUS_204_NO_CONTENT; 2019 case 205: 2020 return HTTP_STATUS_205_RESET_CONTENT; 2021 case 206: 2022 return HTTP_STATUS_206_PARTIAL_CONTENT; 2023 case 300: 2024 return HTTP_STATUS_300_MULTIPLE_CHOICES; 2025 case 301: 2026 return HTTP_STATUS_301_MOVED_PERMANENTLY; 2027 case 302: 2028 return HTTP_STATUS_302_FOUND; 2029 case 303: 2030 return HTTP_STATUS_303_SEE_OTHER; 2031 case 304: 2032 return HTTP_STATUS_304_NOT_MODIFIED; 2033 case 305: 2034 return HTTP_STATUS_305_USE_PROXY; 2035 case 307: 2036 return HTTP_STATUS_307_TEMPORARY_REDIRECT; 2037 case 308: 2038 return HTTP_STATUS_308_PERMANENT_REDIRECT; 2039 case 400: 2040 return HTTP_STATUS_400_BAD_REQUEST; 2041 case 401: 2042 return HTTP_STATUS_401_UNAUTHORIZED; 2043 case 402: 2044 return HTTP_STATUS_402_PAYMENT_REQUIRED; 2045 case 403: 2046 return HTTP_STATUS_403_FORBIDDEN; 2047 case 404: 2048 return HTTP_STATUS_404_NOT_FOUND; 2049 case 405: 2050 return HTTP_STATUS_405_METHOD_NOT_ALLOWED; 2051 case 406: 2052 return HTTP_STATUS_406_NOT_ACCEPTABLE; 2053 case 407: 2054 return HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED; 2055 case 408: 2056 return HTTP_STATUS_408_REQUEST_TIME_OUT; 2057 case 409: 2058 return HTTP_STATUS_409_CONFLICT; 2059 case 410: 2060 return HTTP_STATUS_410_GONE; 2061 case 411: 2062 return HTTP_STATUS_411_LENGTH_REQUIRED; 2063 case 412: 2064 return HTTP_STATUS_412_PRECONDITION_FAILED; 2065 case 413: 2066 return HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE; 2067 case 414: 2068 return HTTP_STATUS_414_REQUEST_URI_TOO_LARGE; 2069 case 415: 2070 return HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE; 2071 case 416: 2072 return HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED; 2073 case 417: 2074 return HTTP_STATUS_417_EXPECTATION_FAILED; 2075 case 500: 2076 return HTTP_STATUS_500_INTERNAL_SERVER_ERROR; 2077 case 501: 2078 return HTTP_STATUS_501_NOT_IMPLEMENTED; 2079 case 502: 2080 return HTTP_STATUS_502_BAD_GATEWAY; 2081 case 503: 2082 return HTTP_STATUS_503_SERVICE_UNAVAILABLE; 2083 case 504: 2084 return HTTP_STATUS_504_GATEWAY_TIME_OUT; 2085 case 505: 2086 return HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED; 2087 2088 default: 2089 return HTTP_STATUS_UNSUPPORTED_STATUS; 2057 2090 } 2058 2091 } … … 2072 2105 EFIAPI 2073 2106 HttpIsValidHttpHeader ( 2074 IN CHAR8 2075 IN UINTN 2076 IN CHAR8 2077 ) 2078 { 2079 UINTN 2107 IN CHAR8 *DeleteList[], 2108 IN UINTN DeleteCount, 2109 IN CHAR8 *FieldName 2110 ) 2111 { 2112 UINTN Index; 2080 2113 2081 2114 if (FieldName == NULL) { … … 2096 2129 } 2097 2130 2098 2099 2131 /** 2100 2132 Create a HTTP_IO_HEADER to hold the HTTP header items. … … 2107 2139 HTTP_IO_HEADER * 2108 2140 HttpIoCreateHeader ( 2109 UINTN 2110 ) 2111 { 2112 HTTP_IO_HEADER 2141 UINTN MaxHeaderCount 2142 ) 2143 { 2144 HTTP_IO_HEADER *HttpIoHeader; 2113 2145 2114 2146 if (MaxHeaderCount == 0) { … … 2122 2154 2123 2155 HttpIoHeader->MaxHeaderCount = MaxHeaderCount; 2124 HttpIoHeader->Headers = (EFI_HTTP_HEADER *)(HttpIoHeader + 1);2156 HttpIoHeader->Headers = (EFI_HTTP_HEADER *)(HttpIoHeader + 1); 2125 2157 2126 2158 return HttpIoHeader; … … 2135 2167 VOID 2136 2168 HttpIoFreeHeader ( 2137 IN HTTP_IO_HEADER 2138 ) 2139 { 2140 UINTN 2169 IN HTTP_IO_HEADER *HttpIoHeader 2170 ) 2171 { 2172 UINTN Index; 2141 2173 2142 2174 if (HttpIoHeader != NULL) { … … 2148 2180 } 2149 2181 } 2182 2150 2183 FreePool (HttpIoHeader); 2151 2184 } … … 2167 2200 EFI_STATUS 2168 2201 HttpIoSetHeader ( 2169 IN HTTP_IO_HEADER 2170 IN CHAR8 2171 IN CHAR8 2172 ) 2173 { 2174 EFI_HTTP_HEADER 2175 UINTN 2176 CHAR8 2177 2178 if ( HttpIoHeader == NULL || FieldName == NULL || FieldValue == NULL) {2202 IN HTTP_IO_HEADER *HttpIoHeader, 2203 IN CHAR8 *FieldName, 2204 IN CHAR8 *FieldValue 2205 ) 2206 { 2207 EFI_HTTP_HEADER *Header; 2208 UINTN StrSize; 2209 CHAR8 *NewFieldValue; 2210 2211 if ((HttpIoHeader == NULL) || (FieldName == NULL) || (FieldValue == NULL)) { 2179 2212 return EFI_INVALID_PARAMETER; 2180 2213 } … … 2188 2221 return EFI_OUT_OF_RESOURCES; 2189 2222 } 2223 2190 2224 Header = &HttpIoHeader->Headers[HttpIoHeader->HeaderCount]; 2191 2225 2192 StrSize = AsciiStrSize (FieldName);2226 StrSize = AsciiStrSize (FieldName); 2193 2227 Header->FieldName = AllocatePool (StrSize); 2194 2228 if (Header->FieldName == NULL) { 2195 2229 return EFI_OUT_OF_RESOURCES; 2196 2230 } 2231 2197 2232 CopyMem (Header->FieldName, FieldName, StrSize); 2198 2233 Header->FieldName[StrSize -1] = '\0'; 2199 2234 2200 StrSize = AsciiStrSize (FieldValue);2235 StrSize = AsciiStrSize (FieldValue); 2201 2236 Header->FieldValue = AllocatePool (StrSize); 2202 2237 if (Header->FieldValue == NULL) { … … 2204 2239 return EFI_OUT_OF_RESOURCES; 2205 2240 } 2241 2206 2242 CopyMem (Header->FieldValue, FieldValue, StrSize); 2207 2243 Header->FieldValue[StrSize -1] = '\0'; … … 2212 2248 // Update an existing one. 2213 2249 // 2214 StrSize = AsciiStrSize (FieldValue);2250 StrSize = AsciiStrSize (FieldValue); 2215 2251 NewFieldValue = AllocatePool (StrSize); 2216 2252 if (NewFieldValue == NULL) { 2217 2253 return EFI_OUT_OF_RESOURCES; 2218 2254 } 2255 2219 2256 CopyMem (NewFieldValue, FieldValue, StrSize); 2220 2257 NewFieldValue[StrSize -1] = '\0'; … … 2223 2260 FreePool (Header->FieldValue); 2224 2261 } 2262 2225 2263 Header->FieldValue = NewFieldValue; 2226 2264 }
Note:
See TracChangeset
for help on using the changeset viewer.