Commit a48c9db1 authored by tony@chromium.org's avatar tony@chromium.org

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
parent 69fc4705
......@@ -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() {
......
......@@ -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) {
......
......@@ -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*) {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment