1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/child/multipart_response_delegate.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "testing/gtest/include/gtest/gtest.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebString;
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURL;
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLError;
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLLoader;
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLLoaderClient;
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLRequest;
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLResponse;
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing std::string;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace content {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MultipartResponseDelegateTester {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegateTester(MultipartResponseDelegate* delegate)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : delegate_(delegate) {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int PushOverLine(const std::string& data, size_t pos) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return delegate_->PushOverLine(data, pos);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ParseHeaders() { return delegate_->ParseHeaders(); }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t FindBoundary() { return delegate_->FindBoundary(); }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string& boundary() { return delegate_->boundary_; }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string& data() { return delegate_->data_; }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegate* delegate_;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MultipartResponseTest : public testing::Test {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockWebURLLoaderClient : public WebURLLoaderClient {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWebURLLoaderClient() { Reset(); }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void willSendRequest(
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebURLLoader*, WebURLRequest&, const WebURLResponse&) {}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void didSendData(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebURLLoader*, unsigned long long, unsigned long long) {}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void didReceiveResponse(WebURLLoader* loader,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const WebURLResponse& response) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++received_response_;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_ = response;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_.clear();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void didReceiveData(
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebURLLoader* loader,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const char* data,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int data_length,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int encoded_data_length) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++received_data_;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_.append(data, data_length);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    total_encoded_data_length_ += encoded_data_length;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void didFinishLoading(
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      WebURLLoader*, double finishTime, int64_t total_encoded_data_length) {}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void didFail(WebURLLoader*, const WebURLError&) {}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset() {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    received_response_ = received_data_ = total_encoded_data_length_ = 0;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_.clear();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_.reset();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string GetResponseHeader(const char* name) const {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return string(response_.httpHeaderField(WebString::fromUTF8(name)).utf8());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int received_response_, received_data_, total_encoded_data_length_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data_;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response_;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We can't put this in an anonymous function because it's a friend class for
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// access to private members.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MultipartResponseTest, Functions) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PushOverLine tests
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.initialize();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setMIMEType("multipart/x-mixed-replace");
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setHTTPHeaderField("Foo", "Bar");
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setHTTPHeaderField("Content-type", "text/plain");
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWebURLLoaderClient client;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegateTester delegate_tester(&delegate);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* input;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int position;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int expected;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } line_tests[] = {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Line", 0, 0 },
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Line", 2, 0 },
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Line", 10, 0 },
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "\r\nLine", 0, 2 },
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "\nLine", 0, 1 },
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "\n\nLine", 0, 2 },
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "\rLine", 0, 1 },
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Line\r\nLine", 4, 2 },
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Line\nLine", 4, 1 },
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Line\n\nLine", 4, 2 },
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Line\rLine", 4, 1 },
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Line\r\rLine", 4, 1 },
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(line_tests); ++i) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(line_tests[i].expected,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              delegate_tester.PushOverLine(line_tests[i].input,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           line_tests[i].position));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ParseHeaders tests
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* data;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const bool rv;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int received_response_calls;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* newdata;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } header_tests[] = {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "This is junk", false, 0, "This is junk" },
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Foo: bar\nBaz:\n\nAfter:\n", true, 1, "After:\n" },
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Foo: bar\nBaz:\n", false, 0, "Foo: bar\nBaz:\n" },
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Foo: bar\r\nBaz:\r\n\r\nAfter:\r\n", true, 1, "After:\r\n" },
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Foo: bar\r\nBaz:\r\n", false, 0, "Foo: bar\r\nBaz:\r\n" },
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Foo: bar\nBaz:\r\n\r\nAfter:\n\n", true, 1, "After:\n\n" },
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "Foo: bar\r\nBaz:\n", false, 0, "Foo: bar\r\nBaz:\n" },
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "\r\n", true, 1, "" },
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(header_tests); ++i) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client.Reset();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_tester.data().assign(header_tests[i].data);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(header_tests[i].rv,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              delegate_tester.ParseHeaders());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(header_tests[i].received_response_calls,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              client.received_response_);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(string(header_tests[i].newdata),
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              delegate_tester.data());
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that the resource response is filled in correctly when parsing
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // headers.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client.Reset();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string test_header("content-type: image/png\ncontent-length: 10\n\n");
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_tester.data().assign(test_header);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(delegate_tester.ParseHeaders());
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(delegate_tester.data().length() == 0);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("image/png"), client.GetResponseHeader("Content-Type"));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("10"), client.GetResponseHeader("content-length"));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This header is passed from the original request.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("Bar"), client.GetResponseHeader("foo"));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we parse the right mime-type if a charset is provided.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client.Reset();
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string test_header2("content-type: text/html; charset=utf-8\n\n");
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_tester.data().assign(test_header2);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(delegate_tester.ParseHeaders());
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(delegate_tester.data().length() == 0);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("text/html; charset=utf-8"),
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            client.GetResponseHeader("Content-Type"));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("utf-8"),
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            string(client.response_.textEncodingName().utf8()));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FindBoundary tests
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* boundary;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* data;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const size_t position;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } boundary_tests[] = {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "bound", "bound", 0 },
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "bound", "--bound", 0 },
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "bound", "junkbound", 4 },
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "bound", "junk--bound", 4 },
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "foo", "bound", string::npos },
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "bound", "--boundbound", 0 },
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(boundary_tests); ++i) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_tester.boundary().assign(boundary_tests[i].boundary);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_tester.data().assign(boundary_tests[i].data);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(boundary_tests[i].position,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              delegate_tester.FindBoundary());
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MultipartResponseTest, MissingBoundaries) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.initialize();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setMIMEType("multipart/x-mixed-replace");
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setHTTPHeaderField("Foo", "Bar");
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setHTTPHeaderField("Content-type", "text/plain");
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWebURLLoaderClient client;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No start boundary
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string no_start_boundary(
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-type: text/plain\n\n"
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "This is a sample response\n"
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "--bound--"
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "ignore junk after end token --bound\n\nTest2\n");
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.OnReceivedData(no_start_boundary.c_str(),
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(no_start_boundary.length()),
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(no_start_boundary.length()));
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_response_);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_data_);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("This is a sample response"), client.data_);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(no_start_boundary.length()),
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            client.total_encoded_data_length_);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.OnCompletedRequest();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_response_);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_data_);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No end boundary
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client.Reset();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegate delegate2(&client, NULL, response, "bound");
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string no_end_boundary(
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "bound\nContent-type: text/plain\n\n"
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "This is a sample response\n");
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate2.OnReceivedData(no_end_boundary.c_str(),
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(no_end_boundary.length()),
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(no_end_boundary.length()));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_response_);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_data_);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("This is a sample response\n", client.data_);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(no_end_boundary.length()),
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            client.total_encoded_data_length_);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate2.OnCompletedRequest();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_response_);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_data_);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("This is a sample response\n"), client.data_);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(no_end_boundary.length()),
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            client.total_encoded_data_length_);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Neither boundary
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client.Reset();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegate delegate3(&client, NULL, response, "bound");
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string no_boundaries(
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-type: text/plain\n\n"
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "This is a sample response\n");
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate3.OnReceivedData(no_boundaries.c_str(),
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           static_cast<int>(no_boundaries.length()),
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           static_cast<int>(no_boundaries.length()));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_response_);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_data_);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("This is a sample response\n", client.data_);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(no_boundaries.length()),
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            client.total_encoded_data_length_);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate3.OnCompletedRequest();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_response_);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_data_);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("This is a sample response\n"), client.data_);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(no_boundaries.length()),
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            client.total_encoded_data_length_);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MultipartResponseTest, MalformedBoundary) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Some servers send a boundary that is prefixed by "--".  See bug 5786.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.initialize();
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setMIMEType("multipart/x-mixed-replace");
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setHTTPHeaderField("Foo", "Bar");
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setHTTPHeaderField("Content-type", "text/plain");
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWebURLLoaderClient client;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegate delegate(&client, NULL, response, "--bound");
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data(
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "--bound\n"
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-type: text/plain\n\n"
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "This is a sample response\n"
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "--bound--"
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "ignore junk after end token --bound\n\nTest2\n");
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.OnReceivedData(data.c_str(),
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(data.length()),
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(data.length()));
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_response_);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_data_);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("This is a sample response"), client.data_);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.OnCompletedRequest();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_response_);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_data_);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used in for tests that break the data in various places.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TestChunk {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int start_pos;  // offset in data
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int end_pos;    // end offset in data
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int expected_responses;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int expected_received_data;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* expected_data;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int expected_encoded_data_length;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VariousChunkSizesTest(const TestChunk chunks[], int chunks_size,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int responses, int received_data,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const char* completed_data,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int completed_encoded_data_length) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const string data(
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "--bound\n"                    // 0-7
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-type: image/png\n\n"  // 8-32
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "datadatadatadatadata"         // 33-52
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "--bound\n"                    // 53-60
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Content-type: image/jpg\n\n"  // 61-85
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foofoofoofoofoo"              // 86-100
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "--bound--");                  // 101-109
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.initialize();
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setMIMEType("multipart/x-mixed-replace");
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWebURLLoaderClient client;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < chunks_size; ++i) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(chunks[i].start_pos < chunks[i].end_pos);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string chunk = data.substr(chunks[i].start_pos,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               chunks[i].end_pos - chunks[i].start_pos);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate.OnReceivedData(
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chunk.c_str(),
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<int>(chunk.length()),
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<int>(chunk.length()));
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(chunks[i].expected_responses, client.received_response_);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(chunks[i].expected_received_data, client.received_data_);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(string(chunks[i].expected_data), client.data_);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(chunks[i].expected_encoded_data_length,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              client.total_encoded_data_length_);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check final state
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.OnCompletedRequest();
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(responses, client.received_response_);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(received_data, client.received_data_);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string completed_data_string(completed_data);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(completed_data_string, client.data_);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(completed_encoded_data_length, client.total_encoded_data_length_);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MultipartResponseTest, BreakInBoundary) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Break in the first boundary
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TestChunk bound1[] = {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0, 4, 0, 0, "", 0 },
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 4, 110, 2, 2, "foofoofoofoofoo", 110 },
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariousChunkSizesTest(bound1, arraysize(bound1),
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        2, 2, "foofoofoofoofoo", 110);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Break in first and second
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TestChunk bound2[] = {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0, 4, 0, 0, "", 0 },
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 4, 55, 1, 1, "datadatadatadat", 55 },
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 55, 65, 1, 2, "datadatadatadatadata", 65 },
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 65, 110, 2, 3, "foofoofoofoofoo", 110 },
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariousChunkSizesTest(bound2, arraysize(bound2),
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        2, 3, "foofoofoofoofoo", 110);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Break in second only
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TestChunk bound3[] = {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0, 55, 1, 1, "datadatadatadat", 55 },
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 55, 110, 2, 3, "foofoofoofoofoo", 110 },
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariousChunkSizesTest(bound3, arraysize(bound3),
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        2, 3, "foofoofoofoofoo", 110);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MultipartResponseTest, BreakInHeaders) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Break in first header
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TestChunk header1[] = {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0, 10, 0, 0, "", 0 },
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 10, 35, 1, 0, "", 0 },
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 35, 110, 2, 2, "foofoofoofoofoo", 110 },
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariousChunkSizesTest(header1, arraysize(header1),
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        2, 2, "foofoofoofoofoo", 110);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Break in both headers
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TestChunk header2[] = {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0, 10, 0, 0, "", 0 },
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 10, 65, 1, 1, "datadatadatadatadata", 65 },
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariousChunkSizesTest(header2, arraysize(header2),
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        2, 2, "foofoofoofoofoo", 110);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Break at end of a header
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TestChunk header3[] = {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0, 33, 1, 0, "", 0 },
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 33, 65, 1, 1, "datadatadatadatadata", 65 },
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariousChunkSizesTest(header3, arraysize(header3),
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        2, 2, "foofoofoofoofoo", 110);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MultipartResponseTest, BreakInData) {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All data as one chunk
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TestChunk data1[] = {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0, 110, 2, 2, "foofoofoofoofoo", 110 },
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariousChunkSizesTest(data1, arraysize(data1),
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        2, 2, "foofoofoofoofoo", 110);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // breaks in data segment
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TestChunk data2[] = {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0, 35, 1, 0, "", 0 },
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 35, 65, 1, 1, "datadatadatadatadata", 65 },
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 65, 90, 2, 1, "", 65 },
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 90, 110, 2, 2, "foofoofoofoofoo", 110 },
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariousChunkSizesTest(data2, arraysize(data2),
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        2, 2, "foofoofoofoofoo", 110);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Incomplete send
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TestChunk data3[] = {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 0, 35, 1, 0, "", 0 },
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { 35, 90, 2, 1, "", 90 },
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VariousChunkSizesTest(data3, arraysize(data3),
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        2, 2, "foof", 90);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MultipartResponseTest, SmallChunk) {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.initialize();
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setMIMEType("multipart/x-mixed-replace");
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setHTTPHeaderField("Content-type", "text/plain");
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWebURLLoaderClient client;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test chunks of size 1, 2, and 0.
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data(
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "--boundContent-type: text/plain\n\n"
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n--boundContent-type: text/plain\n\n"
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n\n--boundContent-type: text/plain\n\n"
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "--boundContent-type: text/plain\n\n"
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "end--bound--");
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.OnReceivedData(data.c_str(),
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(data.length()),
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(data.length()));
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, client.received_response_);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, client.received_data_);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("end"), client.data_);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.OnCompletedRequest();
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, client.received_response_);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, client.received_data_);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MultipartResponseTest, MultipleBoundaries) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test multiple boundaries back to back
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.initialize();
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setMIMEType("multipart/x-mixed-replace");
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWebURLLoaderClient client;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data("--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--");
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.OnReceivedData(data.c_str(),
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(data.length()),
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(data.length()));
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, client.received_response_);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_data_);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("foofoo"), client.data_);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MultipartResponseTest, MultipartByteRangeParsingTest) {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test multipart/byteranges based boundary parsing.
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response1;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response1.initialize();
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response1.setMIMEType("multipart/x-mixed-replace");
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response1.setHTTPHeaderField("Content-Length", "200");
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response1.setHTTPHeaderField("Content-type",
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               "multipart/byteranges; boundary=--bound--");
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string multipart_boundary;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = MultipartResponseDelegate::ReadMultipartBoundary(
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response1, &multipart_boundary);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(result, true);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("--bound--"),
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            multipart_boundary);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response2;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response2.initialize();
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response2.setMIMEType("image/png");
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response2.setHTTPHeaderField("Content-Length", "300");
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response2.setHTTPHeaderField("Last-Modified",
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               "Mon, 04 Apr 2005 20:36:01 GMT");
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response2.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  multipart_boundary.clear();
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = MultipartResponseDelegate::ReadMultipartBoundary(
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response2, &multipart_boundary);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(result, false);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response3;
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response3.initialize();
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response3.setMIMEType("multipart/byteranges");
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response3.setHTTPHeaderField("Content-Length", "300");
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response3.setHTTPHeaderField("Last-Modified",
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               "Mon, 04 Apr 2005 20:36:01 GMT");
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response3.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response3.setHTTPHeaderField("Content-type", "multipart/byteranges");
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  multipart_boundary.clear();
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = MultipartResponseDelegate::ReadMultipartBoundary(
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response3, &multipart_boundary);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(result, false);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(multipart_boundary.length(), 0U);
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response4;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response4.initialize();
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response4.setMIMEType("multipart/byteranges");
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response4.setHTTPHeaderField("Content-Length", "200");
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response4.setHTTPHeaderField("Content-type",
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "multipart/byteranges; boundary=--bound--; charSet=utf8");
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  multipart_boundary.clear();
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = MultipartResponseDelegate::ReadMultipartBoundary(
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response4, &multipart_boundary);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(result, true);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("--bound--"), multipart_boundary);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response5;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response5.initialize();
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response5.setMIMEType("multipart/byteranges");
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response5.setHTTPHeaderField("Content-Length", "200");
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response5.setHTTPHeaderField("Content-type",
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8");
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  multipart_boundary.clear();
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = MultipartResponseDelegate::ReadMultipartBoundary(
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response5, &multipart_boundary);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(result, true);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("--bound--"), multipart_boundary);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MultipartResponseTest, MultipartContentRangesTest) {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response1;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response1.initialize();
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response1.setMIMEType("application/pdf");
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response1.setHTTPHeaderField("Content-Length", "200");  // Ignored!
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use intentionally >32bit values to check they are handled correctly.
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response1.setHTTPHeaderField("Content-Range",
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               "bytes 5000000000-5000000050/6000000000");
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 content_range_lower_bound = 0;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 content_range_upper_bound = 0;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 content_range_instance_size = 0;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = MultipartResponseDelegate::ReadContentRanges(
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response1, &content_range_lower_bound,
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &content_range_upper_bound,
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &content_range_instance_size);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(result, true);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content_range_lower_bound, 5e9);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content_range_upper_bound, 5e9+50);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content_range_instance_size, 6e9);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response2;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response2.initialize();
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response2.setMIMEType("application/pdf");
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response2.setHTTPHeaderField("Content-Length", "200");
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response2.setHTTPHeaderField("Content-Range", "bytes 1000/1050");
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content_range_lower_bound = 0;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content_range_upper_bound = 0;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content_range_instance_size = 0;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = MultipartResponseDelegate::ReadContentRanges(
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response2, &content_range_lower_bound,
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &content_range_upper_bound,
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &content_range_instance_size);
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(result, false);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response3;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response3.initialize();
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response3.setMIMEType("application/pdf");
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response3.setHTTPHeaderField("Content-Length", "200");
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response3.setHTTPHeaderField("Range", "bytes 1000-1050/5000");
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content_range_lower_bound = 0;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content_range_upper_bound = 0;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content_range_instance_size = 0;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = MultipartResponseDelegate::ReadContentRanges(
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response3, &content_range_lower_bound,
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &content_range_upper_bound,
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &content_range_instance_size);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(result, true);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content_range_lower_bound, 1000);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(content_range_upper_bound, 1050);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response4;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response4.initialize();
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response4.setMIMEType("application/pdf");
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response4.setHTTPHeaderField("Content-Length", "200");
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content_range_lower_bound = 0;
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content_range_upper_bound = 0;
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content_range_instance_size = 0;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = MultipartResponseDelegate::ReadContentRanges(
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response4, &content_range_lower_bound,
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &content_range_upper_bound,
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &content_range_instance_size);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(result, false);
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MultipartResponseTest, MultipartPayloadSet) {
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebURLResponse response;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.initialize();
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.setMIMEType("multipart/x-mixed-replace");
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWebURLLoaderClient client;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data(
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "--bound\n"
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/plain\n\n"
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "response data\n"
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "--bound\n");
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.OnReceivedData(data.c_str(),
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(data.length()),
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(data.length()));
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client.received_response_);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("response data"), client.data_);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(client.response_.isMultipartPayload());
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data2(
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-type: text/plain\n\n"
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "response data2\n"
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "--bound\n");
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.OnReceivedData(data2.c_str(),
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(data2.length()),
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<int>(data2.length()));
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, client.received_response_);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("response data2"), client.data_);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(data.length()) + static_cast<int>(data2.length()),
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            client.total_encoded_data_length_);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(client.response_.isMultipartPayload());
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
674cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace content
675