| Index: net/spdy/spdy_protocol.cc
|
| diff --git a/net/spdy/spdy_protocol.cc b/net/spdy/spdy_protocol.cc
|
| index 02c74ef3bd178f5d287bc525966c6e071b8a4974..b7867977e73780ccdd615505f8ac49ca48d4067d 100644
|
| --- a/net/spdy/spdy_protocol.cc
|
| +++ b/net/spdy/spdy_protocol.cc
|
| @@ -49,6 +49,7 @@ bool SpdyConstants::IsValidFrameType(SpdyMajorVersion version,
|
|
|
| return true;
|
| case SPDY4:
|
| + case SPDY5:
|
| // DATA is the first valid frame.
|
| if (frame_type_field < SerializeFrameType(version, DATA)) {
|
| return false;
|
| @@ -91,6 +92,7 @@ SpdyFrameType SpdyConstants::ParseFrameType(SpdyMajorVersion version,
|
| }
|
| break;
|
| case SPDY4:
|
| + case SPDY5:
|
| switch (frame_type_field) {
|
| case 0:
|
| return DATA;
|
| @@ -148,6 +150,7 @@ int SpdyConstants::SerializeFrameType(SpdyMajorVersion version,
|
| return -1;
|
| }
|
| case SPDY4:
|
| + case SPDY5:
|
| switch (frame_type) {
|
| case DATA:
|
| return 0;
|
| @@ -199,6 +202,7 @@ bool SpdyConstants::IsValidSettingId(SpdyMajorVersion version,
|
|
|
| return true;
|
| case SPDY4:
|
| + case SPDY5:
|
| // HEADER_TABLE_SIZE is the first valid setting id.
|
| if (setting_id_field <
|
| SerializeSettingId(version, SETTINGS_HEADER_TABLE_SIZE)) {
|
| @@ -241,6 +245,7 @@ SpdySettingsIds SpdyConstants::ParseSettingId(SpdyMajorVersion version,
|
| }
|
| break;
|
| case SPDY4:
|
| + case SPDY5:
|
| switch (setting_id_field) {
|
| case 1:
|
| return SETTINGS_HEADER_TABLE_SIZE;
|
| @@ -283,6 +288,7 @@ int SpdyConstants::SerializeSettingId(SpdyMajorVersion version,
|
| return -1;
|
| }
|
| case SPDY4:
|
| + case SPDY5:
|
| switch (id) {
|
| case SETTINGS_HEADER_TABLE_SIZE:
|
| return 1;
|
| @@ -301,6 +307,405 @@ int SpdyConstants::SerializeSettingId(SpdyMajorVersion version,
|
| return -1;
|
| }
|
|
|
| +bool SpdyConstants::IsValidRstStreamStatus(SpdyMajorVersion version,
|
| + int rst_stream_status_field) {
|
| + switch (version) {
|
| + case SPDY2:
|
| + case SPDY3:
|
| + // PROTOCOL_ERROR is the valid first status code.
|
| + if (rst_stream_status_field <
|
| + SerializeRstStreamStatus(version, RST_STREAM_PROTOCOL_ERROR)) {
|
| + return false;
|
| + }
|
| +
|
| + // FRAME_TOO_LARGE is the valid last status code.
|
| + if (rst_stream_status_field >
|
| + SerializeRstStreamStatus(version, RST_STREAM_FRAME_TOO_LARGE)) {
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| + case SPDY4:
|
| + case SPDY5:
|
| + // NO_ERROR is the first valid status code.
|
| + if (rst_stream_status_field <
|
| + SerializeRstStreamStatus(version, RST_STREAM_PROTOCOL_ERROR)) {
|
| + return false;
|
| + }
|
| +
|
| + // TODO(hkhalil): Omit COMPRESSION_ERROR and SETTINGS_TIMEOUT
|
| + /*
|
| + // This works because GOAWAY and RST_STREAM share a namespace.
|
| + if (rst_stream_status_field ==
|
| + SerializeGoAwayStatus(version, GOAWAY_COMPRESSION_ERROR) ||
|
| + rst_stream_status_field ==
|
| + SerializeGoAwayStatus(version, GOAWAY_SETTINGS_TIMEOUT)) {
|
| + return false;
|
| + }
|
| + */
|
| +
|
| + // ENHANCE_YOUR_CALM is the last valid status code.
|
| + if (rst_stream_status_field >
|
| + SerializeRstStreamStatus(version, RST_STREAM_ENHANCE_YOUR_CALM)) {
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| + }
|
| + LOG(DFATAL) << "Unhandled SPDY version " << version;
|
| + return false;
|
| +}
|
| +
|
| +SpdyRstStreamStatus SpdyConstants::ParseRstStreamStatus(
|
| + SpdyMajorVersion version,
|
| + int rst_stream_status_field) {
|
| + switch (version) {
|
| + case SPDY2:
|
| + case SPDY3:
|
| + switch (rst_stream_status_field) {
|
| + case 1:
|
| + return RST_STREAM_PROTOCOL_ERROR;
|
| + case 2:
|
| + return RST_STREAM_INVALID_STREAM;
|
| + case 3:
|
| + return RST_STREAM_REFUSED_STREAM;
|
| + case 4:
|
| + return RST_STREAM_UNSUPPORTED_VERSION;
|
| + case 5:
|
| + return RST_STREAM_CANCEL;
|
| + case 6:
|
| + return RST_STREAM_INTERNAL_ERROR;
|
| + case 7:
|
| + return RST_STREAM_FLOW_CONTROL_ERROR;
|
| + case 8:
|
| + return RST_STREAM_STREAM_IN_USE;
|
| + case 9:
|
| + return RST_STREAM_STREAM_ALREADY_CLOSED;
|
| + case 10:
|
| + return RST_STREAM_INVALID_CREDENTIALS;
|
| + case 11:
|
| + return RST_STREAM_FRAME_TOO_LARGE;
|
| + }
|
| + break;
|
| + case SPDY4:
|
| + case SPDY5:
|
| + switch (rst_stream_status_field) {
|
| + case 1:
|
| + return RST_STREAM_PROTOCOL_ERROR;
|
| + case 2:
|
| + return RST_STREAM_INTERNAL_ERROR;
|
| + case 3:
|
| + return RST_STREAM_FLOW_CONTROL_ERROR;
|
| + case 5:
|
| + return RST_STREAM_STREAM_CLOSED;
|
| + case 6:
|
| + return RST_STREAM_FRAME_SIZE_ERROR;
|
| + case 7:
|
| + return RST_STREAM_REFUSED_STREAM;
|
| + case 8:
|
| + return RST_STREAM_CANCEL;
|
| + case 10:
|
| + return RST_STREAM_CONNECT_ERROR;
|
| + case 11:
|
| + return RST_STREAM_ENHANCE_YOUR_CALM;
|
| + }
|
| + break;
|
| + }
|
| +
|
| + LOG(DFATAL) << "Invalid RST_STREAM status " << rst_stream_status_field;
|
| + return RST_STREAM_PROTOCOL_ERROR;
|
| +}
|
| +
|
| +int SpdyConstants::SerializeRstStreamStatus(
|
| + SpdyMajorVersion version,
|
| + SpdyRstStreamStatus rst_stream_status) {
|
| + switch (version) {
|
| + case SPDY2:
|
| + case SPDY3:
|
| + switch (rst_stream_status) {
|
| + case RST_STREAM_PROTOCOL_ERROR:
|
| + return 1;
|
| + case RST_STREAM_INVALID_STREAM:
|
| + return 2;
|
| + case RST_STREAM_REFUSED_STREAM:
|
| + return 3;
|
| + case RST_STREAM_UNSUPPORTED_VERSION:
|
| + return 4;
|
| + case RST_STREAM_CANCEL:
|
| + return 5;
|
| + case RST_STREAM_INTERNAL_ERROR:
|
| + return 6;
|
| + case RST_STREAM_FLOW_CONTROL_ERROR:
|
| + return 7;
|
| + case RST_STREAM_STREAM_IN_USE:
|
| + return 8;
|
| + case RST_STREAM_STREAM_ALREADY_CLOSED:
|
| + return 9;
|
| + case RST_STREAM_INVALID_CREDENTIALS:
|
| + return 10;
|
| + case RST_STREAM_FRAME_TOO_LARGE:
|
| + return 11;
|
| + default:
|
| + LOG(DFATAL) << "Unhandled RST_STREAM status "
|
| + << rst_stream_status;
|
| + return -1;
|
| + }
|
| + case SPDY4:
|
| + case SPDY5:
|
| + switch (rst_stream_status) {
|
| + case RST_STREAM_PROTOCOL_ERROR:
|
| + return 1;
|
| + case RST_STREAM_INTERNAL_ERROR:
|
| + return 2;
|
| + case RST_STREAM_FLOW_CONTROL_ERROR:
|
| + return 3;
|
| + case RST_STREAM_STREAM_CLOSED:
|
| + return 5;
|
| + case RST_STREAM_FRAME_SIZE_ERROR:
|
| + return 6;
|
| + case RST_STREAM_REFUSED_STREAM:
|
| + return 7;
|
| + case RST_STREAM_CANCEL:
|
| + return 8;
|
| + case RST_STREAM_CONNECT_ERROR:
|
| + return 10;
|
| + case RST_STREAM_ENHANCE_YOUR_CALM:
|
| + return 11;
|
| + default:
|
| + LOG(DFATAL) << "Unhandled RST_STREAM status "
|
| + << rst_stream_status;
|
| + return -1;
|
| + }
|
| + }
|
| + LOG(DFATAL) << "Unhandled SPDY version " << version;
|
| + return -1;
|
| +}
|
| +
|
| +bool SpdyConstants::IsValidGoAwayStatus(SpdyMajorVersion version,
|
| + int goaway_status_field) {
|
| + switch (version) {
|
| + case SPDY2:
|
| + case SPDY3:
|
| + // GOAWAY_OK is the first valid status.
|
| + if (goaway_status_field < SerializeGoAwayStatus(version, GOAWAY_OK)) {
|
| + return false;
|
| + }
|
| +
|
| + // GOAWAY_INTERNAL_ERROR is the last valid status.
|
| + if (goaway_status_field > SerializeGoAwayStatus(version,
|
| + GOAWAY_INTERNAL_ERROR)) {
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| + case SPDY4:
|
| + case SPDY5:
|
| + // GOAWAY_NO_ERROR is the first valid status.
|
| + if (goaway_status_field < SerializeGoAwayStatus(version,
|
| + GOAWAY_NO_ERROR)) {
|
| + return false;
|
| + }
|
| +
|
| + // GOAWAY_INADEQUATE_SECURITY is the last valid status.
|
| + if (goaway_status_field >
|
| + SerializeGoAwayStatus(version, GOAWAY_INADEQUATE_SECURITY)) {
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| + }
|
| + LOG(DFATAL) << "Unknown SpdyMajorVersion " << version;
|
| + return false;
|
| +}
|
| +
|
| +SpdyGoAwayStatus SpdyConstants::ParseGoAwayStatus(SpdyMajorVersion version,
|
| + int goaway_status_field) {
|
| + switch (version) {
|
| + case SPDY2:
|
| + case SPDY3:
|
| + switch (goaway_status_field) {
|
| + case 0:
|
| + return GOAWAY_OK;
|
| + case 1:
|
| + return GOAWAY_PROTOCOL_ERROR;
|
| + case 2:
|
| + return GOAWAY_INTERNAL_ERROR;
|
| + }
|
| + break;
|
| + case SPDY4:
|
| + case SPDY5:
|
| + switch (goaway_status_field) {
|
| + case 0:
|
| + return GOAWAY_NO_ERROR;
|
| + case 1:
|
| + return GOAWAY_PROTOCOL_ERROR;
|
| + case 2:
|
| + return GOAWAY_INTERNAL_ERROR;
|
| + case 3:
|
| + return GOAWAY_FLOW_CONTROL_ERROR;
|
| + case 4:
|
| + return GOAWAY_SETTINGS_TIMEOUT;
|
| + case 5:
|
| + return GOAWAY_STREAM_CLOSED;
|
| + case 6:
|
| + return GOAWAY_FRAME_SIZE_ERROR;
|
| + case 7:
|
| + return GOAWAY_REFUSED_STREAM;
|
| + case 8:
|
| + return GOAWAY_CANCEL;
|
| + case 9:
|
| + return GOAWAY_COMPRESSION_ERROR;
|
| + case 10:
|
| + return GOAWAY_CONNECT_ERROR;
|
| + case 11:
|
| + return GOAWAY_ENHANCE_YOUR_CALM;
|
| + case 12:
|
| + return GOAWAY_INADEQUATE_SECURITY;
|
| + }
|
| + break;
|
| + }
|
| +
|
| + LOG(DFATAL) << "Unhandled GOAWAY status " << goaway_status_field;
|
| + return GOAWAY_PROTOCOL_ERROR;
|
| +}
|
| +
|
| +SpdyMajorVersion SpdyConstants::ParseMajorVersion(int version_number) {
|
| + switch (version_number) {
|
| + case 2:
|
| + return SPDY2;
|
| + case 3:
|
| + return SPDY3;
|
| + case 4:
|
| + return SPDY4;
|
| + case 5:
|
| + return SPDY5;
|
| + default:
|
| + LOG(DFATAL) << "Unsupported SPDY version number: " << version_number;
|
| + return SPDY3;
|
| + }
|
| +}
|
| +
|
| +int SpdyConstants::SerializeMajorVersion(SpdyMajorVersion version) {
|
| + switch (version) {
|
| + case SPDY2:
|
| + return 2;
|
| + case SPDY3:
|
| + return 3;
|
| + case SPDY4:
|
| + return 4;
|
| + case SPDY5:
|
| + return 5;
|
| + default:
|
| + LOG(DFATAL) << "Unsupported SPDY major version: " << version;
|
| + return -1;
|
| + }
|
| +}
|
| +
|
| +std::string SpdyConstants::GetVersionString(SpdyMajorVersion version) {
|
| + switch (version) {
|
| + case SPDY2:
|
| + return "spdy/2";
|
| + case SPDY3:
|
| + return "spdy/3";
|
| + case SPDY4:
|
| + return "spdy/4";
|
| + case SPDY5:
|
| + return "spdy/5";
|
| + default:
|
| + LOG(DFATAL) << "Unsupported SPDY major version: " << version;
|
| + return "spdy/3";
|
| + }
|
| +}
|
| +
|
| +int SpdyConstants::SerializeGoAwayStatus(SpdyMajorVersion version,
|
| + SpdyGoAwayStatus status) {
|
| + switch (version) {
|
| + case SPDY2:
|
| + case SPDY3:
|
| + switch (status) {
|
| + case GOAWAY_OK:
|
| + return 0;
|
| + case GOAWAY_PROTOCOL_ERROR:
|
| + return 1;
|
| + case GOAWAY_INTERNAL_ERROR:
|
| + return 2;
|
| + default:
|
| + LOG(DFATAL) << "Serializing unhandled GOAWAY status " << status;
|
| + return -1;
|
| + }
|
| + case SPDY4:
|
| + case SPDY5:
|
| + switch (status) {
|
| + case GOAWAY_NO_ERROR:
|
| + return 0;
|
| + case GOAWAY_PROTOCOL_ERROR:
|
| + return 1;
|
| + case GOAWAY_INTERNAL_ERROR:
|
| + return 2;
|
| + case GOAWAY_FLOW_CONTROL_ERROR:
|
| + return 3;
|
| + case GOAWAY_SETTINGS_TIMEOUT:
|
| + return 4;
|
| + case GOAWAY_STREAM_CLOSED:
|
| + return 5;
|
| + case GOAWAY_FRAME_SIZE_ERROR:
|
| + return 6;
|
| + case GOAWAY_REFUSED_STREAM:
|
| + return 7;
|
| + case GOAWAY_CANCEL:
|
| + return 8;
|
| + case GOAWAY_COMPRESSION_ERROR:
|
| + return 9;
|
| + case GOAWAY_CONNECT_ERROR:
|
| + return 10;
|
| + case GOAWAY_ENHANCE_YOUR_CALM:
|
| + return 11;
|
| + case GOAWAY_INADEQUATE_SECURITY:
|
| + return 12;
|
| + default:
|
| + LOG(DFATAL) << "Serializing unhandled GOAWAY status " << status;
|
| + return -1;
|
| + }
|
| + }
|
| + LOG(DFATAL) << "Unknown SpdyMajorVersion " << version;
|
| + return -1;
|
| +}
|
| +
|
| +size_t SpdyConstants::GetDataFrameMinimumSize() {
|
| + return 8;
|
| +}
|
| +
|
| +size_t SpdyConstants::GetControlFrameHeaderSize(SpdyMajorVersion version) {
|
| + switch (version) {
|
| + case SPDY2:
|
| + case SPDY3:
|
| + case SPDY4:
|
| + case SPDY5:
|
| + return 8;
|
| + }
|
| + LOG(DFATAL) << "Unhandled SPDY version.";
|
| + return 0;
|
| +}
|
| +
|
| +size_t SpdyConstants::GetPrefixLength(SpdyFrameType type,
|
| + SpdyMajorVersion version) {
|
| + if (type != DATA) {
|
| + return GetControlFrameHeaderSize(version);
|
| + } else {
|
| + return GetDataFrameMinimumSize();
|
| + }
|
| +}
|
| +
|
| +size_t SpdyConstants::GetFrameMaximumSize(SpdyMajorVersion version) {
|
| + if (version < SPDY4) {
|
| + // 24-bit length field plus eight-byte frame header.
|
| + return ((1<<24) - 1) + 8;
|
| + } else {
|
| + // 14-bit length field.
|
| + return (1<<14) - 1;
|
| + }
|
| +}
|
| +
|
| void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const {
|
| return visitor->VisitData(*this);
|
| }
|
|
|