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 853 matching lines...) Loading... |
864 | 864 |
865 bool parseContentRangeHeaderFor206(const String& contentRange, | 865 bool parseContentRangeHeaderFor206(const String& contentRange, |
866 int64_t* firstBytePosition, | 866 int64_t* firstBytePosition, |
867 int64_t* lastBytePosition, | 867 int64_t* lastBytePosition, |
868 int64_t* instanceLength) { | 868 int64_t* instanceLength) { |
869 return net::HttpUtil::ParseContentRangeHeaderFor206( | 869 return net::HttpUtil::ParseContentRangeHeaderFor206( |
870 StringUTF8Adaptor(contentRange).asStringPiece(), firstBytePosition, | 870 StringUTF8Adaptor(contentRange).asStringPiece(), firstBytePosition, |
871 lastBytePosition, instanceLength); | 871 lastBytePosition, instanceLength); |
872 } | 872 } |
873 | 873 |
| 874 template <typename CharType> |
| 875 inline bool isNotServerTimingHeaderDelimiter(CharType c) { |
| 876 return c != '=' && c != ';' && c != ','; |
| 877 } |
| 878 |
| 879 const LChar* parseServerTimingToken(const LChar* begin, |
| 880 const LChar* end, |
| 881 String& result) { |
| 882 const LChar* position = begin; |
| 883 skipWhile<LChar, isNotServerTimingHeaderDelimiter>(position, end); |
| 884 result = String(begin, position - begin).stripWhiteSpace(); |
| 885 return position; |
| 886 } |
| 887 |
| 888 String checkDoubleQuotedString(const String& value) { |
| 889 if (value.length() < 2 || value[0] != '"' || |
| 890 value[value.length() - 1] != '"') { |
| 891 return value; |
| 892 } |
| 893 |
| 894 StringBuilder out; |
| 895 unsigned pos = 1; // Begin after the opening DQUOTE. |
| 896 unsigned len = value.length() - 1; // End before the closing DQUOTE. |
| 897 |
| 898 // Skip past backslashes, but include everything else. |
| 899 while (pos < len) { |
| 900 if (value[pos] == '\\') |
| 901 pos++; |
| 902 if (pos < len) |
| 903 out.append(value[pos++]); |
| 904 } |
| 905 |
| 906 return out.toString(); |
| 907 } |
| 908 |
| 909 std::unique_ptr<ServerTimingHeaderVector> parseServerTimingHeader( |
| 910 const String& headerValue) { |
| 911 std::unique_ptr<ServerTimingHeaderVector> headers = |
| 912 WTF::makeUnique<ServerTimingHeaderVector>(); |
| 913 |
| 914 if (!headerValue.isNull()) { |
| 915 DCHECK(headerValue.is8Bit()); |
| 916 |
| 917 const LChar* position = headerValue.characters8(); |
| 918 const LChar* end = position + headerValue.length(); |
| 919 while (position < end) { |
| 920 String metric, value, description = ""; |
| 921 position = parseServerTimingToken(position, end, metric); |
| 922 if (*position == '=') { |
| 923 position = parseServerTimingToken(position + 1, end, value); |
| 924 } |
| 925 if (*position == ';') { |
| 926 position = parseServerTimingToken(position + 1, end, description); |
| 927 } |
| 928 position++; |
| 929 |
| 930 headers->push_back(WTF::makeUnique<ServerTimingHeader>( |
| 931 metric, value.toDouble(), checkDoubleQuotedString(description))); |
| 932 } |
| 933 } |
| 934 return headers; |
| 935 } |
| 936 |
874 } // namespace blink | 937 } // namespace blink |
OLD | NEW |