diff options
Diffstat (limited to 'linden/indra/llmessage/llurlrequest.cpp')
-rw-r--r-- | linden/indra/llmessage/llurlrequest.cpp | 84 |
1 files changed, 53 insertions, 31 deletions
diff --git a/linden/indra/llmessage/llurlrequest.cpp b/linden/indra/llmessage/llurlrequest.cpp index 42f3f04..ee62798 100644 --- a/linden/indra/llmessage/llurlrequest.cpp +++ b/linden/indra/llmessage/llurlrequest.cpp | |||
@@ -461,26 +461,62 @@ size_t LLURLRequest::upCallback( | |||
461 | 461 | ||
462 | static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) | 462 | static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) |
463 | { | 463 | { |
464 | const char* headerLine = (const char*)data; | 464 | const char* header_line = (const char*)data; |
465 | size_t headerLen = size * nmemb; | 465 | size_t header_len = size * nmemb; |
466 | LLURLRequestComplete* complete = (LLURLRequestComplete*)user; | 466 | LLURLRequestComplete* complete = (LLURLRequestComplete*)user; |
467 | 467 | ||
468 | if (!complete || !header_line) | ||
469 | { | ||
470 | return header_len; | ||
471 | } | ||
472 | |||
468 | // *TODO: This should be a utility in llstring.h: isascii() | 473 | // *TODO: This should be a utility in llstring.h: isascii() |
469 | for (size_t i = 0; i < headerLen; ++i) | 474 | for (size_t i = 0; i < header_len; ++i) |
475 | { | ||
476 | if (header_line[i] < 0) | ||
477 | { | ||
478 | return header_len; | ||
479 | } | ||
480 | } | ||
481 | |||
482 | std::string header(header_line, header_len); | ||
483 | |||
484 | // Per HTTP spec the first header line must be the status line. | ||
485 | if (!complete->haveHTTPStatus()) | ||
470 | { | 486 | { |
471 | if (headerLine[i] < 0) | 487 | if (header.substr(0,5) == "HTTP/") |
472 | { | 488 | { |
473 | return headerLen; | 489 | std::string::iterator end = header.end(); |
490 | std::string::iterator pos1 = std::find(header.begin(), end, ' '); | ||
491 | if (pos1 != end) ++pos1; | ||
492 | std::string::iterator pos2 = std::find(pos1, end, ' '); | ||
493 | if (pos2 != end) ++pos2; | ||
494 | std::string::iterator pos3 = std::find(pos2, end, '\r'); | ||
495 | |||
496 | std::string version(header.begin(), pos1); | ||
497 | std::string status(pos1, pos2); | ||
498 | std::string reason(pos2, pos3); | ||
499 | |||
500 | int statusCode = atoi(status.c_str()); | ||
501 | if (statusCode >= 300 && statusCode < 400) | ||
502 | { | ||
503 | // This is a redirect, ignore it and all headers | ||
504 | // until we find a normal status code. | ||
505 | } | ||
506 | else if (statusCode > 0) | ||
507 | { | ||
508 | complete->httpStatus((U32)statusCode, reason); | ||
509 | } | ||
474 | } | 510 | } |
511 | return header_len; | ||
475 | } | 512 | } |
476 | 513 | ||
477 | size_t sep; | 514 | std::string::iterator sep = std::find(header.begin(),header.end(),':'); |
478 | for (sep = 0; sep < headerLen && headerLine[sep] != ':'; ++sep) { } | ||
479 | 515 | ||
480 | if (sep < headerLen && complete) | 516 | if (sep != header.end()) |
481 | { | 517 | { |
482 | std::string key(headerLine, sep); | 518 | std::string key(header.begin(), sep); |
483 | std::string value(headerLine + sep + 1, headerLen - sep - 1); | 519 | std::string value(sep + 1, header.end()); |
484 | 520 | ||
485 | key = utf8str_tolower(utf8str_trim(key)); | 521 | key = utf8str_tolower(utf8str_trim(key)); |
486 | value = utf8str_trim(value); | 522 | value = utf8str_trim(value); |
@@ -489,30 +525,14 @@ static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) | |||
489 | } | 525 | } |
490 | else | 526 | else |
491 | { | 527 | { |
492 | std::string s(headerLine, headerLen); | 528 | LLStringUtil::trim(header); |
493 | 529 | if (!header.empty()) | |
494 | std::string::iterator end = s.end(); | ||
495 | std::string::iterator pos1 = std::find(s.begin(), end, ' '); | ||
496 | if (pos1 != end) ++pos1; | ||
497 | std::string::iterator pos2 = std::find(pos1, end, ' '); | ||
498 | if (pos2 != end) ++pos2; | ||
499 | std::string::iterator pos3 = std::find(pos2, end, '\r'); | ||
500 | |||
501 | std::string version(s.begin(), pos1); | ||
502 | std::string status(pos1, pos2); | ||
503 | std::string reason(pos2, pos3); | ||
504 | |||
505 | int statusCode = atoi(status.c_str()); | ||
506 | if (statusCode > 0) | ||
507 | { | 530 | { |
508 | if (complete) | 531 | llwarns << "Unable to parse header: " << header << llendl; |
509 | { | ||
510 | complete->httpStatus((U32)statusCode, reason); | ||
511 | } | ||
512 | } | 532 | } |
513 | } | 533 | } |
514 | 534 | ||
515 | return headerLen; | 535 | return header_len; |
516 | } | 536 | } |
517 | 537 | ||
518 | /** | 538 | /** |
@@ -553,7 +573,8 @@ LLIOPipe::EStatus LLContextURLExtractor::process_impl( | |||
553 | * LLURLRequestComplete | 573 | * LLURLRequestComplete |
554 | */ | 574 | */ |
555 | LLURLRequestComplete::LLURLRequestComplete() : | 575 | LLURLRequestComplete::LLURLRequestComplete() : |
556 | mRequestStatus(LLIOPipe::STATUS_ERROR) | 576 | mRequestStatus(LLIOPipe::STATUS_ERROR), |
577 | mHaveHTTPStatus(false) | ||
557 | { | 578 | { |
558 | LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); | 579 | LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); |
559 | } | 580 | } |
@@ -572,6 +593,7 @@ void LLURLRequestComplete::header(const std::string& header, const std::string& | |||
572 | //virtual | 593 | //virtual |
573 | void LLURLRequestComplete::httpStatus(U32 status, const std::string& reason) | 594 | void LLURLRequestComplete::httpStatus(U32 status, const std::string& reason) |
574 | { | 595 | { |
596 | mHaveHTTPStatus = true; | ||
575 | } | 597 | } |
576 | 598 | ||
577 | //virtual | 599 | //virtual |