summaryrefslogtreecommitdiffstats
path: root/net/spdy
diff options
context:
space:
mode:
authormbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-16 21:04:55 +0000
committermbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-16 21:04:55 +0000
commit68b745055e85cc466a0c867e87eacb43539baaa4 (patch)
tree498188bc84f5ac6c95f4c1dfb47ded34b7897a9a /net/spdy
parent7e5708ed452a9dc5b84f0b6c605cb9ed70d3548c (diff)
downloadchromium_src-68b745055e85cc466a0c867e87eacb43539baaa4.zip
chromium_src-68b745055e85cc466a0c867e87eacb43539baaa4.tar.gz
chromium_src-68b745055e85cc466a0c867e87eacb43539baaa4.tar.bz2
Fix crash in WriteSocket() when sending Settings frames
and compression is enabled. We need better unit tests for the compressed-frame testing. Filed bug 41805 to implement those. BUG=41803 TEST=NONE Review URL: http://codereview.chromium.org/1648014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44819 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/spdy')
-rw-r--r--net/spdy/spdy_framer.cc18
-rw-r--r--net/spdy/spdy_framer.h3
-rw-r--r--net/spdy/spdy_session.cc8
3 files changed, 28 insertions, 1 deletions
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index 65ef2e5..dc1f856 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -888,6 +888,24 @@ SpdyFrame* SpdyFramer::DuplicateFrame(const SpdyFrame* frame) {
return new_frame;
}
+bool SpdyFramer::IsCompressible(const SpdyFrame* frame) const {
+ // The important frames to compress are those which contain large
+ // amounts of compressible data - namely the headers in the SYN_STREAM
+ // and SYN_REPLY.
+ // TODO(mbelshe): Reconcile this with the spec when the spec is
+ // explicit about which frames compress and which do not.
+ if (frame->is_control_frame()) {
+ const SpdyControlFrame* control_frame =
+ reinterpret_cast<const SpdyControlFrame*>(frame);
+ return control_frame->type() == SYN_STREAM ||
+ control_frame->type() == SYN_REPLY;
+ }
+
+ const SpdyDataFrame* data_frame =
+ reinterpret_cast<const SpdyDataFrame*>(frame);
+ return (data_frame->flags() & DATA_FLAG_COMPRESSED) != 0;
+}
+
void SpdyFramer::set_enable_compression(bool value) {
enable_compression_ = value;
}
diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h
index c265be9..b07dd02 100644
--- a/net/spdy/spdy_framer.h
+++ b/net/spdy/spdy_framer.h
@@ -223,6 +223,9 @@ class SpdyFramer {
// Returned frame must be freed with "delete".
SpdyFrame* DuplicateFrame(const SpdyFrame* frame);
+ // Returns true if a frame could be compressed.
+ bool IsCompressible(const SpdyFrame* frame) const;
+
// For debugging.
static const char* StateToString(int state);
static const char* ErrorCodeToString(int error_code);
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 1ab3904..8d6d9d2 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -685,9 +685,15 @@ void SpdySession::WriteSocket() {
// which is now. At this time, we don't compress our data frames.
spdy::SpdyFrame uncompressed_frame(next_buffer.buffer()->data(), false);
size_t size;
- if (uncompressed_frame.is_control_frame()) {
+ if (spdy_framer_.IsCompressible(&uncompressed_frame)) {
scoped_ptr<spdy::SpdyFrame> compressed_frame(
spdy_framer_.CompressFrame(&uncompressed_frame));
+ if (!compressed_frame.get()) {
+ LOG(ERROR) << "SPDY Compression failure";
+ CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR);
+ return;
+ }
+
size = compressed_frame->length() + spdy::SpdyFrame::size();
DCHECK(size > 0);