Index: net/spdy/spdy_protocol.cc |
diff --git a/net/spdy/spdy_protocol.cc b/net/spdy/spdy_protocol.cc |
index c2b41e4234f77afdb965c2f1ea14e37ccd442a5a..9bf9672d09c16382e8bb2c4c4d445638c13b0606 100644 |
--- a/net/spdy/spdy_protocol.cc |
+++ b/net/spdy/spdy_protocol.cc |
@@ -472,6 +472,145 @@ int SpdyConstants::SerializeRstStreamStatus( |
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: |
+ // 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: |
+ 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; |
+} |
+ |
+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: |
+ 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; |
+} |
+ |
void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const { |
return visitor->VisitData(*this); |
} |