Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / child / multipart_response_delegate_unittest.cc
blob182a1f30fffcd8eb2a039da0b67e590713d2eeff
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/child/multipart_response_delegate.h"
7 #include <vector>
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/WebKit/public/platform/WebString.h"
11 #include "third_party/WebKit/public/platform/WebURL.h"
12 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
13 #include "third_party/WebKit/public/platform/WebURLResponse.h"
15 using blink::WebString;
16 using blink::WebURL;
17 using blink::WebURLError;
18 using blink::WebURLLoader;
19 using blink::WebURLLoaderClient;
20 using blink::WebURLRequest;
21 using blink::WebURLResponse;
22 using std::string;
24 namespace content {
26 class MultipartResponseDelegateTester {
27 public:
28 MultipartResponseDelegateTester(MultipartResponseDelegate* delegate)
29 : delegate_(delegate) {
32 int PushOverLine(const std::string& data, size_t pos) {
33 return delegate_->PushOverLine(data, pos);
36 bool ParseHeaders() { return delegate_->ParseHeaders(); }
37 size_t FindBoundary() { return delegate_->FindBoundary(); }
38 std::string& boundary() { return delegate_->boundary_; }
39 std::string& data() { return delegate_->data_; }
41 private:
42 MultipartResponseDelegate* delegate_;
45 namespace {
47 class MultipartResponseTest : public testing::Test {
50 class MockWebURLLoaderClient : public WebURLLoaderClient {
51 public:
52 MockWebURLLoaderClient() { Reset(); }
54 virtual void willSendRequest(
55 WebURLLoader*, WebURLRequest&, const WebURLResponse&) {}
56 virtual void didSendData(
57 WebURLLoader*, unsigned long long, unsigned long long) {}
59 virtual void didReceiveResponse(WebURLLoader* loader,
60 const WebURLResponse& response) {
61 ++received_response_;
62 response_ = response;
63 data_.clear();
65 virtual void didReceiveData(
66 blink::WebURLLoader* loader,
67 const char* data,
68 int data_length,
69 int encoded_data_length) {
70 ++received_data_;
71 data_.append(data, data_length);
72 total_encoded_data_length_ += encoded_data_length;
74 virtual void didFinishLoading(
75 WebURLLoader*, double finishTime, int64_t total_encoded_data_length) {}
76 virtual void didFail(WebURLLoader*, const WebURLError&) {}
78 void Reset() {
79 received_response_ = received_data_ = total_encoded_data_length_ = 0;
80 data_.clear();
81 response_.reset();
84 string GetResponseHeader(const char* name) const {
85 return string(response_.httpHeaderField(WebString::fromUTF8(name)).utf8());
88 int received_response_, received_data_, total_encoded_data_length_;
89 string data_;
90 WebURLResponse response_;
93 // We can't put this in an anonymous function because it's a friend class for
94 // access to private members.
95 TEST(MultipartResponseTest, Functions) {
96 // PushOverLine tests
98 WebURLResponse response;
99 response.initialize();
100 response.setMIMEType("multipart/x-mixed-replace");
101 response.setHTTPHeaderField("Foo", "Bar");
102 response.setHTTPHeaderField("Content-type", "text/plain");
103 MockWebURLLoaderClient client;
104 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
105 MultipartResponseDelegateTester delegate_tester(&delegate);
107 struct {
108 const char* input;
109 const int position;
110 const int expected;
111 } line_tests[] = {
112 { "Line", 0, 0 },
113 { "Line", 2, 0 },
114 { "Line", 10, 0 },
115 { "\r\nLine", 0, 2 },
116 { "\nLine", 0, 1 },
117 { "\n\nLine", 0, 2 },
118 { "\rLine", 0, 1 },
119 { "Line\r\nLine", 4, 2 },
120 { "Line\nLine", 4, 1 },
121 { "Line\n\nLine", 4, 2 },
122 { "Line\rLine", 4, 1 },
123 { "Line\r\rLine", 4, 1 },
125 for (size_t i = 0; i < arraysize(line_tests); ++i) {
126 EXPECT_EQ(line_tests[i].expected,
127 delegate_tester.PushOverLine(line_tests[i].input,
128 line_tests[i].position));
131 // ParseHeaders tests
132 struct {
133 const char* data;
134 const bool rv;
135 const int received_response_calls;
136 const char* newdata;
137 } header_tests[] = {
138 { "This is junk", false, 0, "This is junk" },
139 { "Foo: bar\nBaz:\n\nAfter:\n", true, 1, "After:\n" },
140 { "Foo: bar\nBaz:\n", false, 0, "Foo: bar\nBaz:\n" },
141 { "Foo: bar\r\nBaz:\r\n\r\nAfter:\r\n", true, 1, "After:\r\n" },
142 { "Foo: bar\r\nBaz:\r\n", false, 0, "Foo: bar\r\nBaz:\r\n" },
143 { "Foo: bar\nBaz:\r\n\r\nAfter:\n\n", true, 1, "After:\n\n" },
144 { "Foo: bar\r\nBaz:\n", false, 0, "Foo: bar\r\nBaz:\n" },
145 { "\r\n", true, 1, "" },
147 for (size_t i = 0; i < arraysize(header_tests); ++i) {
148 client.Reset();
149 delegate_tester.data().assign(header_tests[i].data);
150 EXPECT_EQ(header_tests[i].rv,
151 delegate_tester.ParseHeaders());
152 EXPECT_EQ(header_tests[i].received_response_calls,
153 client.received_response_);
154 EXPECT_EQ(string(header_tests[i].newdata),
155 delegate_tester.data());
157 // Test that the resource response is filled in correctly when parsing
158 // headers.
159 client.Reset();
160 string test_header("content-type: image/png\ncontent-length: 10\n\n");
161 delegate_tester.data().assign(test_header);
162 EXPECT_TRUE(delegate_tester.ParseHeaders());
163 EXPECT_TRUE(delegate_tester.data().length() == 0);
164 EXPECT_EQ(string("image/png"), client.GetResponseHeader("Content-Type"));
165 EXPECT_EQ(string("10"), client.GetResponseHeader("content-length"));
166 // This header is passed from the original request.
167 EXPECT_EQ(string("Bar"), client.GetResponseHeader("foo"));
169 // Make sure we parse the right mime-type if a charset is provided.
170 client.Reset();
171 string test_header2("content-type: text/html; charset=utf-8\n\n");
172 delegate_tester.data().assign(test_header2);
173 EXPECT_TRUE(delegate_tester.ParseHeaders());
174 EXPECT_TRUE(delegate_tester.data().length() == 0);
175 EXPECT_EQ(string("text/html; charset=utf-8"),
176 client.GetResponseHeader("Content-Type"));
177 EXPECT_EQ(string("utf-8"),
178 string(client.response_.textEncodingName().utf8()));
180 // FindBoundary tests
181 struct {
182 const char* boundary;
183 const char* data;
184 const size_t position;
185 } boundary_tests[] = {
186 { "bound", "bound", 0 },
187 { "bound", "--bound", 0 },
188 { "bound", "junkbound", 4 },
189 { "bound", "junk--bound", 4 },
190 { "foo", "bound", string::npos },
191 { "bound", "--boundbound", 0 },
193 for (size_t i = 0; i < arraysize(boundary_tests); ++i) {
194 delegate_tester.boundary().assign(boundary_tests[i].boundary);
195 delegate_tester.data().assign(boundary_tests[i].data);
196 EXPECT_EQ(boundary_tests[i].position,
197 delegate_tester.FindBoundary());
201 TEST(MultipartResponseTest, MissingBoundaries) {
202 WebURLResponse response;
203 response.initialize();
204 response.setMIMEType("multipart/x-mixed-replace");
205 response.setHTTPHeaderField("Foo", "Bar");
206 response.setHTTPHeaderField("Content-type", "text/plain");
207 MockWebURLLoaderClient client;
208 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
210 // No start boundary
211 string no_start_boundary(
212 "Content-type: text/plain\n\n"
213 "This is a sample response\n"
214 "--bound--"
215 "ignore junk after end token --bound\n\nTest2\n");
216 delegate.OnReceivedData(no_start_boundary.c_str(),
217 static_cast<int>(no_start_boundary.length()),
218 static_cast<int>(no_start_boundary.length()));
219 EXPECT_EQ(1, client.received_response_);
220 EXPECT_EQ(1, client.received_data_);
221 EXPECT_EQ(string("This is a sample response"), client.data_);
222 EXPECT_EQ(static_cast<int>(no_start_boundary.length()),
223 client.total_encoded_data_length_);
225 delegate.OnCompletedRequest();
226 EXPECT_EQ(1, client.received_response_);
227 EXPECT_EQ(1, client.received_data_);
229 // No end boundary
230 client.Reset();
231 MultipartResponseDelegate delegate2(&client, NULL, response, "bound");
232 string no_end_boundary(
233 "bound\nContent-type: text/plain\n\n"
234 "This is a sample response\n");
235 delegate2.OnReceivedData(no_end_boundary.c_str(),
236 static_cast<int>(no_end_boundary.length()),
237 static_cast<int>(no_end_boundary.length()));
238 EXPECT_EQ(1, client.received_response_);
239 EXPECT_EQ(1, client.received_data_);
240 EXPECT_EQ("This is a sample response\n", client.data_);
241 EXPECT_EQ(static_cast<int>(no_end_boundary.length()),
242 client.total_encoded_data_length_);
244 delegate2.OnCompletedRequest();
245 EXPECT_EQ(1, client.received_response_);
246 EXPECT_EQ(1, client.received_data_);
247 EXPECT_EQ(string("This is a sample response\n"), client.data_);
248 EXPECT_EQ(static_cast<int>(no_end_boundary.length()),
249 client.total_encoded_data_length_);
251 // Neither boundary
252 client.Reset();
253 MultipartResponseDelegate delegate3(&client, NULL, response, "bound");
254 string no_boundaries(
255 "Content-type: text/plain\n\n"
256 "This is a sample response\n");
257 delegate3.OnReceivedData(no_boundaries.c_str(),
258 static_cast<int>(no_boundaries.length()),
259 static_cast<int>(no_boundaries.length()));
260 EXPECT_EQ(1, client.received_response_);
261 EXPECT_EQ(1, client.received_data_);
262 EXPECT_EQ("This is a sample response\n", client.data_);
263 EXPECT_EQ(static_cast<int>(no_boundaries.length()),
264 client.total_encoded_data_length_);
266 delegate3.OnCompletedRequest();
267 EXPECT_EQ(1, client.received_response_);
268 EXPECT_EQ(1, client.received_data_);
269 EXPECT_EQ(string("This is a sample response\n"), client.data_);
270 EXPECT_EQ(static_cast<int>(no_boundaries.length()),
271 client.total_encoded_data_length_);
274 TEST(MultipartResponseTest, MalformedBoundary) {
275 // Some servers send a boundary that is prefixed by "--". See bug 5786.
277 WebURLResponse response;
278 response.initialize();
279 response.setMIMEType("multipart/x-mixed-replace");
280 response.setHTTPHeaderField("Foo", "Bar");
281 response.setHTTPHeaderField("Content-type", "text/plain");
282 MockWebURLLoaderClient client;
283 MultipartResponseDelegate delegate(&client, NULL, response, "--bound");
285 string data(
286 "--bound\n"
287 "Content-type: text/plain\n\n"
288 "This is a sample response\n"
289 "--bound--"
290 "ignore junk after end token --bound\n\nTest2\n");
291 delegate.OnReceivedData(data.c_str(),
292 static_cast<int>(data.length()),
293 static_cast<int>(data.length()));
294 EXPECT_EQ(1, client.received_response_);
295 EXPECT_EQ(1, client.received_data_);
296 EXPECT_EQ(string("This is a sample response"), client.data_);
297 EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
299 delegate.OnCompletedRequest();
300 EXPECT_EQ(1, client.received_response_);
301 EXPECT_EQ(1, client.received_data_);
305 // Used in for tests that break the data in various places.
306 struct TestChunk {
307 const int start_pos; // offset in data
308 const int end_pos; // end offset in data
309 const int expected_responses;
310 const int expected_received_data;
311 const char* expected_data;
312 const int expected_encoded_data_length;
315 void VariousChunkSizesTest(const TestChunk chunks[], int chunks_size,
316 int responses, int received_data,
317 const char* completed_data,
318 int completed_encoded_data_length) {
319 const string data(
320 "--bound\n" // 0-7
321 "Content-type: image/png\n\n" // 8-32
322 "datadatadatadatadata" // 33-52
323 "--bound\n" // 53-60
324 "Content-type: image/jpg\n\n" // 61-85
325 "foofoofoofoofoo" // 86-100
326 "--bound--"); // 101-109
328 WebURLResponse response;
329 response.initialize();
330 response.setMIMEType("multipart/x-mixed-replace");
331 MockWebURLLoaderClient client;
332 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
334 for (int i = 0; i < chunks_size; ++i) {
335 ASSERT_TRUE(chunks[i].start_pos < chunks[i].end_pos);
336 string chunk = data.substr(chunks[i].start_pos,
337 chunks[i].end_pos - chunks[i].start_pos);
338 delegate.OnReceivedData(
339 chunk.c_str(),
340 static_cast<int>(chunk.length()),
341 static_cast<int>(chunk.length()));
342 EXPECT_EQ(chunks[i].expected_responses, client.received_response_);
343 EXPECT_EQ(chunks[i].expected_received_data, client.received_data_);
344 EXPECT_EQ(string(chunks[i].expected_data), client.data_);
345 EXPECT_EQ(chunks[i].expected_encoded_data_length,
346 client.total_encoded_data_length_);
348 // Check final state
349 delegate.OnCompletedRequest();
350 EXPECT_EQ(responses, client.received_response_);
351 EXPECT_EQ(received_data, client.received_data_);
352 string completed_data_string(completed_data);
353 EXPECT_EQ(completed_data_string, client.data_);
354 EXPECT_EQ(completed_encoded_data_length, client.total_encoded_data_length_);
357 TEST(MultipartResponseTest, BreakInBoundary) {
358 // Break in the first boundary
359 const TestChunk bound1[] = {
360 { 0, 4, 0, 0, "", 0 },
361 { 4, 110, 2, 2, "foofoofoofoofoo", 110 },
363 VariousChunkSizesTest(bound1, arraysize(bound1),
364 2, 2, "foofoofoofoofoo", 110);
366 // Break in first and second
367 const TestChunk bound2[] = {
368 { 0, 4, 0, 0, "", 0 },
369 { 4, 55, 1, 1, "datadatadatadat", 55 },
370 { 55, 65, 1, 2, "datadatadatadatadata", 65 },
371 { 65, 110, 2, 3, "foofoofoofoofoo", 110 },
373 VariousChunkSizesTest(bound2, arraysize(bound2),
374 2, 3, "foofoofoofoofoo", 110);
376 // Break in second only
377 const TestChunk bound3[] = {
378 { 0, 55, 1, 1, "datadatadatadat", 55 },
379 { 55, 110, 2, 3, "foofoofoofoofoo", 110 },
381 VariousChunkSizesTest(bound3, arraysize(bound3),
382 2, 3, "foofoofoofoofoo", 110);
385 TEST(MultipartResponseTest, BreakInHeaders) {
386 // Break in first header
387 const TestChunk header1[] = {
388 { 0, 10, 0, 0, "", 0 },
389 { 10, 35, 1, 0, "", 0 },
390 { 35, 110, 2, 2, "foofoofoofoofoo", 110 },
392 VariousChunkSizesTest(header1, arraysize(header1),
393 2, 2, "foofoofoofoofoo", 110);
395 // Break in both headers
396 const TestChunk header2[] = {
397 { 0, 10, 0, 0, "", 0 },
398 { 10, 65, 1, 1, "datadatadatadatadata", 65 },
399 { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
401 VariousChunkSizesTest(header2, arraysize(header2),
402 2, 2, "foofoofoofoofoo", 110);
404 // Break at end of a header
405 const TestChunk header3[] = {
406 { 0, 33, 1, 0, "", 0 },
407 { 33, 65, 1, 1, "datadatadatadatadata", 65 },
408 { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
410 VariousChunkSizesTest(header3, arraysize(header3),
411 2, 2, "foofoofoofoofoo", 110);
414 TEST(MultipartResponseTest, BreakInData) {
415 // All data as one chunk
416 const TestChunk data1[] = {
417 { 0, 110, 2, 2, "foofoofoofoofoo", 110 },
419 VariousChunkSizesTest(data1, arraysize(data1),
420 2, 2, "foofoofoofoofoo", 110);
422 // breaks in data segment
423 const TestChunk data2[] = {
424 { 0, 35, 1, 0, "", 0 },
425 { 35, 65, 1, 1, "datadatadatadatadata", 65 },
426 { 65, 90, 2, 1, "", 65 },
427 { 90, 110, 2, 2, "foofoofoofoofoo", 110 },
429 VariousChunkSizesTest(data2, arraysize(data2),
430 2, 2, "foofoofoofoofoo", 110);
432 // Incomplete send
433 const TestChunk data3[] = {
434 { 0, 35, 1, 0, "", 0 },
435 { 35, 90, 2, 1, "", 90 },
437 VariousChunkSizesTest(data3, arraysize(data3),
438 2, 2, "foof", 90);
441 TEST(MultipartResponseTest, SmallChunk) {
442 WebURLResponse response;
443 response.initialize();
444 response.setMIMEType("multipart/x-mixed-replace");
445 response.setHTTPHeaderField("Content-type", "text/plain");
446 MockWebURLLoaderClient client;
447 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
449 // Test chunks of size 1, 2, and 0.
450 string data(
451 "--boundContent-type: text/plain\n\n"
452 "\n--boundContent-type: text/plain\n\n"
453 "\n\n--boundContent-type: text/plain\n\n"
454 "--boundContent-type: text/plain\n\n"
455 "end--bound--");
456 delegate.OnReceivedData(data.c_str(),
457 static_cast<int>(data.length()),
458 static_cast<int>(data.length()));
459 EXPECT_EQ(4, client.received_response_);
460 EXPECT_EQ(2, client.received_data_);
461 EXPECT_EQ(string("end"), client.data_);
462 EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
464 delegate.OnCompletedRequest();
465 EXPECT_EQ(4, client.received_response_);
466 EXPECT_EQ(2, client.received_data_);
469 TEST(MultipartResponseTest, MultipleBoundaries) {
470 // Test multiple boundaries back to back
471 WebURLResponse response;
472 response.initialize();
473 response.setMIMEType("multipart/x-mixed-replace");
474 MockWebURLLoaderClient client;
475 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
477 string data("--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--");
478 delegate.OnReceivedData(data.c_str(),
479 static_cast<int>(data.length()),
480 static_cast<int>(data.length()));
481 EXPECT_EQ(2, client.received_response_);
482 EXPECT_EQ(1, client.received_data_);
483 EXPECT_EQ(string("foofoo"), client.data_);
484 EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
487 TEST(MultipartResponseTest, MultipartByteRangeParsingTest) {
488 // Test multipart/byteranges based boundary parsing.
489 WebURLResponse response1;
490 response1.initialize();
491 response1.setMIMEType("multipart/x-mixed-replace");
492 response1.setHTTPHeaderField("Content-Length", "200");
493 response1.setHTTPHeaderField("Content-type",
494 "multipart/byteranges; boundary=--bound--");
496 std::string multipart_boundary;
497 bool result = MultipartResponseDelegate::ReadMultipartBoundary(
498 response1, &multipart_boundary);
499 EXPECT_EQ(result, true);
500 EXPECT_EQ(string("--bound--"),
501 multipart_boundary);
503 WebURLResponse response2;
504 response2.initialize();
505 response2.setMIMEType("image/png");
507 response2.setHTTPHeaderField("Content-Length", "300");
508 response2.setHTTPHeaderField("Last-Modified",
509 "Mon, 04 Apr 2005 20:36:01 GMT");
510 response2.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
512 multipart_boundary.clear();
513 result = MultipartResponseDelegate::ReadMultipartBoundary(
514 response2, &multipart_boundary);
515 EXPECT_EQ(result, false);
517 WebURLResponse response3;
518 response3.initialize();
519 response3.setMIMEType("multipart/byteranges");
521 response3.setHTTPHeaderField("Content-Length", "300");
522 response3.setHTTPHeaderField("Last-Modified",
523 "Mon, 04 Apr 2005 20:36:01 GMT");
524 response3.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
525 response3.setHTTPHeaderField("Content-type", "multipart/byteranges");
527 multipart_boundary.clear();
528 result = MultipartResponseDelegate::ReadMultipartBoundary(
529 response3, &multipart_boundary);
530 EXPECT_EQ(result, false);
531 EXPECT_EQ(multipart_boundary.length(), 0U);
533 WebURLResponse response4;
534 response4.initialize();
535 response4.setMIMEType("multipart/byteranges");
536 response4.setHTTPHeaderField("Content-Length", "200");
537 response4.setHTTPHeaderField("Content-type",
538 "multipart/byteranges; boundary=--bound--; charSet=utf8");
540 multipart_boundary.clear();
542 result = MultipartResponseDelegate::ReadMultipartBoundary(
543 response4, &multipart_boundary);
544 EXPECT_EQ(result, true);
545 EXPECT_EQ(string("--bound--"), multipart_boundary);
547 WebURLResponse response5;
548 response5.initialize();
549 response5.setMIMEType("multipart/byteranges");
550 response5.setHTTPHeaderField("Content-Length", "200");
551 response5.setHTTPHeaderField("Content-type",
552 "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8");
554 multipart_boundary.clear();
556 result = MultipartResponseDelegate::ReadMultipartBoundary(
557 response5, &multipart_boundary);
558 EXPECT_EQ(result, true);
559 EXPECT_EQ(string("--bound--"), multipart_boundary);
562 TEST(MultipartResponseTest, MultipartContentRangesTest) {
563 WebURLResponse response1;
564 response1.initialize();
565 response1.setMIMEType("application/pdf");
566 response1.setHTTPHeaderField("Content-Length", "200"); // Ignored!
567 // Use intentionally >32bit values to check they are handled correctly.
568 response1.setHTTPHeaderField("Content-Range",
569 "bytes 5000000000-5000000050/6000000000");
571 int64 content_range_lower_bound = 0;
572 int64 content_range_upper_bound = 0;
573 int64 content_range_instance_size = 0;
575 bool result = MultipartResponseDelegate::ReadContentRanges(
576 response1, &content_range_lower_bound,
577 &content_range_upper_bound,
578 &content_range_instance_size);
580 EXPECT_EQ(result, true);
581 EXPECT_EQ(content_range_lower_bound, 5e9);
582 EXPECT_EQ(content_range_upper_bound, 5e9+50);
583 EXPECT_EQ(content_range_instance_size, 6e9);
585 WebURLResponse response2;
586 response2.initialize();
587 response2.setMIMEType("application/pdf");
588 response2.setHTTPHeaderField("Content-Length", "200");
589 response2.setHTTPHeaderField("Content-Range", "bytes 1000/1050");
591 content_range_lower_bound = 0;
592 content_range_upper_bound = 0;
593 content_range_instance_size = 0;
595 result = MultipartResponseDelegate::ReadContentRanges(
596 response2, &content_range_lower_bound,
597 &content_range_upper_bound,
598 &content_range_instance_size);
600 EXPECT_EQ(result, false);
602 WebURLResponse response3;
603 response3.initialize();
604 response3.setMIMEType("application/pdf");
605 response3.setHTTPHeaderField("Content-Length", "200");
606 response3.setHTTPHeaderField("Range", "bytes 1000-1050/5000");
608 content_range_lower_bound = 0;
609 content_range_upper_bound = 0;
610 content_range_instance_size = 0;
612 result = MultipartResponseDelegate::ReadContentRanges(
613 response3, &content_range_lower_bound,
614 &content_range_upper_bound,
615 &content_range_instance_size);
617 EXPECT_EQ(result, true);
618 EXPECT_EQ(content_range_lower_bound, 1000);
619 EXPECT_EQ(content_range_upper_bound, 1050);
621 WebURLResponse response4;
622 response4.initialize();
623 response4.setMIMEType("application/pdf");
624 response4.setHTTPHeaderField("Content-Length", "200");
626 content_range_lower_bound = 0;
627 content_range_upper_bound = 0;
628 content_range_instance_size = 0;
630 result = MultipartResponseDelegate::ReadContentRanges(
631 response4, &content_range_lower_bound,
632 &content_range_upper_bound,
633 &content_range_instance_size);
635 EXPECT_EQ(result, false);
638 TEST(MultipartResponseTest, MultipartPayloadSet) {
639 WebURLResponse response;
640 response.initialize();
641 response.setMIMEType("multipart/x-mixed-replace");
642 MockWebURLLoaderClient client;
643 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
645 string data(
646 "--bound\n"
647 "Content-type: text/plain\n\n"
648 "response data\n"
649 "--bound\n");
650 delegate.OnReceivedData(data.c_str(),
651 static_cast<int>(data.length()),
652 static_cast<int>(data.length()));
653 EXPECT_EQ(1, client.received_response_);
654 EXPECT_EQ(string("response data"), client.data_);
655 EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
656 EXPECT_FALSE(client.response_.isMultipartPayload());
658 string data2(
659 "Content-type: text/plain\n\n"
660 "response data2\n"
661 "--bound\n");
662 delegate.OnReceivedData(data2.c_str(),
663 static_cast<int>(data2.length()),
664 static_cast<int>(data2.length()));
665 EXPECT_EQ(2, client.received_response_);
666 EXPECT_EQ(string("response data2"), client.data_);
667 EXPECT_EQ(static_cast<int>(data.length()) + static_cast<int>(data2.length()),
668 client.total_encoded_data_length_);
669 EXPECT_TRUE(client.response_.isMultipartPayload());
672 } // namespace
674 } // namespace content