Index: net/spdy/spdy_protocol.cc |
diff --git a/net/spdy/spdy_protocol.cc b/net/spdy/spdy_protocol.cc |
index 02c74ef3bd178f5d287bc525966c6e071b8a4974..c2b41e4234f77afdb965c2f1ea14e37ccd442a5a 100644 |
--- a/net/spdy/spdy_protocol.cc |
+++ b/net/spdy/spdy_protocol.cc |
@@ -301,6 +301,177 @@ 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: |
+ // 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: |
+ 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: |
+ 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; |
+} |
+ |
void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const { |
return visitor->VisitData(*this); |
} |