Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: third_party/WebKit/Source/platform/network/HTTPParsers.cpp

Issue 1460883003: Drop unused functions in HTTPParsers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) 2 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
3 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4 * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ 4 * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
5 * Copyright (C) 2009 Google Inc. All rights reserved. 5 * Copyright (C) 2009 Google Inc. All rights reserved.
6 * Copyright (C) 2011 Apple Inc. All Rights Reserved. 6 * Copyright (C) 2011 Apple Inc. All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 if (c <= 0x20 || c >= 0x7F 151 if (c <= 0x20 || c >= 0x7F
152 || c == '(' || c == ')' || c == '<' || c == '>' || c == '@' 152 || c == '(' || c == ')' || c == '<' || c == '>' || c == '@'
153 || c == ',' || c == ';' || c == ':' || c == '\\' || c == '"' 153 || c == ',' || c == ';' || c == ':' || c == '\\' || c == '"'
154 || c == '/' || c == '[' || c == ']' || c == '?' || c == '=' 154 || c == '/' || c == '[' || c == ']' || c == '?' || c == '='
155 || c == '{' || c == '}') 155 || c == '{' || c == '}')
156 return false; 156 return false;
157 } 157 }
158 return true; 158 return true;
159 } 159 }
160 160
161 static const size_t maxInputSampleSize = 128;
162 static String trimInputSample(const char* p, size_t length)
163 {
164 if (length > maxInputSampleSize)
165 return String(p, maxInputSampleSize) + horizontalEllipsisCharacter;
166 return String(p, length);
167 }
168
169 ContentDispositionType contentDispositionType(const String& contentDisposition) 161 ContentDispositionType contentDispositionType(const String& contentDisposition)
170 { 162 {
171 if (contentDisposition.isEmpty()) 163 if (contentDisposition.isEmpty())
172 return ContentDispositionNone; 164 return ContentDispositionNone;
173 165
174 Vector<String> parameters; 166 Vector<String> parameters;
175 contentDisposition.split(';', parameters); 167 contentDisposition.split(';', parameters);
176 168
177 if (parameters.isEmpty()) 169 if (parameters.isEmpty())
178 return ContentDispositionNone; 170 return ContentDispositionNone;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 url = refresh.substring(urlStartPos, urlEndPos - urlStartPos).stripWhite Space(); 249 url = refresh.substring(urlStartPos, urlEndPos - urlStartPos).stripWhite Space();
258 return true; 250 return true;
259 } 251 }
260 } 252 }
261 253
262 double parseDate(const String& value) 254 double parseDate(const String& value)
263 { 255 {
264 return parseDateFromNullTerminatedCharacters(value.utf8().data()); 256 return parseDateFromNullTerminatedCharacters(value.utf8().data());
265 } 257 }
266 258
267 // FIXME: This function doesn't comply with RFC 6266.
268 // For example, this function doesn't handle the interaction between " and ;
269 // that arises from quoted-string, nor does this function properly unquote
270 // attribute values. Further this function appears to process parameter names
271 // in a case-sensitive manner. (There are likely other bugs as well.)
272 String filenameFromHTTPContentDisposition(const String& value)
273 {
274 Vector<String> keyValuePairs;
275 value.split(';', keyValuePairs);
276
277 unsigned length = keyValuePairs.size();
278 for (unsigned i = 0; i < length; i++) {
279 size_t valueStartPos = keyValuePairs[i].find('=');
280 if (valueStartPos == kNotFound)
281 continue;
282
283 String key = keyValuePairs[i].left(valueStartPos).stripWhiteSpace();
284
285 if (key.isEmpty() || key != "filename")
286 continue;
287
288 String value = keyValuePairs[i].substring(valueStartPos + 1).stripWhiteS pace();
289
290 // Remove quotes if there are any
291 if (value[0] == '\"')
292 value = value.substring(1, value.length() - 2);
293
294 return value;
295 }
296
297 return String();
298 }
299
300 AtomicString extractMIMETypeFromMediaType(const AtomicString& mediaType) 259 AtomicString extractMIMETypeFromMediaType(const AtomicString& mediaType)
301 { 260 {
302 StringBuilder mimeType; 261 StringBuilder mimeType;
303 unsigned length = mediaType.length(); 262 unsigned length = mediaType.length();
304 mimeType.reserveCapacity(length); 263 mimeType.reserveCapacity(length);
305 for (unsigned i = 0; i < length; i++) { 264 for (unsigned i = 0; i < length; i++) {
306 UChar c = mediaType[i]; 265 UChar c = mediaType[i];
307 266
308 if (c == ';') 267 if (c == ';')
309 break; 268 break;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 } 431 }
473 } 432 }
474 433
475 ContentTypeOptionsDisposition parseContentTypeOptionsHeader(const String& header ) 434 ContentTypeOptionsDisposition parseContentTypeOptionsHeader(const String& header )
476 { 435 {
477 if (header.stripWhiteSpace().lower() == "nosniff") 436 if (header.stripWhiteSpace().lower() == "nosniff")
478 return ContentTypeOptionsNosniff; 437 return ContentTypeOptionsNosniff;
479 return ContentTypeOptionsNone; 438 return ContentTypeOptionsNone;
480 } 439 }
481 440
482 String extractReasonPhraseFromHTTPStatusLine(const String& statusLine)
483 {
484 size_t spacePos = statusLine.find(' ');
485 // Remove status code from the status line.
486 spacePos = statusLine.find(' ', spacePos + 1);
487 return statusLine.substring(spacePos + 1);
488 }
489
490 XFrameOptionsDisposition parseXFrameOptionsHeader(const String& header) 441 XFrameOptionsDisposition parseXFrameOptionsHeader(const String& header)
491 { 442 {
492 XFrameOptionsDisposition result = XFrameOptionsNone; 443 XFrameOptionsDisposition result = XFrameOptionsNone;
493 444
494 if (header.isEmpty()) 445 if (header.isEmpty())
495 return result; 446 return result;
496 447
497 Vector<String> headers; 448 Vector<String> headers;
498 header.split(',', headers); 449 header.split(',', headers);
499 450
(...skipping 10 matching lines...) Expand all
510 currentValue = XFrameOptionsInvalid; 461 currentValue = XFrameOptionsInvalid;
511 462
512 if (result == XFrameOptionsNone) 463 if (result == XFrameOptionsNone)
513 result = currentValue; 464 result = currentValue;
514 else if (result != currentValue) 465 else if (result != currentValue)
515 return XFrameOptionsConflict; 466 return XFrameOptionsConflict;
516 } 467 }
517 return result; 468 return result;
518 } 469 }
519 470
520 bool parseRange(const String& range, long long& rangeOffset, long long& rangeEnd , long long& rangeSuffixLength)
521 {
522 // The format of "Range" header is defined in RFC 2616 Section 14.35.1.
523 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.1
524 // We don't support multiple range requests.
525
526 rangeOffset = rangeEnd = rangeSuffixLength = -1;
527
528 // The "bytes" unit identifier should be present.
529 static const char bytesStart[] = "bytes=";
530 if (!range.startsWith(bytesStart, TextCaseInsensitive))
531 return false;
532 String byteRange = range.substring(sizeof(bytesStart) - 1);
533
534 // The '-' character needs to be present.
535 int index = byteRange.find('-');
536 if (index == -1)
537 return false;
538
539 // If the '-' character is at the beginning, the suffix length, which specif ies the last N bytes, is provided.
540 // Example:
541 // -500
542 if (!index) {
543 String suffixLengthString = byteRange.substring(index + 1).stripWhiteSpa ce();
544 bool ok;
545 long long value = suffixLengthString.toInt64Strict(&ok);
546 if (ok)
547 rangeSuffixLength = value;
548 return true;
549 }
550
551 // Otherwise, the first-byte-position and the last-byte-position are provied .
552 // Examples:
553 // 0-499
554 // 500-
555 String firstBytePosStr = byteRange.left(index).stripWhiteSpace();
556 bool ok;
557 long long firstBytePos = firstBytePosStr.toInt64Strict(&ok);
558 if (!ok)
559 return false;
560
561 String lastBytePosStr = byteRange.substring(index + 1).stripWhiteSpace();
562 long long lastBytePos = -1;
563 if (!lastBytePosStr.isEmpty()) {
564 lastBytePos = lastBytePosStr.toInt64Strict(&ok);
565 if (!ok)
566 return false;
567 }
568
569 if (firstBytePos < 0 || !(lastBytePos == -1 || lastBytePos >= firstBytePos))
570 return false;
571
572 rangeOffset = firstBytePos;
573 rangeEnd = lastBytePos;
574 return true;
575 }
576
577 // HTTP/1.1 - RFC 2616
578 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1
579 // Request-Line = Method SP Request-URI SP HTTP-Version CRLF
580 size_t parseHTTPRequestLine(const char* data, size_t length, String& failureReas on, String& method, String& url, HTTPVersion& httpVersion)
581 {
582 method = String();
583 url = String();
584 httpVersion = Unknown;
585
586 const char* space1 = 0;
587 const char* space2 = 0;
588 const char* p;
589 size_t consumedLength;
590
591 for (p = data, consumedLength = 0; consumedLength < length; p++, consumedLen gth++) {
592 if (*p == ' ') {
593 if (!space1)
594 space1 = p;
595 else if (!space2)
596 space2 = p;
597 } else if (*p == '\n') {
598 break;
599 }
600 }
601
602 // Haven't finished header line.
603 if (consumedLength == length) {
604 failureReason = "Incomplete Request Line";
605 return 0;
606 }
607
608 // RequestLine does not contain 3 parts.
609 if (!space1 || !space2) {
610 failureReason = "Request Line does not appear to contain: <Method> <Url> <HTTPVersion>.";
611 return 0;
612 }
613
614 // The line must end with "\r\n".
615 const char* end = p + 1;
616 if (*(end - 2) != '\r') {
617 failureReason = "Request line does not end with CRLF";
618 return 0;
619 }
620
621 // Request Method.
622 method = String(data, space1 - data); // For length subtract 1 for space, bu t add 1 for data being the first character.
623
624 // Request URI.
625 url = String(space1 + 1, space2 - space1 - 1); // For length subtract 1 for space.
626
627 // HTTP Version.
628 String httpVersionString(space2 + 1, end - space2 - 3); // For length subtra ct 1 for space, and 2 for "\r\n".
629 if (httpVersionString.length() != 8 || !httpVersionString.startsWith("HTTP/1 ."))
630 httpVersion = Unknown;
631 else if (httpVersionString[7] == '0')
632 httpVersion = HTTP_1_0;
633 else if (httpVersionString[7] == '1')
634 httpVersion = HTTP_1_1;
635 else
636 httpVersion = Unknown;
637
638 return end - data;
639 }
640
641 static bool parseHTTPHeaderName(const char* s, size_t start, size_t size, String & failureReason, size_t* position, AtomicString* name)
642 {
643 size_t nameBegin = start;
644 for (size_t i = start; i < size; ++i) {
645 switch (s[i]) {
646 case '\r':
647 failureReason = "Unexpected CR in name at " + trimInputSample(&s[nam eBegin], i - nameBegin);
648 return false;
649 case '\n':
650 failureReason = "Unexpected LF in name at " + trimInputSample(&s[nam eBegin], i - nameBegin);
651 return false;
652 case ':':
653 if (i == nameBegin) {
654 failureReason = "Header name is missing";
655 return false;
656 }
657 *name = AtomicString::fromUTF8(&s[nameBegin], i - nameBegin);
658 if (name->isNull()) {
659 failureReason = "Invalid UTF-8 sequence in header name";
660 return false;
661 }
662 *position = i;
663 return true;
664 default:
665 break;
666 }
667 }
668 failureReason = "Unterminated header name";
669 return false;
670 }
671
672 static bool parseHTTPHeaderValue(const char* s, size_t start, size_t size, Strin g& failureReason, size_t* position, AtomicString* value)
673 {
674 size_t i = start;
675 for (; i < size && s[i] == ' '; ++i) {
676 }
677 size_t valueBegin = i;
678
679 for (; i < size && s[i] != '\r'; ++i) {
680 if (s[i] == '\n') {
681 failureReason = "Unexpected LF in value at " + trimInputSample(&s[va lueBegin], i - valueBegin);
682 return false;
683 }
684 }
685 if (i == size) {
686 failureReason = "Unterminated header value";
687 return false;
688 }
689
690 ASSERT(i < size && s[i] == '\r');
691 if (i + 1 >= size || s[i + 1] != '\n') {
692 failureReason = "LF doesn't follow CR after value at " + trimInputSample (&s[i + 1], size - i - 1);
693 return false;
694 }
695
696 *value = AtomicString::fromUTF8(&s[valueBegin], i - valueBegin);
697 if (i != valueBegin && value->isNull()) {
698 failureReason = "Invalid UTF-8 sequence in header value";
699 return false;
700 }
701
702 // 2 for strlen("\r\n")
703 *position = i + 2;
704 return true;
705 }
706
707 // Note that the header is already parsed and re-formatted in chromium side.
708 // We assume that the input is more restricted than RFC2616.
709 size_t parseHTTPHeader(const char* s, size_t size, String& failureReason, Atomic String& name, AtomicString& value)
710 {
711 name = nullAtom;
712 value = nullAtom;
713 if (size >= 1 && s[0] == '\r') {
714 if (size >= 2 && s[1] == '\n') {
715 // Skip an empty line.
716 return 2;
717 }
718 failureReason = "LF doesn't follow CR at " + trimInputSample(0, size);
719 return 0;
720 }
721 size_t current = 0;
722 if (!parseHTTPHeaderName(s, current, size, failureReason, &current, &name)) {
723 return 0;
724 }
725 ASSERT(s[current] == ':');
726 ++current;
727
728 if (!parseHTTPHeaderValue(s, current, size, failureReason, &current, &value) ) {
729 return 0;
730 }
731
732 return current;
733 }
734
735 size_t parseHTTPRequestBody(const char* data, size_t length, Vector<unsigned cha r>& body)
736 {
737 body.clear();
738 body.append(data, length);
739
740 return length;
741 }
742
743 static bool isCacheHeaderSeparator(UChar c) 471 static bool isCacheHeaderSeparator(UChar c)
744 { 472 {
745 // See RFC 2616, Section 2.2 473 // See RFC 2616, Section 2.2
746 switch (c) { 474 switch (c) {
747 case '(': 475 case '(':
748 case ')': 476 case ')':
749 case '<': 477 case '<':
750 case '>': 478 case '>':
751 case '@': 479 case '@':
752 case ',': 480 case ',':
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 623
896 void parseCommaDelimitedHeader(const String& headerValue, CommaDelimitedHeaderSe t& headerSet) 624 void parseCommaDelimitedHeader(const String& headerValue, CommaDelimitedHeaderSe t& headerSet)
897 { 625 {
898 Vector<String> results; 626 Vector<String> results;
899 headerValue.split(",", results); 627 headerValue.split(",", results);
900 for (auto& value : results) 628 for (auto& value : results)
901 headerSet.add(value.stripWhiteSpace(isWhitespace)); 629 headerSet.add(value.stripWhiteSpace(isWhitespace));
902 } 630 }
903 631
904 } 632 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698