diff options
author | tony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-10 01:22:47 +0000 |
---|---|---|
committer | tony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-10 01:22:47 +0000 |
commit | a48c9db101d6a0c8a92b6d50eff8534cf86053e7 (patch) | |
tree | 7df269d4f87ecc07cfbf93130c6dd28b27d38843 /webkit/glue | |
parent | 69fc470526aa66350c8a7ecea4b902b06404bb33 (diff) | |
download | chromium_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.cc | 12 | ||||
-rw-r--r-- | webkit/glue/multipart_response_delegate_unittest.cc | 22 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_impl.cc | 1 |
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*) {} |