1 // Copyright (c) 2011 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 webkit_glue::MultipartResponseDelegate
;
24 using webkit_glue::MultipartResponseDelegateTester
;
26 namespace webkit_glue
{
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_
;
47 } // namespace webkit_glue
51 class MultipartResponseTest
: public testing::Test
{
54 class MockWebURLLoaderClient
: public WebURLLoaderClient
{
56 MockWebURLLoaderClient() { Reset(); }
58 virtual void willSendRequest(
59 WebURLLoader
*, WebURLRequest
&, const WebURLResponse
&) {}
60 virtual void didSendData(
61 WebURLLoader
*, unsigned long long, unsigned long long) {}
63 virtual void didReceiveResponse(WebURLLoader
* loader
,
64 const WebURLResponse
& response
) {
69 virtual void didReceiveData(
70 blink::WebURLLoader
* loader
,
73 int encoded_data_length
) {
75 data_
.append(data
, data_length
);
76 total_encoded_data_length_
+= encoded_data_length
;
78 virtual void didFinishLoading(WebURLLoader
*, double finishTime
) {}
79 virtual void didFail(WebURLLoader
*, const WebURLError
&) {}
82 received_response_
= received_data_
= total_encoded_data_length_
= 0;
87 string
GetResponseHeader(const char* name
) const {
88 return string(response_
.httpHeaderField(WebString::fromUTF8(name
)).utf8());
91 int received_response_
, received_data_
, total_encoded_data_length_
;
93 WebURLResponse response_
;
96 // We can't put this in an anonymous function because it's a friend class for
97 // access to private members.
98 TEST(MultipartResponseTest
, Functions
) {
101 WebURLResponse response
;
102 response
.initialize();
103 response
.setMIMEType("multipart/x-mixed-replace");
104 response
.setHTTPHeaderField("Foo", "Bar");
105 response
.setHTTPHeaderField("Content-type", "text/plain");
106 MockWebURLLoaderClient client
;
107 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
108 MultipartResponseDelegateTester
delegate_tester(&delegate
);
118 { "\r\nLine", 0, 2 },
120 { "\n\nLine", 0, 2 },
122 { "Line\r\nLine", 4, 2 },
123 { "Line\nLine", 4, 1 },
124 { "Line\n\nLine", 4, 2 },
125 { "Line\rLine", 4, 1 },
126 { "Line\r\rLine", 4, 1 },
128 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(line_tests
); ++i
) {
129 EXPECT_EQ(line_tests
[i
].expected
,
130 delegate_tester
.PushOverLine(line_tests
[i
].input
,
131 line_tests
[i
].position
));
134 // ParseHeaders tests
138 const int received_response_calls
;
141 { "This is junk", false, 0, "This is junk" },
142 { "Foo: bar\nBaz:\n\nAfter:\n", true, 1, "After:\n" },
143 { "Foo: bar\nBaz:\n", false, 0, "Foo: bar\nBaz:\n" },
144 { "Foo: bar\r\nBaz:\r\n\r\nAfter:\r\n", true, 1, "After:\r\n" },
145 { "Foo: bar\r\nBaz:\r\n", false, 0, "Foo: bar\r\nBaz:\r\n" },
146 { "Foo: bar\nBaz:\r\n\r\nAfter:\n\n", true, 1, "After:\n\n" },
147 { "Foo: bar\r\nBaz:\n", false, 0, "Foo: bar\r\nBaz:\n" },
148 { "\r\n", true, 1, "" },
150 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(header_tests
); ++i
) {
152 delegate_tester
.data().assign(header_tests
[i
].data
);
153 EXPECT_EQ(header_tests
[i
].rv
,
154 delegate_tester
.ParseHeaders());
155 EXPECT_EQ(header_tests
[i
].received_response_calls
,
156 client
.received_response_
);
157 EXPECT_EQ(string(header_tests
[i
].newdata
),
158 delegate_tester
.data());
160 // Test that the resource response is filled in correctly when parsing
163 string
test_header("content-type: image/png\ncontent-length: 10\n\n");
164 delegate_tester
.data().assign(test_header
);
165 EXPECT_TRUE(delegate_tester
.ParseHeaders());
166 EXPECT_TRUE(delegate_tester
.data().length() == 0);
167 EXPECT_EQ(string("image/png"), client
.GetResponseHeader("Content-Type"));
168 EXPECT_EQ(string("10"), client
.GetResponseHeader("content-length"));
169 // This header is passed from the original request.
170 EXPECT_EQ(string("Bar"), client
.GetResponseHeader("foo"));
172 // Make sure we parse the right mime-type if a charset is provided.
174 string
test_header2("content-type: text/html; charset=utf-8\n\n");
175 delegate_tester
.data().assign(test_header2
);
176 EXPECT_TRUE(delegate_tester
.ParseHeaders());
177 EXPECT_TRUE(delegate_tester
.data().length() == 0);
178 EXPECT_EQ(string("text/html; charset=utf-8"),
179 client
.GetResponseHeader("Content-Type"));
180 EXPECT_EQ(string("utf-8"),
181 string(client
.response_
.textEncodingName().utf8()));
183 // FindBoundary tests
185 const char* boundary
;
187 const size_t position
;
188 } boundary_tests
[] = {
189 { "bound", "bound", 0 },
190 { "bound", "--bound", 0 },
191 { "bound", "junkbound", 4 },
192 { "bound", "junk--bound", 4 },
193 { "foo", "bound", string::npos
},
194 { "bound", "--boundbound", 0 },
196 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(boundary_tests
); ++i
) {
197 delegate_tester
.boundary().assign(boundary_tests
[i
].boundary
);
198 delegate_tester
.data().assign(boundary_tests
[i
].data
);
199 EXPECT_EQ(boundary_tests
[i
].position
,
200 delegate_tester
.FindBoundary());
204 TEST(MultipartResponseTest
, MissingBoundaries
) {
205 WebURLResponse response
;
206 response
.initialize();
207 response
.setMIMEType("multipart/x-mixed-replace");
208 response
.setHTTPHeaderField("Foo", "Bar");
209 response
.setHTTPHeaderField("Content-type", "text/plain");
210 MockWebURLLoaderClient client
;
211 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
214 string
no_start_boundary(
215 "Content-type: text/plain\n\n"
216 "This is a sample response\n"
218 "ignore junk after end token --bound\n\nTest2\n");
219 delegate
.OnReceivedData(no_start_boundary
.c_str(),
220 static_cast<int>(no_start_boundary
.length()),
221 static_cast<int>(no_start_boundary
.length()));
222 EXPECT_EQ(1, client
.received_response_
);
223 EXPECT_EQ(1, client
.received_data_
);
224 EXPECT_EQ(string("This is a sample response"), client
.data_
);
225 EXPECT_EQ(static_cast<int>(no_start_boundary
.length()),
226 client
.total_encoded_data_length_
);
228 delegate
.OnCompletedRequest();
229 EXPECT_EQ(1, client
.received_response_
);
230 EXPECT_EQ(1, client
.received_data_
);
234 MultipartResponseDelegate
delegate2(&client
, NULL
, response
, "bound");
235 string
no_end_boundary(
236 "bound\nContent-type: text/plain\n\n"
237 "This is a sample response\n");
238 delegate2
.OnReceivedData(no_end_boundary
.c_str(),
239 static_cast<int>(no_end_boundary
.length()),
240 static_cast<int>(no_end_boundary
.length()));
241 EXPECT_EQ(1, client
.received_response_
);
242 EXPECT_EQ(1, client
.received_data_
);
243 EXPECT_EQ("This is a sample response\n", client
.data_
);
244 EXPECT_EQ(static_cast<int>(no_end_boundary
.length()),
245 client
.total_encoded_data_length_
);
247 delegate2
.OnCompletedRequest();
248 EXPECT_EQ(1, client
.received_response_
);
249 EXPECT_EQ(1, client
.received_data_
);
250 EXPECT_EQ(string("This is a sample response\n"), client
.data_
);
251 EXPECT_EQ(static_cast<int>(no_end_boundary
.length()),
252 client
.total_encoded_data_length_
);
256 MultipartResponseDelegate
delegate3(&client
, NULL
, response
, "bound");
257 string
no_boundaries(
258 "Content-type: text/plain\n\n"
259 "This is a sample response\n");
260 delegate3
.OnReceivedData(no_boundaries
.c_str(),
261 static_cast<int>(no_boundaries
.length()),
262 static_cast<int>(no_boundaries
.length()));
263 EXPECT_EQ(1, client
.received_response_
);
264 EXPECT_EQ(1, client
.received_data_
);
265 EXPECT_EQ("This is a sample response\n", client
.data_
);
266 EXPECT_EQ(static_cast<int>(no_boundaries
.length()),
267 client
.total_encoded_data_length_
);
269 delegate3
.OnCompletedRequest();
270 EXPECT_EQ(1, client
.received_response_
);
271 EXPECT_EQ(1, client
.received_data_
);
272 EXPECT_EQ(string("This is a sample response\n"), client
.data_
);
273 EXPECT_EQ(static_cast<int>(no_boundaries
.length()),
274 client
.total_encoded_data_length_
);
277 TEST(MultipartResponseTest
, MalformedBoundary
) {
278 // Some servers send a boundary that is prefixed by "--". See bug 5786.
280 WebURLResponse response
;
281 response
.initialize();
282 response
.setMIMEType("multipart/x-mixed-replace");
283 response
.setHTTPHeaderField("Foo", "Bar");
284 response
.setHTTPHeaderField("Content-type", "text/plain");
285 MockWebURLLoaderClient client
;
286 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "--bound");
290 "Content-type: text/plain\n\n"
291 "This is a sample response\n"
293 "ignore junk after end token --bound\n\nTest2\n");
294 delegate
.OnReceivedData(data
.c_str(),
295 static_cast<int>(data
.length()),
296 static_cast<int>(data
.length()));
297 EXPECT_EQ(1, client
.received_response_
);
298 EXPECT_EQ(1, client
.received_data_
);
299 EXPECT_EQ(string("This is a sample response"), client
.data_
);
300 EXPECT_EQ(static_cast<int>(data
.length()), client
.total_encoded_data_length_
);
302 delegate
.OnCompletedRequest();
303 EXPECT_EQ(1, client
.received_response_
);
304 EXPECT_EQ(1, client
.received_data_
);
308 // Used in for tests that break the data in various places.
310 const int start_pos
; // offset in data
311 const int end_pos
; // end offset in data
312 const int expected_responses
;
313 const int expected_received_data
;
314 const char* expected_data
;
315 const int expected_encoded_data_length
;
318 void VariousChunkSizesTest(const TestChunk chunks
[], int chunks_size
,
319 int responses
, int received_data
,
320 const char* completed_data
,
321 int completed_encoded_data_length
) {
324 "Content-type: image/png\n\n" // 8-32
325 "datadatadatadatadata" // 33-52
327 "Content-type: image/jpg\n\n" // 61-85
328 "foofoofoofoofoo" // 86-100
329 "--bound--"); // 101-109
331 WebURLResponse response
;
332 response
.initialize();
333 response
.setMIMEType("multipart/x-mixed-replace");
334 MockWebURLLoaderClient client
;
335 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
337 for (int i
= 0; i
< chunks_size
; ++i
) {
338 ASSERT_TRUE(chunks
[i
].start_pos
< chunks
[i
].end_pos
);
339 string chunk
= data
.substr(chunks
[i
].start_pos
,
340 chunks
[i
].end_pos
- chunks
[i
].start_pos
);
341 delegate
.OnReceivedData(
343 static_cast<int>(chunk
.length()),
344 static_cast<int>(chunk
.length()));
345 EXPECT_EQ(chunks
[i
].expected_responses
, client
.received_response_
);
346 EXPECT_EQ(chunks
[i
].expected_received_data
, client
.received_data_
);
347 EXPECT_EQ(string(chunks
[i
].expected_data
), client
.data_
);
348 EXPECT_EQ(chunks
[i
].expected_encoded_data_length
,
349 client
.total_encoded_data_length_
);
352 delegate
.OnCompletedRequest();
353 EXPECT_EQ(responses
, client
.received_response_
);
354 EXPECT_EQ(received_data
, client
.received_data_
);
355 string
completed_data_string(completed_data
);
356 EXPECT_EQ(completed_data_string
, client
.data_
);
357 EXPECT_EQ(completed_encoded_data_length
, client
.total_encoded_data_length_
);
360 TEST(MultipartResponseTest
, BreakInBoundary
) {
361 // Break in the first boundary
362 const TestChunk bound1
[] = {
363 { 0, 4, 0, 0, "", 0 },
364 { 4, 110, 2, 2, "foofoofoofoofoo", 110 },
366 VariousChunkSizesTest(bound1
, arraysize(bound1
),
367 2, 2, "foofoofoofoofoo", 110);
369 // Break in first and second
370 const TestChunk bound2
[] = {
371 { 0, 4, 0, 0, "", 0 },
372 { 4, 55, 1, 1, "datadatadatadat", 55 },
373 { 55, 65, 1, 2, "datadatadatadatadata", 65 },
374 { 65, 110, 2, 3, "foofoofoofoofoo", 110 },
376 VariousChunkSizesTest(bound2
, arraysize(bound2
),
377 2, 3, "foofoofoofoofoo", 110);
379 // Break in second only
380 const TestChunk bound3
[] = {
381 { 0, 55, 1, 1, "datadatadatadat", 55 },
382 { 55, 110, 2, 3, "foofoofoofoofoo", 110 },
384 VariousChunkSizesTest(bound3
, arraysize(bound3
),
385 2, 3, "foofoofoofoofoo", 110);
388 TEST(MultipartResponseTest
, BreakInHeaders
) {
389 // Break in first header
390 const TestChunk header1
[] = {
391 { 0, 10, 0, 0, "", 0 },
392 { 10, 35, 1, 0, "", 0 },
393 { 35, 110, 2, 2, "foofoofoofoofoo", 110 },
395 VariousChunkSizesTest(header1
, arraysize(header1
),
396 2, 2, "foofoofoofoofoo", 110);
398 // Break in both headers
399 const TestChunk header2
[] = {
400 { 0, 10, 0, 0, "", 0 },
401 { 10, 65, 1, 1, "datadatadatadatadata", 65 },
402 { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
404 VariousChunkSizesTest(header2
, arraysize(header2
),
405 2, 2, "foofoofoofoofoo", 110);
407 // Break at end of a header
408 const TestChunk header3
[] = {
409 { 0, 33, 1, 0, "", 0 },
410 { 33, 65, 1, 1, "datadatadatadatadata", 65 },
411 { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
413 VariousChunkSizesTest(header3
, arraysize(header3
),
414 2, 2, "foofoofoofoofoo", 110);
417 TEST(MultipartResponseTest
, BreakInData
) {
418 // All data as one chunk
419 const TestChunk data1
[] = {
420 { 0, 110, 2, 2, "foofoofoofoofoo", 110 },
422 VariousChunkSizesTest(data1
, arraysize(data1
),
423 2, 2, "foofoofoofoofoo", 110);
425 // breaks in data segment
426 const TestChunk data2
[] = {
427 { 0, 35, 1, 0, "", 0 },
428 { 35, 65, 1, 1, "datadatadatadatadata", 65 },
429 { 65, 90, 2, 1, "", 65 },
430 { 90, 110, 2, 2, "foofoofoofoofoo", 110 },
432 VariousChunkSizesTest(data2
, arraysize(data2
),
433 2, 2, "foofoofoofoofoo", 110);
436 const TestChunk data3
[] = {
437 { 0, 35, 1, 0, "", 0 },
438 { 35, 90, 2, 1, "", 90 },
440 VariousChunkSizesTest(data3
, arraysize(data3
),
444 TEST(MultipartResponseTest
, SmallChunk
) {
445 WebURLResponse response
;
446 response
.initialize();
447 response
.setMIMEType("multipart/x-mixed-replace");
448 response
.setHTTPHeaderField("Content-type", "text/plain");
449 MockWebURLLoaderClient client
;
450 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
452 // Test chunks of size 1, 2, and 0.
454 "--boundContent-type: text/plain\n\n"
455 "\n--boundContent-type: text/plain\n\n"
456 "\n\n--boundContent-type: text/plain\n\n"
457 "--boundContent-type: text/plain\n\n"
459 delegate
.OnReceivedData(data
.c_str(),
460 static_cast<int>(data
.length()),
461 static_cast<int>(data
.length()));
462 EXPECT_EQ(4, client
.received_response_
);
463 EXPECT_EQ(2, client
.received_data_
);
464 EXPECT_EQ(string("end"), client
.data_
);
465 EXPECT_EQ(static_cast<int>(data
.length()), client
.total_encoded_data_length_
);
467 delegate
.OnCompletedRequest();
468 EXPECT_EQ(4, client
.received_response_
);
469 EXPECT_EQ(2, client
.received_data_
);
472 TEST(MultipartResponseTest
, MultipleBoundaries
) {
473 // Test multiple boundaries back to back
474 WebURLResponse response
;
475 response
.initialize();
476 response
.setMIMEType("multipart/x-mixed-replace");
477 MockWebURLLoaderClient client
;
478 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
480 string
data("--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--");
481 delegate
.OnReceivedData(data
.c_str(),
482 static_cast<int>(data
.length()),
483 static_cast<int>(data
.length()));
484 EXPECT_EQ(2, client
.received_response_
);
485 EXPECT_EQ(1, client
.received_data_
);
486 EXPECT_EQ(string("foofoo"), client
.data_
);
487 EXPECT_EQ(static_cast<int>(data
.length()), client
.total_encoded_data_length_
);
490 TEST(MultipartResponseTest
, MultipartByteRangeParsingTest
) {
491 // Test multipart/byteranges based boundary parsing.
492 WebURLResponse response1
;
493 response1
.initialize();
494 response1
.setMIMEType("multipart/x-mixed-replace");
495 response1
.setHTTPHeaderField("Content-Length", "200");
496 response1
.setHTTPHeaderField("Content-type",
497 "multipart/byteranges; boundary=--bound--");
499 std::string multipart_boundary
;
500 bool result
= MultipartResponseDelegate::ReadMultipartBoundary(
501 response1
, &multipart_boundary
);
502 EXPECT_EQ(result
, true);
503 EXPECT_EQ(string("--bound--"),
506 WebURLResponse response2
;
507 response2
.initialize();
508 response2
.setMIMEType("image/png");
510 response2
.setHTTPHeaderField("Content-Length", "300");
511 response2
.setHTTPHeaderField("Last-Modified",
512 "Mon, 04 Apr 2005 20:36:01 GMT");
513 response2
.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
515 multipart_boundary
.clear();
516 result
= MultipartResponseDelegate::ReadMultipartBoundary(
517 response2
, &multipart_boundary
);
518 EXPECT_EQ(result
, false);
520 WebURLResponse response3
;
521 response3
.initialize();
522 response3
.setMIMEType("multipart/byteranges");
524 response3
.setHTTPHeaderField("Content-Length", "300");
525 response3
.setHTTPHeaderField("Last-Modified",
526 "Mon, 04 Apr 2005 20:36:01 GMT");
527 response3
.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
528 response3
.setHTTPHeaderField("Content-type", "multipart/byteranges");
530 multipart_boundary
.clear();
531 result
= MultipartResponseDelegate::ReadMultipartBoundary(
532 response3
, &multipart_boundary
);
533 EXPECT_EQ(result
, false);
534 EXPECT_EQ(multipart_boundary
.length(), 0U);
536 WebURLResponse response4
;
537 response4
.initialize();
538 response4
.setMIMEType("multipart/byteranges");
539 response4
.setHTTPHeaderField("Content-Length", "200");
540 response4
.setHTTPHeaderField("Content-type",
541 "multipart/byteranges; boundary=--bound--; charSet=utf8");
543 multipart_boundary
.clear();
545 result
= MultipartResponseDelegate::ReadMultipartBoundary(
546 response4
, &multipart_boundary
);
547 EXPECT_EQ(result
, true);
548 EXPECT_EQ(string("--bound--"), multipart_boundary
);
550 WebURLResponse response5
;
551 response5
.initialize();
552 response5
.setMIMEType("multipart/byteranges");
553 response5
.setHTTPHeaderField("Content-Length", "200");
554 response5
.setHTTPHeaderField("Content-type",
555 "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8");
557 multipart_boundary
.clear();
559 result
= MultipartResponseDelegate::ReadMultipartBoundary(
560 response5
, &multipart_boundary
);
561 EXPECT_EQ(result
, true);
562 EXPECT_EQ(string("--bound--"), multipart_boundary
);
565 TEST(MultipartResponseTest
, MultipartContentRangesTest
) {
566 WebURLResponse response1
;
567 response1
.initialize();
568 response1
.setMIMEType("application/pdf");
569 response1
.setHTTPHeaderField("Content-Length", "200"); // Ignored!
570 // Use intentionally >32bit values to check they are handled correctly.
571 response1
.setHTTPHeaderField("Content-Range",
572 "bytes 5000000000-5000000050/6000000000");
574 int64 content_range_lower_bound
= 0;
575 int64 content_range_upper_bound
= 0;
576 int64 content_range_instance_size
= 0;
578 bool result
= MultipartResponseDelegate::ReadContentRanges(
579 response1
, &content_range_lower_bound
,
580 &content_range_upper_bound
,
581 &content_range_instance_size
);
583 EXPECT_EQ(result
, true);
584 EXPECT_EQ(content_range_lower_bound
, 5e9
);
585 EXPECT_EQ(content_range_upper_bound
, 5e9
+50);
586 EXPECT_EQ(content_range_instance_size
, 6e9
);
588 WebURLResponse response2
;
589 response2
.initialize();
590 response2
.setMIMEType("application/pdf");
591 response2
.setHTTPHeaderField("Content-Length", "200");
592 response2
.setHTTPHeaderField("Content-Range", "bytes 1000/1050");
594 content_range_lower_bound
= 0;
595 content_range_upper_bound
= 0;
596 content_range_instance_size
= 0;
598 result
= MultipartResponseDelegate::ReadContentRanges(
599 response2
, &content_range_lower_bound
,
600 &content_range_upper_bound
,
601 &content_range_instance_size
);
603 EXPECT_EQ(result
, false);
605 WebURLResponse response3
;
606 response3
.initialize();
607 response3
.setMIMEType("application/pdf");
608 response3
.setHTTPHeaderField("Content-Length", "200");
609 response3
.setHTTPHeaderField("Range", "bytes 1000-1050/5000");
611 content_range_lower_bound
= 0;
612 content_range_upper_bound
= 0;
613 content_range_instance_size
= 0;
615 result
= MultipartResponseDelegate::ReadContentRanges(
616 response3
, &content_range_lower_bound
,
617 &content_range_upper_bound
,
618 &content_range_instance_size
);
620 EXPECT_EQ(result
, true);
621 EXPECT_EQ(content_range_lower_bound
, 1000);
622 EXPECT_EQ(content_range_upper_bound
, 1050);
624 WebURLResponse response4
;
625 response4
.initialize();
626 response4
.setMIMEType("application/pdf");
627 response4
.setHTTPHeaderField("Content-Length", "200");
629 content_range_lower_bound
= 0;
630 content_range_upper_bound
= 0;
631 content_range_instance_size
= 0;
633 result
= MultipartResponseDelegate::ReadContentRanges(
634 response4
, &content_range_lower_bound
,
635 &content_range_upper_bound
,
636 &content_range_instance_size
);
638 EXPECT_EQ(result
, false);
641 TEST(MultipartResponseTest
, MultipartPayloadSet
) {
642 WebURLResponse response
;
643 response
.initialize();
644 response
.setMIMEType("multipart/x-mixed-replace");
645 MockWebURLLoaderClient client
;
646 MultipartResponseDelegate
delegate(&client
, NULL
, response
, "bound");
650 "Content-type: text/plain\n\n"
653 delegate
.OnReceivedData(data
.c_str(),
654 static_cast<int>(data
.length()),
655 static_cast<int>(data
.length()));
656 EXPECT_EQ(1, client
.received_response_
);
657 EXPECT_EQ(string("response data"), client
.data_
);
658 EXPECT_EQ(static_cast<int>(data
.length()), client
.total_encoded_data_length_
);
659 EXPECT_FALSE(client
.response_
.isMultipartPayload());
662 "Content-type: text/plain\n\n"
665 delegate
.OnReceivedData(data2
.c_str(),
666 static_cast<int>(data2
.length()),
667 static_cast<int>(data2
.length()));
668 EXPECT_EQ(2, client
.received_response_
);
669 EXPECT_EQ(string("response data2"), client
.data_
);
670 EXPECT_EQ(static_cast<int>(data
.length()) + static_cast<int>(data2
.length()),
671 client
.total_encoded_data_length_
);
672 EXPECT_TRUE(client
.response_
.isMultipartPayload());