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

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

Issue 2889033002: Better header value parsing for Server-Timing. (Closed)
Patch Set: add TODOs for skipping all whitespace Created 3 years, 7 months 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 831 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 842
843 bool ParseContentRangeHeaderFor206(const String& content_range, 843 bool ParseContentRangeHeaderFor206(const String& content_range,
844 int64_t* first_byte_position, 844 int64_t* first_byte_position,
845 int64_t* last_byte_position, 845 int64_t* last_byte_position,
846 int64_t* instance_length) { 846 int64_t* instance_length) {
847 return net::HttpUtil::ParseContentRangeHeaderFor206( 847 return net::HttpUtil::ParseContentRangeHeaderFor206(
848 StringUTF8Adaptor(content_range).AsStringPiece(), first_byte_position, 848 StringUTF8Adaptor(content_range).AsStringPiece(), first_byte_position,
849 last_byte_position, instance_length); 849 last_byte_position, instance_length);
850 } 850 }
851 851
852 template <typename CharType>
853 inline bool IsNotServerTimingHeaderDelimiter(CharType c) {
854 return c != '=' && c != ';' && c != ',';
855 }
856
857 const LChar* ParseServerTimingToken(const LChar* begin,
858 const LChar* end,
859 String& result) {
860 const LChar* position = begin;
861 skipWhile<LChar, IsNotServerTimingHeaderDelimiter>(position, end);
862 result = String(begin, position - begin).StripWhiteSpace();
863 return position;
864 }
865
866 String CheckDoubleQuotedString(const String& value) {
867 if (value.length() < 2 || value[0] != '"' ||
868 value[value.length() - 1] != '"') {
869 return value;
870 }
871
872 StringBuilder out;
873 unsigned pos = 1; // Begin after the opening DQUOTE.
874 unsigned len = value.length() - 1; // End before the closing DQUOTE.
875
876 // Skip past backslashes, but include everything else.
877 while (pos < len) {
878 if (value[pos] == '\\')
879 pos++;
880 if (pos < len)
881 out.Append(value[pos++]);
882 }
883
884 return out.ToString();
885 }
886
887 std::unique_ptr<ServerTimingHeaderVector> ParseServerTimingHeader( 852 std::unique_ptr<ServerTimingHeaderVector> ParseServerTimingHeader(
888 const String& headerValue) { 853 const String& headerValue) {
889 std::unique_ptr<ServerTimingHeaderVector> headers = 854 std::unique_ptr<ServerTimingHeaderVector> headers =
890 WTF::MakeUnique<ServerTimingHeaderVector>(); 855 WTF::MakeUnique<ServerTimingHeaderVector>();
891 856
892 if (!headerValue.IsNull()) { 857 if (!headerValue.IsNull()) {
893 DCHECK(headerValue.Is8Bit()); 858 DCHECK(headerValue.Is8Bit());
894 859
895 const LChar* position = headerValue.Characters8(); 860 unsigned index = 0;
896 const LChar* end = position + headerValue.length(); 861 while (index < headerValue.length()) {
897 while (position < end) { 862 StringView metric;
898 String metric, value, description = ""; 863 if (!ConsumeToken(Mode::kNormal, headerValue, index, metric)) {
899 position = ParseServerTimingToken(position, end, metric); 864 continue;
900 if (position != end && *position == '=') {
901 position = ParseServerTimingToken(position + 1, end, value);
902 } 865 }
903 if (position != end && *position == ';') { 866
904 position = ParseServerTimingToken(position + 1, end, description); 867 StringView duration;
868 String description;
869 if (Consume('=', headerValue, index)) {
870 ConsumeToken(Mode::kNormal, headerValue, index, duration);
905 } 871 }
906 position++; 872 if (Consume(';', headerValue, index)) {
873 ConsumeTokenOrQuotedString(Mode::kNormal, headerValue, index,
874 description);
875 }
907 876
908 headers->push_back(WTF::MakeUnique<ServerTimingHeader>( 877 headers->push_back(WTF::MakeUnique<ServerTimingHeader>(
909 metric, value.ToDouble(), CheckDoubleQuotedString(description))); 878 metric.ToString(), duration.ToString().ToDouble(),
879 description ? description : ""));
880
881 Consume(',', headerValue, index);
910 } 882 }
911 } 883 }
912 return headers; 884 return headers;
913 } 885 }
914 886
915 bool IsTokenCharacter(Mode mode, UChar c) { 887 bool IsTokenCharacter(Mode mode, UChar c) {
916 if (c >= 128) 888 if (c >= 128)
917 return false; 889 return false;
918 if (c < 0x20) 890 if (c < 0x20)
919 return false; 891 return false;
(...skipping 17 matching lines...) Expand all
937 case '?': 909 case '?':
938 case '=': 910 case '=':
939 return mode == Mode::kRelaxed; 911 return mode == Mode::kRelaxed;
940 default: 912 default:
941 return true; 913 return true;
942 } 914 }
943 } 915 }
944 916
945 bool Consume(char c, const String& input, unsigned& index) { 917 bool Consume(char c, const String& input, unsigned& index) {
946 DCHECK_NE(c, ' '); 918 DCHECK_NE(c, ' ');
919 // TODO: skip all whitespace, not just spaces
Yoav Weiss 2017/05/18 21:45:05 The format should be `// TODO(cvazac): ...`. Also
947 while (index < input.length() && input[index] == ' ') 920 while (index < input.length() && input[index] == ' ')
948 ++index; 921 ++index;
949 922
950 if (index < input.length() && input[index] == c) { 923 if (index < input.length() && input[index] == c) {
951 ++index; 924 ++index;
952 return true; 925 return true;
953 } 926 }
954 return false; 927 return false;
955 } 928 }
956 929
957 bool ConsumeToken(Mode mode, 930 bool ConsumeToken(Mode mode,
958 const String& input, 931 const String& input,
959 unsigned& index, 932 unsigned& index,
960 StringView& output) { 933 StringView& output) {
961 DCHECK(output.IsNull()); 934 DCHECK(output.IsNull());
962 935
936 // TODO: skip all whitespace, not just spaces
963 while (index < input.length() && input[index] == ' ') 937 while (index < input.length() && input[index] == ' ')
964 ++index; 938 ++index;
965 939
966 auto start = index; 940 auto start = index;
967 while (index < input.length() && IsTokenCharacter(mode, input[index])) 941 while (index < input.length() && IsTokenCharacter(mode, input[index]))
968 ++index; 942 ++index;
969 943
970 if (start == index) 944 if (start == index)
971 return false; 945 return false;
972 946
(...skipping 22 matching lines...) Expand all
995 builder.Append(input[index]); 969 builder.Append(input[index]);
996 ++index; 970 ++index;
997 } 971 }
998 return false; 972 return false;
999 } 973 }
1000 974
1001 bool ConsumeTokenOrQuotedString(Mode mode, 975 bool ConsumeTokenOrQuotedString(Mode mode,
1002 const String& input, 976 const String& input,
1003 unsigned& index, 977 unsigned& index,
1004 String& output) { 978 String& output) {
979 // TODO: skip all whitespace, not just spaces
1005 while (index < input.length() && input[index] == ' ') 980 while (index < input.length() && input[index] == ' ')
1006 ++index; 981 ++index;
1007 if (input.length() == index) 982 if (input.length() == index)
1008 return false; 983 return false;
1009 if (input[index] == '"') { 984 if (input[index] == '"') {
1010 return ConsumeQuotedString(input, index, output); 985 return ConsumeQuotedString(input, index, output);
1011 } 986 }
1012 StringView view; 987 StringView view;
1013 auto result = ConsumeToken(mode, input, index, view); 988 auto result = ConsumeToken(mode, input, index, view);
1014 output = view.ToString(); 989 output = view.ToString();
1015 return result; 990 return result;
1016 } 991 }
1017 992
1018 bool IsEnd(const String& input, unsigned index) { 993 bool IsEnd(const String& input, unsigned index) {
1019 while (index < input.length()) { 994 while (index < input.length()) {
995 // TODO: skip all whitespace, not just spaces
1020 if (input[index] != ' ') 996 if (input[index] != ' ')
1021 return false; 997 return false;
1022 ++index; 998 ++index;
1023 } 999 }
1024 return true; 1000 return true;
1025 } 1001 }
1026 1002
1027 } // namespace blink 1003 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698