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.
7 #include "base/basictypes.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/WebKit/public/platform/WebString.h"
10 #include "third_party/WebKit/public/platform/WebURL.h"
11 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
12 #include "third_party/WebKit/public/platform/WebURLResponse.h"
13 #include "webkit/child/multipart_response_delegate.h"
16 using blink::WebString
;
18 using blink::WebURLError
;
19 using blink::WebURLLoader
;
20 using blink::WebURLLoaderClient
;
21 using blink::WebURLRequest
;
22 using blink::WebURLResponse
;
23 using content::MultipartResponseDelegateTester
;
24 using webkit_glue::MultipartResponseDelegate
;
28 class MultipartResponseDelegateTester
{
30 MultipartResponseDelegateTester(MultipartResponseDelegate
* delegate
)
31 : delegate_(delegate
) {
34 int PushOverLine(const std::string
& data
, size_t pos
) {
35 return delegate_
->PushOverLine(data
, pos
);
38 bool ParseHeaders() { return delegate_
->ParseHeaders(); }
39 size_t FindBoundary() { return delegate_
->FindBoundary(); }
40 std::string
& boundary() { return delegate_
->boundary_
; }
41 std::string
& data() { return delegate_
->data_
; }
44 MultipartResponseDelegate
* delegate_
;
49 class MultipartResponseTest
: public testing::Test
{
52 class MockWebURLLoaderClient
: public WebURLLoaderClient
{
54 MockWebURLLoaderClient() { Reset(); }
56 virtual void willSendRequest(
57 WebURLLoader
*, WebURLRequest
&, const WebURLResponse
&) {}
58 virtual void didSendData(
59 WebURLLoader
*, unsigned long long, unsigned long long) {}
61 virtual void didReceiveResponse(WebURLLoader
* loader
,
62 const WebURLResponse
& response
) {
67 virtual void didReceiveData(
68 blink::WebURLLoader
* loader
,
71 int encoded_data_length
) {
73 data_
.append(data
, data_length
);
74 total_encoded_data_length_
+= encoded_data_length
;
76 virtual void didFinishLoading(
77 WebURLLoader
*, double finishTime
, int64_t total_encoded_data_length
) {}
78 virtual void didFail(WebURLLoader
*, const WebURLError
&) {}
81 received_response_
= received_data_
= total_encoded_data_length_
= 0;
86 string
GetResponseHeader(const char* name
) const {
87 return string(response_
.httpHeaderField(WebString::fromUTF8(name
)).utf8());
90 int received_response_
, received_data_
, total_encoded_data_length_
;
92 WebURLResponse response_
;
95 // We can't put this in an anonymous function because it's a friend class for
96 // access to private members.
97 TEST(MultipartResponseTest
, Functions
) {
100 WebURLResponse response
;
101 response
.initialize();
102 response
.setMIMEType("multipart/x-mixed-replace");
103 response
.setHTTPHeaderField("Foo", "Bar");
104 response
.setHTTPHeaderField("Content-type", "text/plain");
105 MockWebURLLoaderClient client
;
106 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
107 MultipartResponseDelegateTester
delegate_tester(&delegate
);
117 { "\r\nLine", 0, 2 },
119 { "\n\nLine", 0, 2 },
121 { "Line\r\nLine", 4, 2 },
122 { "Line\nLine", 4, 1 },
123 { "Line\n\nLine", 4, 2 },
124 { "Line\rLine", 4, 1 },
125 { "Line\r\rLine", 4, 1 },
127 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(line_tests
); ++i
) {
128 EXPECT_EQ(line_tests
[i
].expected
,
129 delegate_tester
.PushOverLine(line_tests
[i
].input
,
130 line_tests
[i
].position
));
133 // ParseHeaders tests
137 const int received_response_calls
;
140 { "This is junk", false, 0, "This is junk" },
141 { "Foo: bar\nBaz:\n\nAfter:\n", true, 1, "After:\n" },
142 { "Foo: bar\nBaz:\n", false, 0, "Foo: bar\nBaz:\n" },
143 { "Foo: bar\r\nBaz:\r\n\r\nAfter:\r\n", true, 1, "After:\r\n" },
144 { "Foo: bar\r\nBaz:\r\n", false, 0, "Foo: bar\r\nBaz:\r\n" },
145 { "Foo: bar\nBaz:\r\n\r\nAfter:\n\n", true, 1, "After:\n\n" },
146 { "Foo: bar\r\nBaz:\n", false, 0, "Foo: bar\r\nBaz:\n" },
147 { "\r\n", true, 1, "" },
149 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(header_tests
); ++i
) {
151 delegate_tester
.data().assign(header_tests
[i
].data
);
152 EXPECT_EQ(header_tests
[i
].rv
,
153 delegate_tester
.ParseHeaders());
154 EXPECT_EQ(header_tests
[i
].received_response_calls
,
155 client
.received_response_
);
156 EXPECT_EQ(string(header_tests
[i
].newdata
),
157 delegate_tester
.data());
159 // Test that the resource response is filled in correctly when parsing
162 string
test_header("content-type: image/png\ncontent-length: 10\n\n");
163 delegate_tester
.data().assign(test_header
);
164 EXPECT_TRUE(delegate_tester
.ParseHeaders());
165 EXPECT_TRUE(delegate_tester
.data().length() == 0);
166 EXPECT_EQ(string("image/png"), client
.GetResponseHeader("Content-Type"));
167 EXPECT_EQ(string("10"), client
.GetResponseHeader("content-length"));
168 // This header is passed from the original request.
169 EXPECT_EQ(string("Bar"), client
.GetResponseHeader("foo"));
171 // Make sure we parse the right mime-type if a charset is provided.
173 string
test_header2("content-type: text/html; charset=utf-8\n\n");
174 delegate_tester
.data().assign(test_header2
);
175 EXPECT_TRUE(delegate_tester
.ParseHeaders());
176 EXPECT_TRUE(delegate_tester
.data().length() == 0);
177 EXPECT_EQ(string("text/html; charset=utf-8"),
178 client
.GetResponseHeader("Content-Type"));
179 EXPECT_EQ(string("utf-8"),
180 string(client
.response_
.textEncodingName().utf8()));
182 // FindBoundary tests
184 const char* boundary
;
186 const size_t position
;
187 } boundary_tests
[] = {
188 { "bound", "bound", 0 },
189 { "bound", "--bound", 0 },
190 { "bound", "junkbound", 4 },
191 { "bound", "junk--bound", 4 },
192 { "foo", "bound", string::npos
},
193 { "bound", "--boundbound", 0 },
195 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(boundary_tests
); ++i
) {
196 delegate_tester
.boundary().assign(boundary_tests
[i
].boundary
);
197 delegate_tester
.data().assign(boundary_tests
[i
].data
);
198 EXPECT_EQ(boundary_tests
[i
].position
,
199 delegate_tester
.FindBoundary());
203 TEST(MultipartResponseTest
, MissingBoundaries
) {
204 WebURLResponse response
;
205 response
.initialize();
206 response
.setMIMEType("multipart/x-mixed-replace");
207 response
.setHTTPHeaderField("Foo", "Bar");
208 response
.setHTTPHeaderField("Content-type", "text/plain");
209 MockWebURLLoaderClient client
;
210 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
213 string
no_start_boundary(
214 "Content-type: text/plain\n\n"
215 "This is a sample response\n"
217 "ignore junk after end token --bound\n\nTest2\n");
218 delegate
.OnReceivedData(no_start_boundary
.c_str(),
219 static_cast<int>(no_start_boundary
.length()),
220 static_cast<int>(no_start_boundary
.length()));
221 EXPECT_EQ(1, client
.received_response_
);
222 EXPECT_EQ(1, client
.received_data_
);
223 EXPECT_EQ(string("This is a sample response"), client
.data_
);
224 EXPECT_EQ(static_cast<int>(no_start_boundary
.length()),
225 client
.total_encoded_data_length_
);
227 delegate
.OnCompletedRequest();
228 EXPECT_EQ(1, client
.received_response_
);
229 EXPECT_EQ(1, client
.received_data_
);
233 MultipartResponseDelegate
delegate2(&client
, NULL
, response
, "bound");
234 string
no_end_boundary(
235 "bound\nContent-type: text/plain\n\n"
236 "This is a sample response\n");
237 delegate2
.OnReceivedData(no_end_boundary
.c_str(),
238 static_cast<int>(no_end_boundary
.length()),
239 static_cast<int>(no_end_boundary
.length()));
240 EXPECT_EQ(1, client
.received_response_
);
241 EXPECT_EQ(1, client
.received_data_
);
242 EXPECT_EQ("This is a sample response\n", client
.data_
);
243 EXPECT_EQ(static_cast<int>(no_end_boundary
.length()),
244 client
.total_encoded_data_length_
);
246 delegate2
.OnCompletedRequest();
247 EXPECT_EQ(1, client
.received_response_
);
248 EXPECT_EQ(1, client
.received_data_
);
249 EXPECT_EQ(string("This is a sample response\n"), client
.data_
);
250 EXPECT_EQ(static_cast<int>(no_end_boundary
.length()),
251 client
.total_encoded_data_length_
);
255 MultipartResponseDelegate
delegate3(&client
, NULL
, response
, "bound");
256 string
no_boundaries(
257 "Content-type: text/plain\n\n"
258 "This is a sample response\n");
259 delegate3
.OnReceivedData(no_boundaries
.c_str(),
260 static_cast<int>(no_boundaries
.length()),
261 static_cast<int>(no_boundaries
.length()));
262 EXPECT_EQ(1, client
.received_response_
);
263 EXPECT_EQ(1, client
.received_data_
);
264 EXPECT_EQ("This is a sample response\n", client
.data_
);
265 EXPECT_EQ(static_cast<int>(no_boundaries
.length()),
266 client
.total_encoded_data_length_
);
268 delegate3
.OnCompletedRequest();
269 EXPECT_EQ(1, client
.received_response_
);
270 EXPECT_EQ(1, client
.received_data_
);
271 EXPECT_EQ(string("This is a sample response\n"), client
.data_
);
272 EXPECT_EQ(static_cast<int>(no_boundaries
.length()),
273 client
.total_encoded_data_length_
);
276 TEST(MultipartResponseTest
, MalformedBoundary
) {
277 // Some servers send a boundary that is prefixed by "--". See bug 5786.
279 WebURLResponse response
;
280 response
.initialize();
281 response
.setMIMEType("multipart/x-mixed-replace");
282 response
.setHTTPHeaderField("Foo", "Bar");
283 response
.setHTTPHeaderField("Content-type", "text/plain");
284 MockWebURLLoaderClient client
;
285 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "--bound");
289 "Content-type: text/plain\n\n"
290 "This is a sample response\n"
292 "ignore junk after end token --bound\n\nTest2\n");
293 delegate
.OnReceivedData(data
.c_str(),
294 static_cast<int>(data
.length()),
295 static_cast<int>(data
.length()));
296 EXPECT_EQ(1, client
.received_response_
);
297 EXPECT_EQ(1, client
.received_data_
);
298 EXPECT_EQ(string("This is a sample response"), client
.data_
);
299 EXPECT_EQ(static_cast<int>(data
.length()), client
.total_encoded_data_length_
);
301 delegate
.OnCompletedRequest();
302 EXPECT_EQ(1, client
.received_response_
);
303 EXPECT_EQ(1, client
.received_data_
);
307 // Used in for tests that break the data in various places.
309 const int start_pos
; // offset in data
310 const int end_pos
; // end offset in data
311 const int expected_responses
;
312 const int expected_received_data
;
313 const char* expected_data
;
314 const int expected_encoded_data_length
;
317 void VariousChunkSizesTest(const TestChunk chunks
[], int chunks_size
,
318 int responses
, int received_data
,
319 const char* completed_data
,
320 int completed_encoded_data_length
) {
323 "Content-type: image/png\n\n" // 8-32
324 "datadatadatadatadata" // 33-52
326 "Content-type: image/jpg\n\n" // 61-85
327 "foofoofoofoofoo" // 86-100
328 "--bound--"); // 101-109
330 WebURLResponse response
;
331 response
.initialize();
332 response
.setMIMEType("multipart/x-mixed-replace");
333 MockWebURLLoaderClient client
;
334 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
336 for (int i
= 0; i
< chunks_size
; ++i
) {
337 ASSERT_TRUE(chunks
[i
].start_pos
< chunks
[i
].end_pos
);
338 string chunk
= data
.substr(chunks
[i
].start_pos
,
339 chunks
[i
].end_pos
- chunks
[i
].start_pos
);
340 delegate
.OnReceivedData(
342 static_cast<int>(chunk
.length()),
343 static_cast<int>(chunk
.length()));
344 EXPECT_EQ(chunks
[i
].expected_responses
, client
.received_response_
);
345 EXPECT_EQ(chunks
[i
].expected_received_data
, client
.received_data_
);
346 EXPECT_EQ(string(chunks
[i
].expected_data
), client
.data_
);
347 EXPECT_EQ(chunks
[i
].expected_encoded_data_length
,
348 client
.total_encoded_data_length_
);
351 delegate
.OnCompletedRequest();
352 EXPECT_EQ(responses
, client
.received_response_
);
353 EXPECT_EQ(received_data
, client
.received_data_
);
354 string
completed_data_string(completed_data
);
355 EXPECT_EQ(completed_data_string
, client
.data_
);
356 EXPECT_EQ(completed_encoded_data_length
, client
.total_encoded_data_length_
);
359 TEST(MultipartResponseTest
, BreakInBoundary
) {
360 // Break in the first boundary
361 const TestChunk bound1
[] = {
362 { 0, 4, 0, 0, "", 0 },
363 { 4, 110, 2, 2, "foofoofoofoofoo", 110 },
365 VariousChunkSizesTest(bound1
, arraysize(bound1
),
366 2, 2, "foofoofoofoofoo", 110);
368 // Break in first and second
369 const TestChunk bound2
[] = {
370 { 0, 4, 0, 0, "", 0 },
371 { 4, 55, 1, 1, "datadatadatadat", 55 },
372 { 55, 65, 1, 2, "datadatadatadatadata", 65 },
373 { 65, 110, 2, 3, "foofoofoofoofoo", 110 },
375 VariousChunkSizesTest(bound2
, arraysize(bound2
),
376 2, 3, "foofoofoofoofoo", 110);
378 // Break in second only
379 const TestChunk bound3
[] = {
380 { 0, 55, 1, 1, "datadatadatadat", 55 },
381 { 55, 110, 2, 3, "foofoofoofoofoo", 110 },
383 VariousChunkSizesTest(bound3
, arraysize(bound3
),
384 2, 3, "foofoofoofoofoo", 110);
387 TEST(MultipartResponseTest
, BreakInHeaders
) {
388 // Break in first header
389 const TestChunk header1
[] = {
390 { 0, 10, 0, 0, "", 0 },
391 { 10, 35, 1, 0, "", 0 },
392 { 35, 110, 2, 2, "foofoofoofoofoo", 110 },
394 VariousChunkSizesTest(header1
, arraysize(header1
),
395 2, 2, "foofoofoofoofoo", 110);
397 // Break in both headers
398 const TestChunk header2
[] = {
399 { 0, 10, 0, 0, "", 0 },
400 { 10, 65, 1, 1, "datadatadatadatadata", 65 },
401 { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
403 VariousChunkSizesTest(header2
, arraysize(header2
),
404 2, 2, "foofoofoofoofoo", 110);
406 // Break at end of a header
407 const TestChunk header3
[] = {
408 { 0, 33, 1, 0, "", 0 },
409 { 33, 65, 1, 1, "datadatadatadatadata", 65 },
410 { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
412 VariousChunkSizesTest(header3
, arraysize(header3
),
413 2, 2, "foofoofoofoofoo", 110);
416 TEST(MultipartResponseTest
, BreakInData
) {
417 // All data as one chunk
418 const TestChunk data1
[] = {
419 { 0, 110, 2, 2, "foofoofoofoofoo", 110 },
421 VariousChunkSizesTest(data1
, arraysize(data1
),
422 2, 2, "foofoofoofoofoo", 110);
424 // breaks in data segment
425 const TestChunk data2
[] = {
426 { 0, 35, 1, 0, "", 0 },
427 { 35, 65, 1, 1, "datadatadatadatadata", 65 },
428 { 65, 90, 2, 1, "", 65 },
429 { 90, 110, 2, 2, "foofoofoofoofoo", 110 },
431 VariousChunkSizesTest(data2
, arraysize(data2
),
432 2, 2, "foofoofoofoofoo", 110);
435 const TestChunk data3
[] = {
436 { 0, 35, 1, 0, "", 0 },
437 { 35, 90, 2, 1, "", 90 },
439 VariousChunkSizesTest(data3
, arraysize(data3
),
443 TEST(MultipartResponseTest
, SmallChunk
) {
444 WebURLResponse response
;
445 response
.initialize();
446 response
.setMIMEType("multipart/x-mixed-replace");
447 response
.setHTTPHeaderField("Content-type", "text/plain");
448 MockWebURLLoaderClient client
;
449 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
451 // Test chunks of size 1, 2, and 0.
453 "--boundContent-type: text/plain\n\n"
454 "\n--boundContent-type: text/plain\n\n"
455 "\n\n--boundContent-type: text/plain\n\n"
456 "--boundContent-type: text/plain\n\n"
458 delegate
.OnReceivedData(data
.c_str(),
459 static_cast<int>(data
.length()),
460 static_cast<int>(data
.length()));
461 EXPECT_EQ(4, client
.received_response_
);
462 EXPECT_EQ(2, client
.received_data_
);
463 EXPECT_EQ(string("end"), client
.data_
);
464 EXPECT_EQ(static_cast<int>(data
.length()), client
.total_encoded_data_length_
);
466 delegate
.OnCompletedRequest();
467 EXPECT_EQ(4, client
.received_response_
);
468 EXPECT_EQ(2, client
.received_data_
);
471 TEST(MultipartResponseTest
, MultipleBoundaries
) {
472 // Test multiple boundaries back to back
473 WebURLResponse response
;
474 response
.initialize();
475 response
.setMIMEType("multipart/x-mixed-replace");
476 MockWebURLLoaderClient client
;
477 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
479 string
data("--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--");
480 delegate
.OnReceivedData(data
.c_str(),
481 static_cast<int>(data
.length()),
482 static_cast<int>(data
.length()));
483 EXPECT_EQ(2, client
.received_response_
);
484 EXPECT_EQ(1, client
.received_data_
);
485 EXPECT_EQ(string("foofoo"), client
.data_
);
486 EXPECT_EQ(static_cast<int>(data
.length()), client
.total_encoded_data_length_
);
489 TEST(MultipartResponseTest
, MultipartByteRangeParsingTest
) {
490 // Test multipart/byteranges based boundary parsing.
491 WebURLResponse response1
;
492 response1
.initialize();
493 response1
.setMIMEType("multipart/x-mixed-replace");
494 response1
.setHTTPHeaderField("Content-Length", "200");
495 response1
.setHTTPHeaderField("Content-type",
496 "multipart/byteranges; boundary=--bound--");
498 std::string multipart_boundary
;
499 bool result
= MultipartResponseDelegate::ReadMultipartBoundary(
500 response1
, &multipart_boundary
);
501 EXPECT_EQ(result
, true);
502 EXPECT_EQ(string("--bound--"),
505 WebURLResponse response2
;
506 response2
.initialize();
507 response2
.setMIMEType("image/png");
509 response2
.setHTTPHeaderField("Content-Length", "300");
510 response2
.setHTTPHeaderField("Last-Modified",
511 "Mon, 04 Apr 2005 20:36:01 GMT");
512 response2
.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
514 multipart_boundary
.clear();
515 result
= MultipartResponseDelegate::ReadMultipartBoundary(
516 response2
, &multipart_boundary
);
517 EXPECT_EQ(result
, false);
519 WebURLResponse response3
;
520 response3
.initialize();
521 response3
.setMIMEType("multipart/byteranges");
523 response3
.setHTTPHeaderField("Content-Length", "300");
524 response3
.setHTTPHeaderField("Last-Modified",
525 "Mon, 04 Apr 2005 20:36:01 GMT");
526 response3
.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
527 response3
.setHTTPHeaderField("Content-type", "multipart/byteranges");
529 multipart_boundary
.clear();
530 result
= MultipartResponseDelegate::ReadMultipartBoundary(
531 response3
, &multipart_boundary
);
532 EXPECT_EQ(result
, false);
533 EXPECT_EQ(multipart_boundary
.length(), 0U);
535 WebURLResponse response4
;
536 response4
.initialize();
537 response4
.setMIMEType("multipart/byteranges");
538 response4
.setHTTPHeaderField("Content-Length", "200");
539 response4
.setHTTPHeaderField("Content-type",
540 "multipart/byteranges; boundary=--bound--; charSet=utf8");
542 multipart_boundary
.clear();
544 result
= MultipartResponseDelegate::ReadMultipartBoundary(
545 response4
, &multipart_boundary
);
546 EXPECT_EQ(result
, true);
547 EXPECT_EQ(string("--bound--"), multipart_boundary
);
549 WebURLResponse response5
;
550 response5
.initialize();
551 response5
.setMIMEType("multipart/byteranges");
552 response5
.setHTTPHeaderField("Content-Length", "200");
553 response5
.setHTTPHeaderField("Content-type",
554 "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8");
556 multipart_boundary
.clear();
558 result
= MultipartResponseDelegate::ReadMultipartBoundary(
559 response5
, &multipart_boundary
);
560 EXPECT_EQ(result
, true);
561 EXPECT_EQ(string("--bound--"), multipart_boundary
);
564 TEST(MultipartResponseTest
, MultipartContentRangesTest
) {
565 WebURLResponse response1
;
566 response1
.initialize();
567 response1
.setMIMEType("application/pdf");
568 response1
.setHTTPHeaderField("Content-Length", "200"); // Ignored!
569 // Use intentionally >32bit values to check they are handled correctly.
570 response1
.setHTTPHeaderField("Content-Range",
571 "bytes 5000000000-5000000050/6000000000");
573 int64 content_range_lower_bound
= 0;
574 int64 content_range_upper_bound
= 0;
575 int64 content_range_instance_size
= 0;
577 bool result
= MultipartResponseDelegate::ReadContentRanges(
578 response1
, &content_range_lower_bound
,
579 &content_range_upper_bound
,
580 &content_range_instance_size
);
582 EXPECT_EQ(result
, true);
583 EXPECT_EQ(content_range_lower_bound
, 5e9
);
584 EXPECT_EQ(content_range_upper_bound
, 5e9
+50);
585 EXPECT_EQ(content_range_instance_size
, 6e9
);
587 WebURLResponse response2
;
588 response2
.initialize();
589 response2
.setMIMEType("application/pdf");
590 response2
.setHTTPHeaderField("Content-Length", "200");
591 response2
.setHTTPHeaderField("Content-Range", "bytes 1000/1050");
593 content_range_lower_bound
= 0;
594 content_range_upper_bound
= 0;
595 content_range_instance_size
= 0;
597 result
= MultipartResponseDelegate::ReadContentRanges(
598 response2
, &content_range_lower_bound
,
599 &content_range_upper_bound
,
600 &content_range_instance_size
);
602 EXPECT_EQ(result
, false);
604 WebURLResponse response3
;
605 response3
.initialize();
606 response3
.setMIMEType("application/pdf");
607 response3
.setHTTPHeaderField("Content-Length", "200");
608 response3
.setHTTPHeaderField("Range", "bytes 1000-1050/5000");
610 content_range_lower_bound
= 0;
611 content_range_upper_bound
= 0;
612 content_range_instance_size
= 0;
614 result
= MultipartResponseDelegate::ReadContentRanges(
615 response3
, &content_range_lower_bound
,
616 &content_range_upper_bound
,
617 &content_range_instance_size
);
619 EXPECT_EQ(result
, true);
620 EXPECT_EQ(content_range_lower_bound
, 1000);
621 EXPECT_EQ(content_range_upper_bound
, 1050);
623 WebURLResponse response4
;
624 response4
.initialize();
625 response4
.setMIMEType("application/pdf");
626 response4
.setHTTPHeaderField("Content-Length", "200");
628 content_range_lower_bound
= 0;
629 content_range_upper_bound
= 0;
630 content_range_instance_size
= 0;
632 result
= MultipartResponseDelegate::ReadContentRanges(
633 response4
, &content_range_lower_bound
,
634 &content_range_upper_bound
,
635 &content_range_instance_size
);
637 EXPECT_EQ(result
, false);
640 TEST(MultipartResponseTest
, MultipartPayloadSet
) {
641 WebURLResponse response
;
642 response
.initialize();
643 response
.setMIMEType("multipart/x-mixed-replace");
644 MockWebURLLoaderClient client
;
645 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
649 "Content-type: text/plain\n\n"
652 delegate
.OnReceivedData(data
.c_str(),
653 static_cast<int>(data
.length()),
654 static_cast<int>(data
.length()));
655 EXPECT_EQ(1, client
.received_response_
);
656 EXPECT_EQ(string("response data"), client
.data_
);
657 EXPECT_EQ(static_cast<int>(data
.length()), client
.total_encoded_data_length_
);
658 EXPECT_FALSE(client
.response_
.isMultipartPayload());
661 "Content-type: text/plain\n\n"
664 delegate
.OnReceivedData(data2
.c_str(),
665 static_cast<int>(data2
.length()),
666 static_cast<int>(data2
.length()));
667 EXPECT_EQ(2, client
.received_response_
);
668 EXPECT_EQ(string("response data2"), client
.data_
);
669 EXPECT_EQ(static_cast<int>(data
.length()) + static_cast<int>(data2
.length()),
670 client
.total_encoded_data_length_
);
671 EXPECT_TRUE(client
.response_
.isMultipartPayload());
676 } // namespace content