Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |