1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderClient.h"
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/multipart_response_delegate.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing std::string;
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebString;
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURL;
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLError;
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLLoader;
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLLoaderClient;
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLRequest;
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLResponse;
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::MultipartResponseDelegate;
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::MultipartResponseDelegateTester;
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace webkit_glue {
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MultipartResponseDelegateTester {
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MultipartResponseDelegateTester(MultipartResponseDelegate* delegate)
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : delegate_(delegate) {
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int PushOverLine(const std::string& data, size_t pos) {
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return delegate_->PushOverLine(data, pos);
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ParseHeaders() { return delegate_->ParseHeaders(); }
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t FindBoundary() { return delegate_->FindBoundary(); }
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string& boundary() { return delegate_->boundary_; }
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string& data() { return delegate_->data_; }
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MultipartResponseDelegate* delegate_;
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace webkit_glue
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MultipartResponseTest : public testing::Test {
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockWebURLLoaderClient : public WebURLLoaderClient {
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockWebURLLoaderClient() { Reset(); }
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void willSendRequest(
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WebURLLoader*, WebURLRequest&, const WebURLResponse&) {}
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void didSendData(
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WebURLLoader*, unsigned long long, unsigned long long) {}
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void didReceiveResponse(WebURLLoader* loader,
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  const WebURLResponse& response) {
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ++received_response_;
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response_ = response;
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data_.clear();
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void didReceiveData(
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      WebKit::WebURLLoader* loader,
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const char* data,
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      int data_length,
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      int encoded_data_length) {
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ++received_data_;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data_.append(data, data_length);
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    total_encoded_data_length_ += encoded_data_length;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void didFinishLoading(WebURLLoader*, double finishTime) {}
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void didFail(WebURLLoader*, const WebURLError&) {}
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Reset() {
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    received_response_ = received_data_ = total_encoded_data_length_ = 0;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data_.clear();
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response_.reset();
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string GetResponseHeader(const char* name) const {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return string(response_.httpHeaderField(WebString::fromUTF8(name)).utf8());
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int received_response_, received_data_, total_encoded_data_length_;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string data_;
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response_;
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// We can't put this in an anonymous function because it's a friend class for
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// access to private members.
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(MultipartResponseTest, Functions) {
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // PushOverLine tests
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response.initialize();
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setMIMEType("multipart/x-mixed-replace");
1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setHTTPHeaderField("Foo", "Bar");
1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setHTTPHeaderField("Content-type", "text/plain");
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockWebURLLoaderClient client;
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MultipartResponseDelegateTester delegate_tester(&delegate);
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct {
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const char* input;
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const int position;
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const int expected;
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } line_tests[] = {
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Line", 0, 0 },
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Line", 2, 0 },
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Line", 10, 0 },
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "\r\nLine", 0, 2 },
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "\nLine", 0, 1 },
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "\n\nLine", 0, 2 },
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "\rLine", 0, 1 },
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Line\r\nLine", 4, 2 },
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Line\nLine", 4, 1 },
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Line\n\nLine", 4, 2 },
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Line\rLine", 4, 1 },
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Line\r\rLine", 4, 1 },
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(line_tests); ++i) {
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(line_tests[i].expected,
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              delegate_tester.PushOverLine(line_tests[i].input,
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           line_tests[i].position));
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ParseHeaders tests
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct {
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const char* data;
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const bool rv;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const int received_response_calls;
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const char* newdata;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } header_tests[] = {
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "This is junk", false, 0, "This is junk" },
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Foo: bar\nBaz:\n\nAfter:\n", true, 1, "After:\n" },
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Foo: bar\nBaz:\n", false, 0, "Foo: bar\nBaz:\n" },
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Foo: bar\r\nBaz:\r\n\r\nAfter:\r\n", true, 1, "After:\r\n" },
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Foo: bar\r\nBaz:\r\n", false, 0, "Foo: bar\r\nBaz:\r\n" },
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Foo: bar\nBaz:\r\n\r\nAfter:\n\n", true, 1, "After:\n\n" },
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "Foo: bar\r\nBaz:\n", false, 0, "Foo: bar\r\nBaz:\n" },
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "\r\n", true, 1, "" },
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(header_tests); ++i) {
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    client.Reset();
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate_tester.data().assign(header_tests[i].data);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(header_tests[i].rv,
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              delegate_tester.ParseHeaders());
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(header_tests[i].received_response_calls,
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              client.received_response_);
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(string(header_tests[i].newdata),
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              delegate_tester.data());
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test that the resource response is filled in correctly when parsing
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // headers.
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  client.Reset();
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string test_header("content-type: image/png\ncontent-length: 10\n\n");
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate_tester.data().assign(test_header);
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate_tester.ParseHeaders());
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate_tester.data().length() == 0);
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(string("image/png"), client.GetResponseHeader("Content-Type"));
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(string("10"), client.GetResponseHeader("content-length"));
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This header is passed from the original request.
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(string("Bar"), client.GetResponseHeader("foo"));
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure we parse the right mime-type if a charset is provided.
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  client.Reset();
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string test_header2("content-type: text/html; charset=utf-8\n\n");
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate_tester.data().assign(test_header2);
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate_tester.ParseHeaders());
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate_tester.data().length() == 0);
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(string("text/html; charset=utf-8"),
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            client.GetResponseHeader("Content-Type"));
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(string("utf-8"),
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            string(client.response_.textEncodingName().utf8()));
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // FindBoundary tests
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct {
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const char* boundary;
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const char* data;
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const size_t position;
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } boundary_tests[] = {
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "bound", "bound", 0 },
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "bound", "--bound", 0 },
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "bound", "junkbound", 4 },
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "bound", "junk--bound", 4 },
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "foo", "bound", string::npos },
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { "bound", "--boundbound", 0 },
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(boundary_tests); ++i) {
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate_tester.boundary().assign(boundary_tests[i].boundary);
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate_tester.data().assign(boundary_tests[i].data);
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(boundary_tests[i].position,
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              delegate_tester.FindBoundary());
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(MultipartResponseTest, MissingBoundaries) {
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response;
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response.initialize();
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setMIMEType("multipart/x-mixed-replace");
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setHTTPHeaderField("Foo", "Bar");
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setHTTPHeaderField("Content-type", "text/plain");
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockWebURLLoaderClient client;
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // No start boundary
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string no_start_boundary(
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "Content-type: text/plain\n\n"
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "This is a sample response\n"
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "--bound--"
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "ignore junk after end token --bound\n\nTest2\n");
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate.OnReceivedData(no_start_boundary.c_str(),
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          static_cast<int>(no_start_boundary.length()),
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          static_cast<int>(no_start_boundary.length()));
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_response_);
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_data_);
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(string("This is a sample response"), client.data_);
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(static_cast<int>(no_start_boundary.length()),
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            client.total_encoded_data_length_);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate.OnCompletedRequest();
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_response_);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_data_);
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // No end boundary
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  client.Reset();
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MultipartResponseDelegate delegate2(&client, NULL, response, "bound");
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string no_end_boundary(
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "bound\nContent-type: text/plain\n\n"
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "This is a sample response\n");
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate2.OnReceivedData(no_end_boundary.c_str(),
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          static_cast<int>(no_end_boundary.length()),
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          static_cast<int>(no_end_boundary.length()));
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_response_);
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_data_);
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("This is a sample response\n", client.data_);
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(static_cast<int>(no_end_boundary.length()),
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            client.total_encoded_data_length_);
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate2.OnCompletedRequest();
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_response_);
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_data_);
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(string("This is a sample response\n"), client.data_);
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(static_cast<int>(no_end_boundary.length()),
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            client.total_encoded_data_length_);
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Neither boundary
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  client.Reset();
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MultipartResponseDelegate delegate3(&client, NULL, response, "bound");
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string no_boundaries(
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "Content-type: text/plain\n\n"
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "This is a sample response\n");
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate3.OnReceivedData(no_boundaries.c_str(),
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           static_cast<int>(no_boundaries.length()),
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           static_cast<int>(no_boundaries.length()));
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_response_);
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_data_);
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("This is a sample response\n", client.data_);
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(static_cast<int>(no_boundaries.length()),
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            client.total_encoded_data_length_);
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate3.OnCompletedRequest();
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_response_);
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_data_);
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(string("This is a sample response\n"), client.data_);
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(static_cast<int>(no_boundaries.length()),
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            client.total_encoded_data_length_);
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(MultipartResponseTest, MalformedBoundary) {
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Some servers send a boundary that is prefixed by "--".  See bug 5786.
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response;
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response.initialize();
2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setMIMEType("multipart/x-mixed-replace");
2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setHTTPHeaderField("Foo", "Bar");
2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setHTTPHeaderField("Content-type", "text/plain");
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockWebURLLoaderClient client;
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MultipartResponseDelegate delegate(&client, NULL, response, "--bound");
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string data(
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "--bound\n"
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "Content-type: text/plain\n\n"
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "This is a sample response\n"
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "--bound--"
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "ignore junk after end token --bound\n\nTest2\n");
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delegate.OnReceivedData(data.c_str(),
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          static_cast<int>(data.length()),
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          static_cast<int>(data.length()));
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_response_);
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_data_);
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(string("This is a sample response"), client.data_);
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate.OnCompletedRequest();
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_response_);
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, client.received_data_);
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Used in for tests that break the data in various places.
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct TestChunk {
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int start_pos;  // offset in data
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int end_pos;    // end offset in data
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int expected_responses;
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int expected_received_data;
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* expected_data;
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const int expected_encoded_data_length;
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid VariousChunkSizesTest(const TestChunk chunks[], int chunks_size,
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           int responses, int received_data,
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           const char* completed_data,
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           int completed_encoded_data_length) {
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const string data(
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "--bound\n"                    // 0-7
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "Content-type: image/png\n\n"  // 8-32
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "datadatadatadatadata"         // 33-52
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "--bound\n"                    // 53-60
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "Content-type: image/jpg\n\n"  // 61-85
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "foofoofoofoofoo"              // 86-100
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "--bound--");                  // 101-109
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response;
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response.initialize();
3333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setMIMEType("multipart/x-mixed-replace");
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockWebURLLoaderClient client;
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < chunks_size; ++i) {
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(chunks[i].start_pos < chunks[i].end_pos);
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    string chunk = data.substr(chunks[i].start_pos,
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               chunks[i].end_pos - chunks[i].start_pos);
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delegate.OnReceivedData(
342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        chunk.c_str(),
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        static_cast<int>(chunk.length()),
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        static_cast<int>(chunk.length()));
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(chunks[i].expected_responses, client.received_response_);
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(chunks[i].expected_received_data, client.received_data_);
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(string(chunks[i].expected_data), client.data_);
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(chunks[i].expected_encoded_data_length,
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              client.total_encoded_data_length_);
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check final state
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate.OnCompletedRequest();
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(responses, client.received_response_);
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(received_data, client.received_data_);
355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  string completed_data_string(completed_data);
356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(completed_data_string, client.data_);
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(completed_encoded_data_length, client.total_encoded_data_length_);
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(MultipartResponseTest, BreakInBoundary) {
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Break in the first boundary
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const TestChunk bound1[] = {
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 0, 4, 0, 0, "", 0 },
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 4, 110, 2, 2, "foofoofoofoofoo", 110 },
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VariousChunkSizesTest(bound1, arraysize(bound1),
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        2, 2, "foofoofoofoofoo", 110);
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Break in first and second
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const TestChunk bound2[] = {
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 0, 4, 0, 0, "", 0 },
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 4, 55, 1, 1, "datadatadatadat", 55 },
373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 55, 65, 1, 2, "datadatadatadatadata", 65 },
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 65, 110, 2, 3, "foofoofoofoofoo", 110 },
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VariousChunkSizesTest(bound2, arraysize(bound2),
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        2, 3, "foofoofoofoofoo", 110);
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Break in second only
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const TestChunk bound3[] = {
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 0, 55, 1, 1, "datadatadatadat", 55 },
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 55, 110, 2, 3, "foofoofoofoofoo", 110 },
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VariousChunkSizesTest(bound3, arraysize(bound3),
385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        2, 3, "foofoofoofoofoo", 110);
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(MultipartResponseTest, BreakInHeaders) {
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Break in first header
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const TestChunk header1[] = {
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 0, 10, 0, 0, "", 0 },
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 10, 35, 1, 0, "", 0 },
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 35, 110, 2, 2, "foofoofoofoofoo", 110 },
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VariousChunkSizesTest(header1, arraysize(header1),
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        2, 2, "foofoofoofoofoo", 110);
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Break in both headers
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const TestChunk header2[] = {
400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 0, 10, 0, 0, "", 0 },
401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 10, 65, 1, 1, "datadatadatadatadata", 65 },
402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VariousChunkSizesTest(header2, arraysize(header2),
405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        2, 2, "foofoofoofoofoo", 110);
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Break at end of a header
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const TestChunk header3[] = {
409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 0, 33, 1, 0, "", 0 },
410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 33, 65, 1, 1, "datadatadatadatadata", 65 },
411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VariousChunkSizesTest(header3, arraysize(header3),
414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        2, 2, "foofoofoofoofoo", 110);
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(MultipartResponseTest, BreakInData) {
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // All data as one chunk
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const TestChunk data1[] = {
420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 0, 110, 2, 2, "foofoofoofoofoo", 110 },
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VariousChunkSizesTest(data1, arraysize(data1),
423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        2, 2, "foofoofoofoofoo", 110);
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // breaks in data segment
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const TestChunk data2[] = {
427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 0, 35, 1, 0, "", 0 },
428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 35, 65, 1, 1, "datadatadatadatadata", 65 },
429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 65, 90, 2, 1, "", 65 },
430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 90, 110, 2, 2, "foofoofoofoofoo", 110 },
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VariousChunkSizesTest(data2, arraysize(data2),
433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        2, 2, "foofoofoofoofoo", 110);
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Incomplete send
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const TestChunk data3[] = {
437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 0, 35, 1, 0, "", 0 },
438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 35, 90, 2, 1, "", 90 },
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VariousChunkSizesTest(data3, arraysize(data3),
441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        2, 2, "foof", 90);
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4443345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST(MultipartResponseTest, SmallChunk) {
4453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  WebURLResponse response;
4463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.initialize();
4473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setMIMEType("multipart/x-mixed-replace");
4483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setHTTPHeaderField("Content-type", "text/plain");
4493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockWebURLLoaderClient client;
4503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
4513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Test chunks of size 1, 2, and 0.
4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  string data(
4543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    "--boundContent-type: text/plain\n\n"
4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    "\n--boundContent-type: text/plain\n\n"
4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    "\n\n--boundContent-type: text/plain\n\n"
4573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    "--boundContent-type: text/plain\n\n"
4583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    "end--bound--");
4593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  delegate.OnReceivedData(data.c_str(),
460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          static_cast<int>(data.length()),
4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                          static_cast<int>(data.length()));
4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(4, client.received_response_);
4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(2, client.received_data_);
4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(string("end"), client.data_);
465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  delegate.OnCompletedRequest();
4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(4, client.received_response_);
4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(2, client.received_data_);
4703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(MultipartResponseTest, MultipleBoundaries) {
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test multiple boundaries back to back
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response;
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response.initialize();
4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setMIMEType("multipart/x-mixed-replace");
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockWebURLLoaderClient client;
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string data("--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--");
481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delegate.OnReceivedData(data.c_str(),
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          static_cast<int>(data.length()),
483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          static_cast<int>(data.length()));
484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, client.received_response_);
485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, client.received_data_);
486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(string("foofoo"), client.data_);
487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(MultipartResponseTest, MultipartByteRangeParsingTest) {
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test multipart/byteranges based boundary parsing.
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response1;
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response1.initialize();
4943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response1.setMIMEType("multipart/x-mixed-replace");
4953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response1.setHTTPHeaderField("Content-Length", "200");
4963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response1.setHTTPHeaderField("Content-type",
4973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               "multipart/byteranges; boundary=--bound--");
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string multipart_boundary;
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool result = MultipartResponseDelegate::ReadMultipartBoundary(
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      response1, &multipart_boundary);
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(result, true);
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(string("--bound--"),
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            multipart_boundary);
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response2;
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response2.initialize();
5083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response2.setMIMEType("image/png");
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response2.setHTTPHeaderField("Content-Length", "300");
5113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response2.setHTTPHeaderField("Last-Modified",
5123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               "Mon, 04 Apr 2005 20:36:01 GMT");
5133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response2.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  multipart_boundary.clear();
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = MultipartResponseDelegate::ReadMultipartBoundary(
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      response2, &multipart_boundary);
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(result, false);
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response3;
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response3.initialize();
5223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response3.setMIMEType("multipart/byteranges");
5233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response3.setHTTPHeaderField("Content-Length", "300");
5253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response3.setHTTPHeaderField("Last-Modified",
5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               "Mon, 04 Apr 2005 20:36:01 GMT");
5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response3.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT");
5283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response3.setHTTPHeaderField("Content-type", "multipart/byteranges");
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  multipart_boundary.clear();
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = MultipartResponseDelegate::ReadMultipartBoundary(
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      response3, &multipart_boundary);
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(result, false);
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(multipart_boundary.length(), 0U);
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response4;
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response4.initialize();
5383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response4.setMIMEType("multipart/byteranges");
5393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response4.setHTTPHeaderField("Content-Length", "200");
5403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response4.setHTTPHeaderField("Content-type",
5413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "multipart/byteranges; boundary=--bound--; charSet=utf8");
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  multipart_boundary.clear();
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = MultipartResponseDelegate::ReadMultipartBoundary(
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      response4, &multipart_boundary);
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(result, true);
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(string("--bound--"), multipart_boundary);
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response5;
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response5.initialize();
5523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response5.setMIMEType("multipart/byteranges");
5533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response5.setHTTPHeaderField("Content-Length", "200");
5543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response5.setHTTPHeaderField("Content-type",
5553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8");
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  multipart_boundary.clear();
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = MultipartResponseDelegate::ReadMultipartBoundary(
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      response5, &multipart_boundary);
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(result, true);
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(string("--bound--"), multipart_boundary);
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(MultipartResponseTest, MultipartContentRangesTest) {
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response1;
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response1.initialize();
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response1.setMIMEType("application/pdf");
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response1.setHTTPHeaderField("Content-Length", "200");
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response1.setHTTPHeaderField("Content-Range", "bytes 1000-1050/5000");
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int content_range_lower_bound = 0;
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int content_range_upper_bound = 0;
57421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  int content_range_instance_size = 0;
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool result = MultipartResponseDelegate::ReadContentRanges(
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      response1, &content_range_lower_bound,
57821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      &content_range_upper_bound,
57921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      &content_range_instance_size);
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(result, true);
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(content_range_lower_bound, 1000);
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(content_range_upper_bound, 1050);
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response2;
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response2.initialize();
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response2.setMIMEType("application/pdf");
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response2.setHTTPHeaderField("Content-Length", "200");
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response2.setHTTPHeaderField("Content-Range", "bytes 1000/1050");
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  content_range_lower_bound = 0;
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  content_range_upper_bound = 0;
59321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  content_range_instance_size = 0;
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = MultipartResponseDelegate::ReadContentRanges(
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      response2, &content_range_lower_bound,
59721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      &content_range_upper_bound,
59821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      &content_range_instance_size);
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(result, false);
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response3;
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response3.initialize();
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response3.setMIMEType("application/pdf");
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response3.setHTTPHeaderField("Content-Length", "200");
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response3.setHTTPHeaderField("Range", "bytes 1000-1050/5000");
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  content_range_lower_bound = 0;
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  content_range_upper_bound = 0;
61021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  content_range_instance_size = 0;
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = MultipartResponseDelegate::ReadContentRanges(
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      response3, &content_range_lower_bound,
61421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      &content_range_upper_bound,
61521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      &content_range_instance_size);
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(result, true);
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(content_range_lower_bound, 1000);
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(content_range_upper_bound, 1050);
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response4;
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response4.initialize();
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response4.setMIMEType("application/pdf");
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response4.setHTTPHeaderField("Content-Length", "200");
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  content_range_lower_bound = 0;
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  content_range_upper_bound = 0;
62821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  content_range_instance_size = 0;
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = MultipartResponseDelegate::ReadContentRanges(
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      response4, &content_range_lower_bound,
63221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      &content_range_upper_bound,
63321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      &content_range_instance_size);
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(result, false);
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(MultipartResponseTest, MultipartPayloadSet) {
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response;
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  response.initialize();
6413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  response.setMIMEType("multipart/x-mixed-replace");
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockWebURLLoaderClient client;
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string data(
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "--bound\n"
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Content-type: text/plain\n\n"
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "response data\n"
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "--bound\n");
650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delegate.OnReceivedData(data.c_str(),
651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          static_cast<int>(data.length()),
652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          static_cast<int>(data.length()));
653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, client.received_response_);
654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(string("response data"), client.data_);
655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
656731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(client.response_.isMultipartPayload());
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string data2(
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "Content-type: text/plain\n\n"
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "response data2\n"
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "--bound\n");
662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delegate.OnReceivedData(data2.c_str(),
663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          static_cast<int>(data2.length()),
664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          static_cast<int>(data2.length()));
665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, client.received_response_);
666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(string("response data2"), client.data_);
667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(static_cast<int>(data.length()) + static_cast<int>(data2.length()),
668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            client.total_encoded_data_length_);
669731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(client.response_.isMultipartPayload());
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
673