1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/android/url_request_content_job.h"
9 #include "base/files/file_util.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/run_loop.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/test/test_file_util.h"
14 #include "net/url_request/url_request.h"
15 #include "net/url_request/url_request_test_util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
23 // A URLRequestJobFactory that will return URLRequestContentJobWithCallbacks
24 // instances for content:// scheme URLs.
25 class CallbacksJobFactory
: public net::URLRequestJobFactory
{
29 virtual void OnJobCreated(URLRequestContentJob
* job
) = 0;
32 CallbacksJobFactory(const base::FilePath
& path
, JobObserver
* observer
)
33 : path_(path
), observer_(observer
) {
36 ~CallbacksJobFactory() override
{}
38 net::URLRequestJob
* MaybeCreateJobWithProtocolHandler(
39 const std::string
& scheme
,
40 net::URLRequest
* request
,
41 net::NetworkDelegate
* network_delegate
) const override
{
42 URLRequestContentJob
* job
=
43 new URLRequestContentJob(
47 const_cast<base::MessageLoop
*>(&message_loop_
)->task_runner());
48 observer_
->OnJobCreated(job
);
52 net::URLRequestJob
* MaybeInterceptRedirect(
53 net::URLRequest
* request
,
54 net::NetworkDelegate
* network_delegate
,
55 const GURL
& location
) const override
{
59 net::URLRequestJob
* MaybeInterceptResponse(
60 net::URLRequest
* request
,
61 net::NetworkDelegate
* network_delegate
) const override
{
65 bool IsHandledProtocol(const std::string
& scheme
) const override
{
66 return scheme
== "content";
69 bool IsHandledURL(const GURL
& url
) const override
{
70 return IsHandledProtocol(url
.scheme());
73 bool IsSafeRedirectTarget(const GURL
& location
) const override
{
78 base::MessageLoop message_loop_
;
80 JobObserver
* observer_
;
83 class JobObserverImpl
: public CallbacksJobFactory::JobObserver
{
85 void OnJobCreated(URLRequestContentJob
* job
) override
{
89 typedef std::vector
<scoped_refptr
<URLRequestContentJob
> > JobList
;
91 const JobList
& jobs() { return jobs_
; }
97 // A simple holder for start/end used in http range requests.
102 explicit Range(int start
, int end
) {
108 // A superclass for tests of the OnSeekComplete / OnReadComplete functions of
109 // URLRequestContentJob.
110 class URLRequestContentJobTest
: public testing::Test
{
112 URLRequestContentJobTest();
115 // This inserts an image file into the android MediaStore and retrieves the
116 // content URI. Then creates and runs a URLRequestContentJob to get the
117 // contents out of it. If a Range is provided, this function will add the
118 // appropriate Range http header to the request and verify the bytes
120 void RunRequest(const Range
* range
);
122 JobObserverImpl observer_
;
123 net::TestURLRequestContext context_
;
124 net::TestDelegate delegate_
;
127 URLRequestContentJobTest::URLRequestContentJobTest() {}
129 void URLRequestContentJobTest::RunRequest(const Range
* range
) {
130 base::FilePath test_dir
;
131 PathService::Get(base::DIR_SOURCE_ROOT
, &test_dir
);
132 test_dir
= test_dir
.AppendASCII("content");
133 test_dir
= test_dir
.AppendASCII("test");
134 test_dir
= test_dir
.AppendASCII("data");
135 test_dir
= test_dir
.AppendASCII("android");
136 ASSERT_TRUE(base::PathExists(test_dir
));
137 base::FilePath image_file
= test_dir
.Append(FILE_PATH_LITERAL("red.png"));
139 // Insert the image into MediaStore. MediaStore will do some conversions, and
140 // return the content URI.
141 base::FilePath path
= base::InsertImageIntoMediaStore(image_file
);
142 EXPECT_TRUE(path
.IsContentUri());
143 EXPECT_TRUE(base::PathExists(path
));
145 EXPECT_TRUE(base::GetFileSize(path
, &file_size
));
146 EXPECT_LT(0, file_size
);
147 CallbacksJobFactory
factory(path
, &observer_
);
148 context_
.set_job_factory(&factory
);
150 scoped_ptr
<net::URLRequest
> request(context_
.CreateRequest(
151 GURL(path
.value()), net::DEFAULT_PRIORITY
, &delegate_
));
152 int expected_length
= file_size
;
154 ASSERT_GE(range
->start
, 0);
155 ASSERT_GE(range
->end
, 0);
156 ASSERT_LE(range
->start
, range
->end
);
157 std::string range_value
=
158 base::StringPrintf("bytes=%d-%d", range
->start
, range
->end
);
159 request
->SetExtraRequestHeaderByName(
160 net::HttpRequestHeaders::kRange
, range_value
, true /*overwrite*/);
161 if (range
->start
<= file_size
)
163 std::min(range
->end
, (int) (file_size
- 1)) - range
->start
+ 1;
172 EXPECT_FALSE(delegate_
.request_failed());
173 ASSERT_EQ(observer_
.jobs().size(), 1u);
174 EXPECT_EQ(delegate_
.bytes_received(), expected_length
);
177 TEST_F(URLRequestContentJobTest
, ContentURIWithoutRange
) {
181 TEST_F(URLRequestContentJobTest
, ContentURIWithSmallRange
) {
186 TEST_F(URLRequestContentJobTest
, ContentURIWithLargeRange
) {
187 Range
range(1, 100000);
191 TEST_F(URLRequestContentJobTest
, ContentURIWithZeroRange
) {
198 } // namespace content