15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/run_loop.h"
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/stringprintf.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/request_priority.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_job.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_job_factory.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_job_factory_impl.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_simple_job.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_test_util.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net {
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestData[] = "Huge data array";
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kRangeFirstPosition = 5;
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kRangeLastPosition = 8;
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)COMPILE_ASSERT(kRangeFirstPosition > 0 &&
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    kRangeFirstPosition < kRangeLastPosition &&
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    kRangeLastPosition < static_cast<int>(arraysize(kTestData) - 1),
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    invalid_range);
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MockSimpleJob : public URLRequestSimpleJob {
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MockSimpleJob(URLRequest* request, NetworkDelegate* network_delegate)
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : URLRequestSimpleJob(request, network_delegate) {
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetData(std::string* mime_type,
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      std::string* charset,
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      std::string* data,
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      const CompletionCallback& callback) const OVERRIDE {
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    mime_type->assign("text/plain");
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    charset->assign("US-ASCII");
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    data->assign(kTestData);
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return OK;
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~MockSimpleJob() {}
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string data_;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockSimpleJob);
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SimpleJobProtocolHandler :
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    public URLRequestJobFactory::ProtocolHandler {
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual URLRequestJob* MaybeCreateJob(
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      URLRequest* request,
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NetworkDelegate* network_delegate) const OVERRIDE {
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return new MockSimpleJob(request, network_delegate);
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class URLRequestSimpleJobTest : public ::testing::Test {
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  URLRequestSimpleJobTest() : context_(true) {
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    job_factory_.SetProtocolHandler("data", new SimpleJobProtocolHandler());
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    context_.set_job_factory(&job_factory_);
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    context_.Init();
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = context_.CreateRequest(
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("data:test"), DEFAULT_PRIORITY, &delegate_, NULL);
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void StartRequest(const HttpRequestHeaders* headers) {
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (headers)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      request_->SetExtraRequestHeaders(*headers);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    request_->Start();
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(request_->is_pending());
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::RunLoop().Run();
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(request_->is_pending());
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  URLRequestJobFactoryImpl job_factory_;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestURLRequestContext context_;
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestDelegate delegate_;
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<URLRequest> request_;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(URLRequestSimpleJobTest, SimpleRequest) {
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartRequest(NULL);
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(request_->status().is_success());
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kTestData, delegate_.data_received());
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(URLRequestSimpleJobTest, RangeRequest) {
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::string kExpectedBody = std::string(
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kTestData + kRangeFirstPosition, kTestData + kRangeLastPosition + 1);
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HttpRequestHeaders headers;
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  headers.SetHeader(
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HttpRequestHeaders::kRange,
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HttpByteRange::Bounded(kRangeFirstPosition, kRangeLastPosition)
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          .GetHeaderValue());
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartRequest(&headers);
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(request_->status().is_success());
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kExpectedBody, delegate_.data_received());
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(URLRequestSimpleJobTest, MultipleRangeRequest) {
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HttpRequestHeaders headers;
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int middle_pos = (kRangeFirstPosition + kRangeLastPosition)/2;
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string range = base::StringPrintf("bytes=%d-%d,%d-%d",
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                         kRangeFirstPosition,
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                         middle_pos,
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                         middle_pos + 1,
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                         kRangeLastPosition);
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  headers.SetHeader(HttpRequestHeaders::kRange, range);
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartRequest(&headers);
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(delegate_.request_failed());
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ERR_REQUEST_RANGE_NOT_SATISFIABLE, request_->status().error());
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(URLRequestSimpleJobTest, InvalidRangeRequest) {
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HttpRequestHeaders headers;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string range = base::StringPrintf(
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "bytes=%d-%d", kRangeLastPosition, kRangeFirstPosition);
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  headers.SetHeader(HttpRequestHeaders::kRange, range);
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartRequest(&headers);
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(request_->status().is_success());
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kTestData, delegate_.data_received());
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace net
143