| Index: net/spdy/spdy_alt_svc_wire_format.cc
|
| diff --git a/net/spdy/spdy_alt_svc_wire_format.cc b/net/spdy/spdy_alt_svc_wire_format.cc
|
| deleted file mode 100644
|
| index 803fb7bc3d4ab08793d347e591a82e067b7909a7..0000000000000000000000000000000000000000
|
| --- a/net/spdy/spdy_alt_svc_wire_format.cc
|
| +++ /dev/null
|
| @@ -1,357 +0,0 @@
|
| -// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/spdy/spdy_alt_svc_wire_format.h"
|
| -
|
| -#include <algorithm>
|
| -#include <cctype>
|
| -#include <limits>
|
| -
|
| -#include "base/logging.h"
|
| -#include "net/spdy/platform/api/spdy_string_utils.h"
|
| -
|
| -namespace net {
|
| -
|
| -namespace {
|
| -
|
| -template <class T>
|
| -bool ParsePositiveIntegerImpl(SpdyStringPiece::const_iterator c,
|
| - SpdyStringPiece::const_iterator end,
|
| - T* value) {
|
| - *value = 0;
|
| - for (; c != end && std::isdigit(*c); ++c) {
|
| - if (*value > std::numeric_limits<T>::max() / 10) {
|
| - return false;
|
| - }
|
| - *value *= 10;
|
| - if (*value > std::numeric_limits<T>::max() - (*c - '0')) {
|
| - return false;
|
| - }
|
| - *value += *c - '0';
|
| - }
|
| - return (c == end && *value > 0);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -SpdyAltSvcWireFormat::AlternativeService::AlternativeService() {}
|
| -
|
| -SpdyAltSvcWireFormat::AlternativeService::AlternativeService(
|
| - const SpdyString& protocol_id,
|
| - const SpdyString& host,
|
| - uint16_t port,
|
| - uint32_t max_age,
|
| - VersionVector version)
|
| - : protocol_id(protocol_id),
|
| - host(host),
|
| - port(port),
|
| - max_age(max_age),
|
| - version(version) {}
|
| -
|
| -SpdyAltSvcWireFormat::AlternativeService::~AlternativeService() {}
|
| -
|
| -SpdyAltSvcWireFormat::AlternativeService::AlternativeService(
|
| - const AlternativeService& other) = default;
|
| -
|
| -// static
|
| -bool SpdyAltSvcWireFormat::ParseHeaderFieldValue(
|
| - SpdyStringPiece value,
|
| - AlternativeServiceVector* altsvc_vector) {
|
| - // Empty value is invalid according to the specification.
|
| - if (value.empty()) {
|
| - return false;
|
| - }
|
| - altsvc_vector->clear();
|
| - if (value == SpdyStringPiece("clear")) {
|
| - return true;
|
| - }
|
| - SpdyStringPiece::const_iterator c = value.begin();
|
| - while (c != value.end()) {
|
| - // Parse protocol-id.
|
| - SpdyStringPiece::const_iterator percent_encoded_protocol_id_end =
|
| - std::find(c, value.end(), '=');
|
| - SpdyString protocol_id;
|
| - if (percent_encoded_protocol_id_end == c ||
|
| - !PercentDecode(c, percent_encoded_protocol_id_end, &protocol_id)) {
|
| - return false;
|
| - }
|
| - c = percent_encoded_protocol_id_end;
|
| - if (c == value.end()) {
|
| - return false;
|
| - }
|
| - // Parse alt-authority.
|
| - DCHECK_EQ('=', *c);
|
| - ++c;
|
| - if (c == value.end() || *c != '"') {
|
| - return false;
|
| - }
|
| - ++c;
|
| - SpdyStringPiece::const_iterator alt_authority_begin = c;
|
| - for (; c != value.end() && *c != '"'; ++c) {
|
| - // Decode backslash encoding.
|
| - if (*c != '\\') {
|
| - continue;
|
| - }
|
| - ++c;
|
| - if (c == value.end()) {
|
| - return false;
|
| - }
|
| - }
|
| - if (c == alt_authority_begin || c == value.end()) {
|
| - return false;
|
| - }
|
| - DCHECK_EQ('"', *c);
|
| - SpdyString host;
|
| - uint16_t port;
|
| - if (!ParseAltAuthority(alt_authority_begin, c, &host, &port)) {
|
| - return false;
|
| - }
|
| - ++c;
|
| - // Parse parameters.
|
| - uint32_t max_age = 86400;
|
| - VersionVector version;
|
| - SpdyStringPiece::const_iterator parameters_end =
|
| - std::find(c, value.end(), ',');
|
| - while (c != parameters_end) {
|
| - SkipWhiteSpace(&c, parameters_end);
|
| - if (c == parameters_end) {
|
| - break;
|
| - }
|
| - if (*c != ';') {
|
| - return false;
|
| - }
|
| - ++c;
|
| - SkipWhiteSpace(&c, parameters_end);
|
| - if (c == parameters_end) {
|
| - break;
|
| - }
|
| - SpdyString parameter_name;
|
| - for (; c != parameters_end && *c != '=' && *c != ' ' && *c != '\t'; ++c) {
|
| - parameter_name.push_back(tolower(*c));
|
| - }
|
| - SkipWhiteSpace(&c, parameters_end);
|
| - if (c == parameters_end || *c != '=') {
|
| - return false;
|
| - }
|
| - ++c;
|
| - SkipWhiteSpace(&c, parameters_end);
|
| - SpdyStringPiece::const_iterator parameter_value_begin = c;
|
| - for (; c != parameters_end && *c != ';' && *c != ' ' && *c != '\t'; ++c) {
|
| - }
|
| - if (c == parameter_value_begin) {
|
| - return false;
|
| - }
|
| - if (parameter_name.compare("ma") == 0) {
|
| - if (!ParsePositiveInteger32(parameter_value_begin, c, &max_age)) {
|
| - return false;
|
| - }
|
| - } else if (parameter_name.compare("v") == 0) {
|
| - // Version is a comma separated list of positive integers enclosed in
|
| - // quotation marks. Since it can contain commas, which are not
|
| - // delineating alternative service entries, |parameters_end| and |c| can
|
| - // be invalid.
|
| - if (*parameter_value_begin != '"') {
|
| - return false;
|
| - }
|
| - c = std::find(parameter_value_begin + 1, value.end(), '"');
|
| - if (c == value.end()) {
|
| - return false;
|
| - }
|
| - ++c;
|
| - parameters_end = std::find(c, value.end(), ',');
|
| - SpdyStringPiece::const_iterator v_begin = parameter_value_begin + 1;
|
| - while (v_begin < c) {
|
| - SpdyStringPiece::const_iterator v_end = v_begin;
|
| - while (v_end < c - 1 && *v_end != ',') {
|
| - ++v_end;
|
| - }
|
| - uint16_t v;
|
| - if (!ParsePositiveInteger16(v_begin, v_end, &v)) {
|
| - return false;
|
| - }
|
| - version.push_back(v);
|
| - v_begin = v_end + 1;
|
| - if (v_begin == c - 1) {
|
| - // List ends in comma.
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - altsvc_vector->emplace_back(protocol_id, host, port, max_age, version);
|
| - for (; c != value.end() && (*c == ' ' || *c == '\t' || *c == ','); ++c) {
|
| - }
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -// static
|
| -SpdyString SpdyAltSvcWireFormat::SerializeHeaderFieldValue(
|
| - const AlternativeServiceVector& altsvc_vector) {
|
| - if (altsvc_vector.empty()) {
|
| - return SpdyString("clear");
|
| - }
|
| - const char kNibbleToHex[] = "0123456789ABCDEF";
|
| - SpdyString value;
|
| - for (const AlternativeService& altsvc : altsvc_vector) {
|
| - if (!value.empty()) {
|
| - value.push_back(',');
|
| - }
|
| - // Percent escape protocol id according to
|
| - // http://tools.ietf.org/html/rfc7230#section-3.2.6.
|
| - for (char c : altsvc.protocol_id) {
|
| - if (isalnum(c)) {
|
| - value.push_back(c);
|
| - continue;
|
| - }
|
| - switch (c) {
|
| - case '!':
|
| - case '#':
|
| - case '$':
|
| - case '&':
|
| - case '\'':
|
| - case '*':
|
| - case '+':
|
| - case '-':
|
| - case '.':
|
| - case '^':
|
| - case '_':
|
| - case '`':
|
| - case '|':
|
| - case '~':
|
| - value.push_back(c);
|
| - break;
|
| - default:
|
| - value.push_back('%');
|
| - // Network byte order is big-endian.
|
| - value.push_back(kNibbleToHex[c >> 4]);
|
| - value.push_back(kNibbleToHex[c & 0x0f]);
|
| - break;
|
| - }
|
| - }
|
| - value.push_back('=');
|
| - value.push_back('"');
|
| - for (char c : altsvc.host) {
|
| - if (c == '"' || c == '\\') {
|
| - value.push_back('\\');
|
| - }
|
| - value.push_back(c);
|
| - }
|
| - SpdyStringAppendF(&value, ":%d\"", altsvc.port);
|
| - if (altsvc.max_age != 86400) {
|
| - SpdyStringAppendF(&value, "; ma=%d", altsvc.max_age);
|
| - }
|
| - if (!altsvc.version.empty()) {
|
| - value.append("; v=\"");
|
| - for (VersionVector::const_iterator it = altsvc.version.begin();
|
| - it != altsvc.version.end(); ++it) {
|
| - if (it != altsvc.version.begin()) {
|
| - value.append(",");
|
| - }
|
| - SpdyStringAppendF(&value, "%d", *it);
|
| - }
|
| - value.append("\"");
|
| - }
|
| - }
|
| - return value;
|
| -}
|
| -
|
| -// static
|
| -void SpdyAltSvcWireFormat::SkipWhiteSpace(SpdyStringPiece::const_iterator* c,
|
| - SpdyStringPiece::const_iterator end) {
|
| - for (; *c != end && (**c == ' ' || **c == '\t'); ++*c) {
|
| - }
|
| -}
|
| -
|
| -// static
|
| -bool SpdyAltSvcWireFormat::PercentDecode(SpdyStringPiece::const_iterator c,
|
| - SpdyStringPiece::const_iterator end,
|
| - SpdyString* output) {
|
| - output->clear();
|
| - for (; c != end; ++c) {
|
| - if (*c != '%') {
|
| - output->push_back(*c);
|
| - continue;
|
| - }
|
| - DCHECK_EQ('%', *c);
|
| - ++c;
|
| - if (c == end || !std::isxdigit(*c)) {
|
| - return false;
|
| - }
|
| - // Network byte order is big-endian.
|
| - char decoded = SpdyHexDigitToInt(*c) << 4;
|
| - ++c;
|
| - if (c == end || !std::isxdigit(*c)) {
|
| - return false;
|
| - }
|
| - decoded += SpdyHexDigitToInt(*c);
|
| - output->push_back(decoded);
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -// static
|
| -bool SpdyAltSvcWireFormat::ParseAltAuthority(
|
| - SpdyStringPiece::const_iterator c,
|
| - SpdyStringPiece::const_iterator end,
|
| - SpdyString* host,
|
| - uint16_t* port) {
|
| - host->clear();
|
| - if (c == end) {
|
| - return false;
|
| - }
|
| - if (*c == '[') {
|
| - for (; c != end && *c != ']'; ++c) {
|
| - if (*c == '"') {
|
| - // Port is mandatory.
|
| - return false;
|
| - }
|
| - host->push_back(*c);
|
| - }
|
| - if (c == end) {
|
| - return false;
|
| - }
|
| - DCHECK_EQ(']', *c);
|
| - host->push_back(*c);
|
| - ++c;
|
| - } else {
|
| - for (; c != end && *c != ':'; ++c) {
|
| - if (*c == '"') {
|
| - // Port is mandatory.
|
| - return false;
|
| - }
|
| - if (*c == '\\') {
|
| - ++c;
|
| - if (c == end) {
|
| - return false;
|
| - }
|
| - }
|
| - host->push_back(*c);
|
| - }
|
| - }
|
| - if (c == end || *c != ':') {
|
| - return false;
|
| - }
|
| - DCHECK_EQ(':', *c);
|
| - ++c;
|
| - return ParsePositiveInteger16(c, end, port);
|
| -}
|
| -
|
| -// static
|
| -bool SpdyAltSvcWireFormat::ParsePositiveInteger16(
|
| - SpdyStringPiece::const_iterator c,
|
| - SpdyStringPiece::const_iterator end,
|
| - uint16_t* value) {
|
| - return ParsePositiveIntegerImpl<uint16_t>(c, end, value);
|
| -}
|
| -
|
| -// static
|
| -bool SpdyAltSvcWireFormat::ParsePositiveInteger32(
|
| - SpdyStringPiece::const_iterator c,
|
| - SpdyStringPiece::const_iterator end,
|
| - uint32_t* value) {
|
| - return ParsePositiveIntegerImpl<uint32_t>(c, end, value);
|
| -}
|
| -
|
| -} // namespace net
|
|
|