1 // Copyright (c) 2012 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. 4 5 #include "base/message_loop/message_loop.h" 6 #include "base/test/test_simple_task_runner.h" 7 #include "content/browser/streams/stream.h" 8 #include "content/browser/streams/stream_registry.h" 9 #include "content/browser/streams/stream_url_request_job.h" 10 #include "content/browser/streams/stream_write_observer.h" 11 #include "net/http/http_response_headers.h" 12 #include "net/url_request/url_request.h" 13 #include "net/url_request/url_request_context.h" 14 #include "net/url_request/url_request_job_factory_impl.h" 15 #include "net/url_request/url_request_test_util.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 18 namespace content { 19 20 namespace { 21 22 const int kBufferSize = 1024; 23 const char kTestData1[] = "Hello"; 24 const char kTestData2[] = "Here it is data."; 25 26 const GURL kStreamURL("blob://stream"); 27 28 } // namespace 29 30 class StreamURLRequestJobTest : public testing::Test { 31 public: 32 // A simple ProtocolHandler implementation to create StreamURLRequestJob. 33 class MockProtocolHandler : 34 public net::URLRequestJobFactory::ProtocolHandler { 35 public: 36 MockProtocolHandler(StreamRegistry* registry) : registry_(registry) {} 37 38 // net::URLRequestJobFactory::ProtocolHandler override. 39 virtual net::URLRequestJob* MaybeCreateJob( 40 net::URLRequest* request, 41 net::NetworkDelegate* network_delegate) const OVERRIDE { 42 scoped_refptr<Stream> stream = registry_->GetStream(request->url()); 43 if (stream.get()) 44 return new StreamURLRequestJob(request, network_delegate, stream); 45 return NULL; 46 } 47 48 private: 49 StreamRegistry* registry_; 50 }; 51 52 StreamURLRequestJobTest() : message_loop_(base::MessageLoop::TYPE_IO) {} 53 54 virtual void SetUp() { 55 registry_.reset(new StreamRegistry()); 56 57 url_request_job_factory_.SetProtocolHandler( 58 "blob", new MockProtocolHandler(registry_.get())); 59 url_request_context_.set_job_factory(&url_request_job_factory_); 60 } 61 62 virtual void TearDown() { 63 } 64 65 void TestSuccessRequest(const GURL& url, 66 const std::string& expected_response) { 67 TestRequest("GET", url, net::HttpRequestHeaders(), 200, expected_response); 68 } 69 70 void TestRequest(const std::string& method, 71 const GURL& url, 72 const net::HttpRequestHeaders& extra_headers, 73 int expected_status_code, 74 const std::string& expected_response) { 75 net::TestDelegate delegate; 76 request_.reset(url_request_context_.CreateRequest(url, &delegate)); 77 request_->set_method(method); 78 if (!extra_headers.IsEmpty()) 79 request_->SetExtraRequestHeaders(extra_headers); 80 request_->Start(); 81 82 base::MessageLoop::current()->RunUntilIdle(); 83 84 // Verify response. 85 EXPECT_TRUE(request_->status().is_success()); 86 EXPECT_EQ(expected_status_code, 87 request_->response_headers()->response_code()); 88 EXPECT_EQ(expected_response, delegate.data_received()); 89 } 90 91 protected: 92 base::MessageLoop message_loop_; 93 scoped_ptr<StreamRegistry> registry_; 94 95 net::URLRequestContext url_request_context_; 96 net::URLRequestJobFactoryImpl url_request_job_factory_; 97 scoped_ptr<net::URLRequest> request_; 98 }; 99 100 TEST_F(StreamURLRequestJobTest, TestGetSimpleDataRequest) { 101 scoped_refptr<Stream> stream( 102 new Stream(registry_.get(), NULL, kStreamURL)); 103 104 scoped_refptr<net::StringIOBuffer> buffer( 105 new net::StringIOBuffer(kTestData1)); 106 107 stream->AddData(buffer, buffer->size()); 108 stream->Finalize(); 109 110 TestSuccessRequest(kStreamURL, kTestData1); 111 } 112 113 TEST_F(StreamURLRequestJobTest, TestGetLargeStreamRequest) { 114 scoped_refptr<Stream> stream( 115 new Stream(registry_.get(), NULL, kStreamURL)); 116 117 std::string large_data; 118 large_data.reserve(kBufferSize * 5); 119 for (int i = 0; i < kBufferSize * 5; ++i) 120 large_data.append(1, static_cast<char>(i % 256)); 121 122 scoped_refptr<net::StringIOBuffer> buffer( 123 new net::StringIOBuffer(large_data)); 124 125 stream->AddData(buffer, buffer->size()); 126 stream->Finalize(); 127 TestSuccessRequest(kStreamURL, large_data); 128 } 129 130 TEST_F(StreamURLRequestJobTest, TestGetNonExistentStreamRequest) { 131 net::TestDelegate delegate; 132 request_.reset(url_request_context_.CreateRequest(kStreamURL, &delegate)); 133 request_->set_method("GET"); 134 request_->Start(); 135 136 base::MessageLoop::current()->RunUntilIdle(); 137 138 // Verify response. 139 EXPECT_FALSE(request_->status().is_success()); 140 } 141 142 TEST_F(StreamURLRequestJobTest, TestRangeDataRequest) { 143 scoped_refptr<Stream> stream( 144 new Stream(registry_.get(), NULL, kStreamURL)); 145 146 scoped_refptr<net::StringIOBuffer> buffer( 147 new net::StringIOBuffer(kTestData2)); 148 149 stream->AddData(buffer, buffer->size()); 150 stream->Finalize(); 151 152 net::HttpRequestHeaders extra_headers; 153 extra_headers.SetHeader(net::HttpRequestHeaders::kRange, "bytes=0-3"); 154 TestRequest("GET", kStreamURL, extra_headers, 155 200, std::string(kTestData2, 4)); 156 } 157 158 TEST_F(StreamURLRequestJobTest, TestInvalidRangeDataRequest) { 159 scoped_refptr<Stream> stream( 160 new Stream(registry_.get(), NULL, kStreamURL)); 161 162 scoped_refptr<net::StringIOBuffer> buffer( 163 new net::StringIOBuffer(kTestData2)); 164 165 stream->AddData(buffer, buffer->size()); 166 stream->Finalize(); 167 168 net::HttpRequestHeaders extra_headers; 169 extra_headers.SetHeader(net::HttpRequestHeaders::kRange, "bytes=1-3"); 170 TestRequest("GET", kStreamURL, extra_headers, 405, std::string()); 171 } 172 173 } // namespace content 174