Add support for hooking up external feedback mechanism for DOM Distiller
[chromium-blink-merge.git] / webkit / child / multipart_response_delegate_unittest.cc
blob58c92c5e448cfe7da3f30ee95a30f7a0b07f8f2e
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.
5 #include <vector>
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"
15 using std::string;
16 using blink::WebString;
17 using blink::WebURL;
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 {
29 public:
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_; }
43 private:
44 MultipartResponseDelegate* delegate_;
47 } // namespace webkit_glue
49 namespace {
51 class MultipartResponseTest : public testing::Test {
54 class MockWebURLLoaderClient : public WebURLLoaderClient {
55 public:
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) {
65 ++received_response_;
66 response_ = response;
67 data_.clear();
69 virtual void didReceiveData(
70 blink::WebURLLoader* loader,
71 const char* data,
72 int data_length,
73 int encoded_data_length) {
74 ++received_data_;
75 data_.append(data, data_length);
76 total_encoded_data_length_ += encoded_data_length;
78 virtual void didFinishLoading(
79 WebURLLoader*, double finishTime, int64_t total_encoded_data_length) {}
80 virtual void didFail(WebURLLoader*, const WebURLError&) {}
82 void Reset() {
83 received_response_ = received_data_ = total_encoded_data_length_ = 0;
84 data_.clear();
85 response_.reset();
88 string GetResponseHeader(const char* name) const {
89 return string(response_.httpHeaderField(WebString::fromUTF8(name)).utf8());
92 int received_response_, received_data_, total_encoded_data_length_;
93 string data_;
94 WebURLResponse response_;
97 // We can't put this in an anonymous function because it's a friend class for
98 // access to private members.
99 TEST(MultipartResponseTest, Functions) {
100 // PushOverLine tests
102 WebURLResponse response;
103 response.initialize();
104 response.setMIMEType("multipart/x-mixed-replace");
105 response.setHTTPHeaderField("Foo", "Bar");
106 response.setHTTPHeaderField("Content-type", "text/plain");
107 MockWebURLLoaderClient client;
108 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
109 MultipartResponseDelegateTester delegate_tester(&delegate);
111 struct {
112 const char* input;
113 const int position;
114 const int expected;
115 } line_tests[] = {
116 { "Line", 0, 0 },
117 { "Line", 2, 0 },
118 { "Line", 10, 0 },
119 { "\r\nLine", 0, 2 },
120 { "\nLine", 0, 1 },
121 { "\n\nLine", 0, 2 },
122 { "\rLine", 0, 1 },
123 { "Line\r\nLine", 4, 2 },
124 { "Line\nLine", 4, 1 },
125 { "Line\n\nLine", 4, 2 },
126 { "Line\rLine", 4, 1 },
127 { "Line\r\rLine", 4, 1 },
129 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(line_tests); ++i) {
130 EXPECT_EQ(line_tests[i].expected,
131 delegate_tester.PushOverLine(line_tests[i].input,
132 line_tests[i].position));
135 // ParseHeaders tests
136 struct {
137 const char* data;
138 const bool rv;
139 const int received_response_calls;
140 const char* newdata;
141 } header_tests[] = {
142 { "This is junk", false, 0, "This is junk" },
143 { "Foo: bar\nBaz:\n\nAfter:\n", true, 1, "After:\n" },
144 { "Foo: bar\nBaz:\n", false, 0, "Foo: bar\nBaz:\n" },
145 { "Foo: bar\r\nBaz:\r\n\r\nAfter:\r\n", true, 1, "After:\r\n" },
146 { "Foo: bar\r\nBaz:\r\n", false, 0, "Foo: bar\r\nBaz:\r\n" },
147 { "Foo: bar\nBaz:\r\n\r\nAfter:\n\n", true, 1, "After:\n\n" },
148 { "Foo: bar\r\nBaz:\n", false, 0, "Foo: bar\r\nBaz:\n" },
149 { "\r\n", true, 1, "" },
151 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(header_tests); ++i) {
152 client.Reset();
153 delegate_tester.data().assign(header_tests[i].data);
154 EXPECT_EQ(header_tests[i].rv,
155 delegate_tester.ParseHeaders());
156 EXPECT_EQ(header_tests[i].received_response_calls,
157 client.received_response_);
158 EXPECT_EQ(string(header_tests[i].newdata),
159 delegate_tester.data());
161 // Test that the resource response is filled in correctly when parsing
162 // headers.
163 client.Reset();
164 string test_header("content-type: image/png\ncontent-length: 10\n\n");
165 delegate_tester.data().assign(test_header);
166 EXPECT_TRUE(delegate_tester.ParseHeaders());
167 EXPECT_TRUE(delegate_tester.data().length() == 0);
168 EXPECT_EQ(string("image/png"), client.GetResponseHeader("Content-Type"));
169 EXPECT_EQ(string("10"), client.GetResponseHeader("content-length"));
170 // This header is passed from the original request.
171 EXPECT_EQ(string("Bar"), client.GetResponseHeader("foo"));
173 // Make sure we parse the right mime-type if a charset is provided.
174 client.Reset();
175 string test_header2("content-type: text/html; charset=utf-8\n\n");
176 delegate_tester.data().assign(test_header2);
177 EXPECT_TRUE(delegate_tester.ParseHeaders());
178 EXPECT_TRUE(delegate_tester.data().length() == 0);
179 EXPECT_EQ(string("text/html; charset=utf-8"),
180 client.GetResponseHeader("Content-Type"));
181 EXPECT_EQ(string("utf-8"),
182 string(client.response_.textEncodingName().utf8()));
184 // FindBoundary tests
185 struct {
186 const char* boundary;
187 const char* data;
188 const size_t position;
189 } boundary_tests[] = {
190 { "bound", "bound", 0 },
191 { "bound", "--bound", 0 },
192 { "bound", "junkbound", 4 },
193 { "bound", "junk--bound", 4 },
194 { "foo", "bound", string::npos },
195 { "bound", "--boundbound", 0 },
197 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(boundary_tests); ++i) {
198 delegate_tester.boundary().assign(boundary_tests[i].boundary);
199 delegate_tester.data().assign(boundary_tests[i].data);
200 EXPECT_EQ(boundary_tests[i].position,
201 delegate_tester.FindBoundary());
205 TEST(MultipartResponseTest, MissingBoundaries) {
206 WebURLResponse response;
207 response.initialize();
208 response.setMIMEType("multipart/x-mixed-replace");
209 response.setHTTPHeaderField("Foo", "Bar");
210 response.setHTTPHeaderField("Content-type", "text/plain");
211 MockWebURLLoaderClient client;
212 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
214 // No start boundary
215 string no_start_boundary(
216 "Content-type: text/plain\n\n"
217 "This is a sample response\n"
218 "--bound--"
219 "ignore junk after end token --bound\n\nTest2\n");
220 delegate.OnReceivedData(no_start_boundary.c_str(),
221 static_cast<int>(no_start_boundary.length()),
222 static_cast<int>(no_start_boundary.length()));
223 EXPECT_EQ(1, client.received_response_);
224 EXPECT_EQ(1, client.received_data_);
225 EXPECT_EQ(string("This is a sample response"), client.data_);
226 EXPECT_EQ(static_cast<int>(no_start_boundary.length()),
227 client.total_encoded_data_length_);
229 delegate.OnCompletedRequest();
230 EXPECT_EQ(1, client.received_response_);
231 EXPECT_EQ(1, client.received_data_);
233 // No end boundary
234 client.Reset();
235 MultipartResponseDelegate delegate2(&client, NULL, response, "bound");
236 string no_end_boundary(
237 "bound\nContent-type: text/plain\n\n"
238 "This is a sample response\n");
239 delegate2.OnReceivedData(no_end_boundary.c_str(),
240 static_cast<int>(no_end_boundary.length()),
241 static_cast<int>(no_end_boundary.length()));
242 EXPECT_EQ(1, client.received_response_);
243 EXPECT_EQ(1, client.received_data_);
244 EXPECT_EQ("This is a sample response\n", client.data_);
245 EXPECT_EQ(static_cast<int>(no_end_boundary.length()),
246 client.total_encoded_data_length_);
248 delegate2.OnCompletedRequest();
249 EXPECT_EQ(1, client.received_response_);
250 EXPECT_EQ(1, client.received_data_);
251 EXPECT_EQ(string("This is a sample response\n"), client.data_);
252 EXPECT_EQ(static_cast<int>(no_end_boundary.length()),
253 client.total_encoded_data_length_);
255 // Neither boundary
256 client.Reset();
257 MultipartResponseDelegate delegate3(&client, NULL, response, "bound");
258 string no_boundaries(
259 "Content-type: text/plain\n\n"
260 "This is a sample response\n");
261 delegate3.OnReceivedData(no_boundaries.c_str(),
262 static_cast<int>(no_boundaries.length()),
263 static_cast<int>(no_boundaries.length()));
264 EXPECT_EQ(1, client.received_response_);
265 EXPECT_EQ(1, client.received_data_);
266 EXPECT_EQ("This is a sample response\n", client.data_);
267 EXPECT_EQ(static_cast<int>(no_boundaries.length()),
268 client.total_encoded_data_length_);
270 delegate3.OnCompletedRequest();
271 EXPECT_EQ(1, client.received_response_);
272 EXPECT_EQ(1, client.received_data_);
273 EXPECT_EQ(string("This is a sample response\n"), client.data_);
274 EXPECT_EQ(static_cast<int>(no_boundaries.length()),
275 client.total_encoded_data_length_);
278 TEST(MultipartResponseTest, MalformedBoundary) {
279 // Some servers send a boundary that is prefixed by "--". See bug 5786.
281 WebURLResponse response;
282 response.initialize();
283 response.setMIMEType("multipart/x-mixed-replace");
284 response.setHTTPHeaderField("Foo", "Bar");
285 response.setHTTPHeaderField("Content-type", "text/plain");
286 MockWebURLLoaderClient client;
287 MultipartResponseDelegate delegate(&client, NULL, response, "--bound");
289 string data(
290 "--bound\n"
291 "Content-type: text/plain\n\n"
292 "This is a sample response\n"
293 "--bound--"
294 "ignore junk after end token --bound\n\nTest2\n");
295 delegate.OnReceivedData(data.c_str(),
296 static_cast<int>(data.length()),
297 static_cast<int>(data.length()));
298 EXPECT_EQ(1, client.received_response_);
299 EXPECT_EQ(1, client.received_data_);
300 EXPECT_EQ(string("This is a sample response"), client.data_);
301 EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
303 delegate.OnCompletedRequest();
304 EXPECT_EQ(1, client.received_response_);
305 EXPECT_EQ(1, client.received_data_);
309 // Used in for tests that break the data in various places.
310 struct TestChunk {
311 const int start_pos; // offset in data
312 const int end_pos; // end offset in data
313 const int expected_responses;
314 const int expected_received_data;
315 const char* expected_data;
316 const int expected_encoded_data_length;
319 void VariousChunkSizesTest(const TestChunk chunks[], int chunks_size,
320 int responses, int received_data,
321 const char* completed_data,
322 int completed_encoded_data_length) {
323 const string data(
324 "--bound\n" // 0-7
325 "Content-type: image/png\n\n" // 8-32
326 "datadatadatadatadata" // 33-52
327 "--bound\n" // 53-60
328 "Content-type: image/jpg\n\n" // 61-85
329 "foofoofoofoofoo" // 86-100
330 "--bound--"); // 101-109
332 WebURLResponse response;
333 response.initialize();
334 response.setMIMEType("multipart/x-mixed-replace");
335 MockWebURLLoaderClient client;
336 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
338 for (int i = 0; i < chunks_size; ++i) {
339 ASSERT_TRUE(chunks[i].start_pos < chunks[i].end_pos);
340 string chunk = data.substr(chunks[i].start_pos,
341 chunks[i].end_pos - chunks[i].start_pos);
342 delegate.OnReceivedData(
343 chunk.c_str(),
344 static_cast<int>(chunk.length()),
345 static_cast<int>(chunk.length()));
346 EXPECT_EQ(chunks[i].expected_responses, client.received_response_);
347 EXPECT_EQ(chunks[i].expected_received_data, client.received_data_);
348 EXPECT_EQ(string(chunks[i].expected_data), client.data_);
349 EXPECT_EQ(chunks[i].expected_encoded_data_length,
350 client.total_encoded_data_length_);
352 // Check final state
353 delegate.OnCompletedRequest();
354 EXPECT_EQ(responses, client.received_response_);
355 EXPECT_EQ(received_data, client.received_data_);
356 string completed_data_string(completed_data);
357 EXPECT_EQ(completed_data_string, client.data_);
358 EXPECT_EQ(completed_encoded_data_length, client.total_encoded_data_length_);
361 TEST(MultipartResponseTest, BreakInBoundary) {
362 // Break in the first boundary
363 const TestChunk bound1[] = {
364 { 0, 4, 0, 0, "", 0 },
365 { 4, 110, 2, 2, "foofoofoofoofoo", 110 },
367 VariousChunkSizesTest(bound1, arraysize(bound1),
368 2, 2, "foofoofoofoofoo", 110);
370 // Break in first and second
371 const TestChunk bound2[] = {
372 { 0, 4, 0, 0, "", 0 },
373 { 4, 55, 1, 1, "datadatadatadat", 55 },
374 { 55, 65, 1, 2, "datadatadatadatadata", 65 },
375 { 65, 110, 2, 3, "foofoofoofoofoo", 110 },
377 VariousChunkSizesTest(bound2, arraysize(bound2),
378 2, 3, "foofoofoofoofoo", 110);
380 // Break in second only
381 const TestChunk bound3[] = {
382 { 0, 55, 1, 1, "datadatadatadat", 55 },
383 { 55, 110, 2, 3, "foofoofoofoofoo", 110 },
385 VariousChunkSizesTest(bound3, arraysize(bound3),
386 2, 3, "foofoofoofoofoo", 110);
389 TEST(MultipartResponseTest, BreakInHeaders) {
390 // Break in first header
391 const TestChunk header1[] = {
392 { 0, 10, 0, 0, "", 0 },
393 { 10, 35, 1, 0, "", 0 },
394 { 35, 110, 2, 2, "foofoofoofoofoo", 110 },
396 VariousChunkSizesTest(header1, arraysize(header1),
397 2, 2, "foofoofoofoofoo", 110);
399 // Break in both headers
400 const TestChunk header2[] = {
401 { 0, 10, 0, 0, "", 0 },
402 { 10, 65, 1, 1, "datadatadatadatadata", 65 },
403 { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
405 VariousChunkSizesTest(header2, arraysize(header2),
406 2, 2, "foofoofoofoofoo", 110);
408 // Break at end of a header
409 const TestChunk header3[] = {
410 { 0, 33, 1, 0, "", 0 },
411 { 33, 65, 1, 1, "datadatadatadatadata", 65 },
412 { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
414 VariousChunkSizesTest(header3, arraysize(header3),
415 2, 2, "foofoofoofoofoo", 110);
418 TEST(MultipartResponseTest, BreakInData) {
419 // All data as one chunk
420 const TestChunk data1[] = {
421 { 0, 110, 2, 2, "foofoofoofoofoo", 110 },
423 VariousChunkSizesTest(data1, arraysize(data1),
424 2, 2, "foofoofoofoofoo", 110);
426 // breaks in data segment
427 const TestChunk data2[] = {
428 { 0, 35, 1, 0, "", 0 },
429 { 35, 65, 1, 1, "datadatadatadatadata", 65 },
430 { 65, 90, 2, 1, "", 65 },
431 { 90, 110, 2, 2, "foofoofoofoofoo", 110 },
433 VariousChunkSizesTest(data2, arraysize(data2),
434 2, 2, "foofoofoofoofoo", 110);
436 // Incomplete send
437 const TestChunk data3[] = {
438 { 0, 35, 1, 0, "", 0 },
439 { 35, 90, 2, 1, "", 90 },
441 VariousChunkSizesTest(data3, arraysize(data3),
442 2, 2, "foof", 90);
445 TEST(MultipartResponseTest, SmallChunk) {
446 WebURLResponse response;
447 response.initialize();
448 response.setMIMEType("multipart/x-mixed-replace");
449 response.setHTTPHeaderField("Content-type", "text/plain");
450 MockWebURLLoaderClient client;
451 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
453 // Test chunks of size 1, 2, and 0.
454 string data(
455 "--boundContent-type: text/plain\n\n"
456 "\n--boundContent-type: text/plain\n\n"
457 "\n\n--boundContent-type: text/plain\n\n"
458 "--boundContent-type: text/plain\n\n"
459 "end--bound--");
460 delegate.OnReceivedData(data.c_str(),
461 static_cast<int>(data.length()),
462 static_cast<int>(data.length()));
463 EXPECT_EQ(4, client.received_response_);
464 EXPECT_EQ(2, client.received_data_);
465 EXPECT_EQ(string("end"), client.data_);
466 EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
468 delegate.OnCompletedRequest();
469 EXPECT_EQ(4, client.received_response_);
470 EXPECT_EQ(2, client.received_data_);
473 TEST(MultipartResponseTest, MultipleBoundaries) {
474 // Test multiple boundaries back to back
475 WebURLResponse response;
476 response.initialize();
477 response.setMIMEType("multipart/x-mixed-replace");
478 MockWebURLLoaderClient client;
479 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
481 string data("--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--");
482 delegate.OnReceivedData(data.c_str(),
483 static_cast<int>(data.length()),
484 static_cast<int>(data.length()));
485 EXPECT_EQ(2, client.received_response_);
486 EXPECT_EQ(1, client.received_data_);
487 EXPECT_EQ(string("foofoo"), client.data_);
488 EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
491 TEST(MultipartResponseTest, MultipartByteRangeParsingTest) {
492 // Test multipart/byteranges based boundary parsing.
493 WebURLResponse response1;
494 response1.initialize();
495 response1.setMIMEType("multipart/x-mixed-replace");
496 response1.setHTTPHeaderField("Content-Length", "200");
497 response1.setHTTPHeaderField("Content-type",
498 "multipart/byteranges; boundary=--bound--");
500 std::string multipart_boundary;
501 bool result = MultipartResponseDelegate::ReadMultipartBoundary(
502 response1, &multipart_boundary);
503 EXPECT_EQ(result, true);
504 EXPECT_EQ(string("--bound--"),
505 multipart_boundary);
507 WebURLResponse response2;
508 response2.initialize();
509 response2.setMIMEType("image/png");
511 response2.setHTTPHeaderField("Content-Length", "300");
512 response2.setHTTPHeaderField("Last-Modified",
513 "Mon, 04 Apr 2005 20:36:01 GMT");
514 response2.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
516 multipart_boundary.clear();
517 result = MultipartResponseDelegate::ReadMultipartBoundary(
518 response2, &multipart_boundary);
519 EXPECT_EQ(result, false);
521 WebURLResponse response3;
522 response3.initialize();
523 response3.setMIMEType("multipart/byteranges");
525 response3.setHTTPHeaderField("Content-Length", "300");
526 response3.setHTTPHeaderField("Last-Modified",
527 "Mon, 04 Apr 2005 20:36:01 GMT");
528 response3.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
529 response3.setHTTPHeaderField("Content-type", "multipart/byteranges");
531 multipart_boundary.clear();
532 result = MultipartResponseDelegate::ReadMultipartBoundary(
533 response3, &multipart_boundary);
534 EXPECT_EQ(result, false);
535 EXPECT_EQ(multipart_boundary.length(), 0U);
537 WebURLResponse response4;
538 response4.initialize();
539 response4.setMIMEType("multipart/byteranges");
540 response4.setHTTPHeaderField("Content-Length", "200");
541 response4.setHTTPHeaderField("Content-type",
542 "multipart/byteranges; boundary=--bound--; charSet=utf8");
544 multipart_boundary.clear();
546 result = MultipartResponseDelegate::ReadMultipartBoundary(
547 response4, &multipart_boundary);
548 EXPECT_EQ(result, true);
549 EXPECT_EQ(string("--bound--"), multipart_boundary);
551 WebURLResponse response5;
552 response5.initialize();
553 response5.setMIMEType("multipart/byteranges");
554 response5.setHTTPHeaderField("Content-Length", "200");
555 response5.setHTTPHeaderField("Content-type",
556 "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8");
558 multipart_boundary.clear();
560 result = MultipartResponseDelegate::ReadMultipartBoundary(
561 response5, &multipart_boundary);
562 EXPECT_EQ(result, true);
563 EXPECT_EQ(string("--bound--"), multipart_boundary);
566 TEST(MultipartResponseTest, MultipartContentRangesTest) {
567 WebURLResponse response1;
568 response1.initialize();
569 response1.setMIMEType("application/pdf");
570 response1.setHTTPHeaderField("Content-Length", "200"); // Ignored!
571 // Use intentionally >32bit values to check they are handled correctly.
572 response1.setHTTPHeaderField("Content-Range",
573 "bytes 5000000000-5000000050/6000000000");
575 int64 content_range_lower_bound = 0;
576 int64 content_range_upper_bound = 0;
577 int64 content_range_instance_size = 0;
579 bool result = MultipartResponseDelegate::ReadContentRanges(
580 response1, &content_range_lower_bound,
581 &content_range_upper_bound,
582 &content_range_instance_size);
584 EXPECT_EQ(result, true);
585 EXPECT_EQ(content_range_lower_bound, 5e9);
586 EXPECT_EQ(content_range_upper_bound, 5e9+50);
587 EXPECT_EQ(content_range_instance_size, 6e9);
589 WebURLResponse response2;
590 response2.initialize();
591 response2.setMIMEType("application/pdf");
592 response2.setHTTPHeaderField("Content-Length", "200");
593 response2.setHTTPHeaderField("Content-Range", "bytes 1000/1050");
595 content_range_lower_bound = 0;
596 content_range_upper_bound = 0;
597 content_range_instance_size = 0;
599 result = MultipartResponseDelegate::ReadContentRanges(
600 response2, &content_range_lower_bound,
601 &content_range_upper_bound,
602 &content_range_instance_size);
604 EXPECT_EQ(result, false);
606 WebURLResponse response3;
607 response3.initialize();
608 response3.setMIMEType("application/pdf");
609 response3.setHTTPHeaderField("Content-Length", "200");
610 response3.setHTTPHeaderField("Range", "bytes 1000-1050/5000");
612 content_range_lower_bound = 0;
613 content_range_upper_bound = 0;
614 content_range_instance_size = 0;
616 result = MultipartResponseDelegate::ReadContentRanges(
617 response3, &content_range_lower_bound,
618 &content_range_upper_bound,
619 &content_range_instance_size);
621 EXPECT_EQ(result, true);
622 EXPECT_EQ(content_range_lower_bound, 1000);
623 EXPECT_EQ(content_range_upper_bound, 1050);
625 WebURLResponse response4;
626 response4.initialize();
627 response4.setMIMEType("application/pdf");
628 response4.setHTTPHeaderField("Content-Length", "200");
630 content_range_lower_bound = 0;
631 content_range_upper_bound = 0;
632 content_range_instance_size = 0;
634 result = MultipartResponseDelegate::ReadContentRanges(
635 response4, &content_range_lower_bound,
636 &content_range_upper_bound,
637 &content_range_instance_size);
639 EXPECT_EQ(result, false);
642 TEST(MultipartResponseTest, MultipartPayloadSet) {
643 WebURLResponse response;
644 response.initialize();
645 response.setMIMEType("multipart/x-mixed-replace");
646 MockWebURLLoaderClient client;
647 MultipartResponseDelegate delegate(&client, NULL, response, "bound");
649 string data(
650 "--bound\n"
651 "Content-type: text/plain\n\n"
652 "response data\n"
653 "--bound\n");
654 delegate.OnReceivedData(data.c_str(),
655 static_cast<int>(data.length()),
656 static_cast<int>(data.length()));
657 EXPECT_EQ(1, client.received_response_);
658 EXPECT_EQ(string("response data"), client.data_);
659 EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
660 EXPECT_FALSE(client.response_.isMultipartPayload());
662 string data2(
663 "Content-type: text/plain\n\n"
664 "response data2\n"
665 "--bound\n");
666 delegate.OnReceivedData(data2.c_str(),
667 static_cast<int>(data2.length()),
668 static_cast<int>(data2.length()));
669 EXPECT_EQ(2, client.received_response_);
670 EXPECT_EQ(string("response data2"), client.data_);
671 EXPECT_EQ(static_cast<int>(data.length()) + static_cast<int>(data2.length()),
672 client.total_encoded_data_length_);
673 EXPECT_TRUE(client.response_.isMultipartPayload());
676 } // namespace