summaryrefslogtreecommitdiffstats
path: root/webkit/glue
diff options
context:
space:
mode:
authortony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-10 01:22:47 +0000
committertony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-10 01:22:47 +0000
commita48c9db101d6a0c8a92b6d50eff8534cf86053e7 (patch)
tree7df269d4f87ecc07cfbf93130c6dd28b27d38843 /webkit/glue
parent69fc470526aa66350c8a7ecea4b902b06404bb33 (diff)
downloadchromium_src-a48c9db101d6a0c8a92b6d50eff8534cf86053e7.zip
chromium_src-a48c9db101d6a0c8a92b6d50eff8534cf86053e7.tar.gz
chromium_src-a48c9db101d6a0c8a92b6d50eff8534cf86053e7.tar.bz2
Take 2 at working around a multipart crash
The work around is to be more aggressive about sending multipart data before we have a response header. We used to buffer a response until we had the full frame. This avoids a crash in webcore by behaving more like CFNetwork. It also makes us behave more like Gecko, which is probably good for compat. The original patch (r47599) broke plugins on Windows because it was depending on the assumption that we would send data as one big chunk. Now that we send data as multiple chunks, we need to update the data offset being sent to the plugin. BUG=30880 Review URL: http://codereview.chromium.org/2787002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49355 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r--webkit/glue/multipart_response_delegate.cc12
-rw-r--r--webkit/glue/multipart_response_delegate_unittest.cc22
-rw-r--r--webkit/glue/plugins/webplugin_impl.cc1
3 files changed, 24 insertions, 11 deletions
diff --git a/webkit/glue/multipart_response_delegate.cc b/webkit/glue/multipart_response_delegate.cc
index 8de6469..1b68064 100644
--- a/webkit/glue/multipart_response_delegate.cc
+++ b/webkit/glue/multipart_response_delegate.cc
@@ -149,6 +149,18 @@ void MultipartResponseDelegate::OnReceivedData(const char* data,
break;
}
}
+
+ // At this point, we should send over any data we have, but keep enough data
+ // buffered to handle a boundary that may have been truncated.
+ if (!processing_headers_ && data_.length() > boundary_.length()) {
+ // If the last character is a new line character, go ahead and just send
+ // everything we have buffered. This matches an optimization in Gecko.
+ int send_length = data_.length() - boundary_.length();
+ if (data_[data_.length() - 1] == '\n')
+ send_length = data_.length();
+ client_->didReceiveData(loader_, data_.data(), send_length);
+ data_ = data_.substr(send_length);
+ }
}
void MultipartResponseDelegate::OnCompletedRequest() {
diff --git a/webkit/glue/multipart_response_delegate_unittest.cc b/webkit/glue/multipart_response_delegate_unittest.cc
index 7e3cc32..84d1e05 100644
--- a/webkit/glue/multipart_response_delegate_unittest.cc
+++ b/webkit/glue/multipart_response_delegate_unittest.cc
@@ -237,8 +237,8 @@ TEST(MultipartResponseTest, MissingBoundaries) {
delegate2.OnReceivedData(no_end_boundary.c_str(),
static_cast<int>(no_end_boundary.length()));
EXPECT_EQ(1, client.received_response_);
- EXPECT_EQ(0, client.received_data_);
- EXPECT_EQ(string(), client.data_);
+ EXPECT_EQ(1, client.received_data_);
+ EXPECT_EQ("This is a sample response\n", client.data_);
delegate2.OnCompletedRequest();
EXPECT_EQ(1, client.received_response_);
@@ -255,8 +255,8 @@ TEST(MultipartResponseTest, MissingBoundaries) {
delegate3.OnReceivedData(no_boundaries.c_str(),
static_cast<int>(no_boundaries.length()));
EXPECT_EQ(1, client.received_response_);
- EXPECT_EQ(0, client.received_data_);
- EXPECT_EQ(string(), client.data_);
+ EXPECT_EQ(1, client.received_data_);
+ EXPECT_EQ("This is a sample response\n", client.data_);
delegate3.OnCompletedRequest();
EXPECT_EQ(1, client.received_response_);
@@ -355,20 +355,20 @@ TEST(MultipartResponseTest, BreakInBoundary) {
// Break in first and second
const TestChunk bound2[] = {
{ 0, 4, 0, 0, ""},
- { 4, 55, 1, 0, "" },
- { 55, 65, 1, 1, "datadatadatadatadata" },
- { 65, 110, 2, 2, "foofoofoofoofoo" },
+ { 4, 55, 1, 1, "datadatadatadat" },
+ { 55, 65, 1, 2, "datadatadatadatadata" },
+ { 65, 110, 2, 3, "foofoofoofoofoo" },
};
VariousChunkSizesTest(bound2, arraysize(bound2),
- 2, 2, "foofoofoofoofoo");
+ 2, 3, "foofoofoofoofoo");
// Break in second only
const TestChunk bound3[] = {
- { 0, 55, 1, 0, "" },
- { 55, 110, 2, 2, "foofoofoofoofoo" },
+ { 0, 55, 1, 1, "datadatadatadat" },
+ { 55, 110, 2, 3, "foofoofoofoofoo" },
};
VariousChunkSizesTest(bound3, arraysize(bound3),
- 2, 2, "foofoofoofoofoo");
+ 2, 3, "foofoofoofoofoo");
}
TEST(MultipartResponseTest, BreakInHeaders) {
diff --git a/webkit/glue/plugins/webplugin_impl.cc b/webkit/glue/plugins/webplugin_impl.cc
index b2c793e..c4b9434 100644
--- a/webkit/glue/plugins/webplugin_impl.cc
+++ b/webkit/glue/plugins/webplugin_impl.cc
@@ -109,6 +109,7 @@ class MultiPartResponseClient : public WebURLLoaderClient {
// as regular resources requested by plugins to prevent reentrancy.
resource_client_->DidReceiveData(
data, data_size, byte_range_lower_bound_);
+ byte_range_lower_bound_ += data_size;
}
virtual void didFinishLoading(WebURLLoader*) {}