Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/http_response_body_drainer.h" | 5 #include "net/http/http_response_body_drainer.h" |
| 6 | 6 |
| 7 #include <cstring> | 7 #include <cstring> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 DISALLOW_COPY_AND_ASSIGN(CloseResultWaiter); | 62 DISALLOW_COPY_AND_ASSIGN(CloseResultWaiter); |
| 63 }; | 63 }; |
| 64 | 64 |
| 65 class MockHttpStream : public HttpStream { | 65 class MockHttpStream : public HttpStream { |
| 66 public: | 66 public: |
| 67 MockHttpStream(CloseResultWaiter* result_waiter) | 67 MockHttpStream(CloseResultWaiter* result_waiter) |
| 68 : result_waiter_(result_waiter), | 68 : result_waiter_(result_waiter), |
| 69 closed_(false), | 69 closed_(false), |
| 70 stall_reads_forever_(false), | 70 stall_reads_forever_(false), |
| 71 num_chunks_(0), | 71 num_chunks_(0), |
| 72 delay_eof_chunk_(false), | |
| 72 is_complete_(false), | 73 is_complete_(false), |
| 73 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {} | 74 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {} |
| 74 virtual ~MockHttpStream() {} | 75 virtual ~MockHttpStream() {} |
| 75 | 76 |
| 76 // HttpStream implementation. | 77 // HttpStream implementation. |
| 77 virtual int InitializeStream(const HttpRequestInfo* request_info, | 78 virtual int InitializeStream(const HttpRequestInfo* request_info, |
| 78 const BoundNetLog& net_log, | 79 const BoundNetLog& net_log, |
| 79 const CompletionCallback& callback) OVERRIDE { | 80 const CompletionCallback& callback) OVERRIDE { |
| 80 return ERR_UNEXPECTED; | 81 return ERR_UNEXPECTED; |
| 81 } | 82 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 | 124 |
| 124 virtual void LogNumRttVsBytesMetrics() const OVERRIDE {} | 125 virtual void LogNumRttVsBytesMetrics() const OVERRIDE {} |
| 125 | 126 |
| 126 virtual void Drain(HttpNetworkSession*) OVERRIDE {} | 127 virtual void Drain(HttpNetworkSession*) OVERRIDE {} |
| 127 | 128 |
| 128 // Methods to tweak/observer mock behavior: | 129 // Methods to tweak/observer mock behavior: |
| 129 void StallReadsForever() { stall_reads_forever_ = true; } | 130 void StallReadsForever() { stall_reads_forever_ = true; } |
| 130 | 131 |
| 131 void set_num_chunks(int num_chunks) { num_chunks_ = num_chunks; } | 132 void set_num_chunks(int num_chunks) { num_chunks_ = num_chunks; } |
| 132 | 133 |
| 134 void DelayEofChunk() { delay_eof_chunk_ = true; } | |
|
mmenke
2012/10/12 18:55:05
Think the logic would be a little simpler if you m
| |
| 135 | |
| 133 private: | 136 private: |
| 134 void CompleteRead(); | 137 void CompleteRead(); |
| 135 | 138 |
| 136 bool closed() const { return closed_; } | 139 bool closed() const { return closed_; } |
| 137 | 140 |
| 138 CloseResultWaiter* const result_waiter_; | 141 CloseResultWaiter* const result_waiter_; |
| 139 scoped_refptr<IOBuffer> user_buf_; | 142 scoped_refptr<IOBuffer> user_buf_; |
| 140 CompletionCallback callback_; | 143 CompletionCallback callback_; |
| 141 bool closed_; | 144 bool closed_; |
| 142 bool stall_reads_forever_; | 145 bool stall_reads_forever_; |
| 143 int num_chunks_; | 146 int num_chunks_; |
| 147 bool delay_eof_chunk_; | |
| 144 bool is_complete_; | 148 bool is_complete_; |
| 145 base::WeakPtrFactory<MockHttpStream> weak_factory_; | 149 base::WeakPtrFactory<MockHttpStream> weak_factory_; |
| 146 }; | 150 }; |
| 147 | 151 |
| 148 int MockHttpStream::ReadResponseBody( | 152 int MockHttpStream::ReadResponseBody( |
| 149 IOBuffer* buf, int buf_len, const CompletionCallback& callback) { | 153 IOBuffer* buf, int buf_len, const CompletionCallback& callback) { |
| 150 DCHECK(!callback.is_null()); | 154 DCHECK(!callback.is_null()); |
| 151 DCHECK(callback_.is_null()); | 155 DCHECK(callback_.is_null()); |
| 152 DCHECK(buf); | 156 DCHECK(buf); |
|
mmenke
2012/10/12 18:55:05
While you're here, could you turn these into CHECK
| |
| 153 | 157 |
| 154 if (stall_reads_forever_) | 158 if (stall_reads_forever_) |
| 155 return ERR_IO_PENDING; | 159 return ERR_IO_PENDING; |
| 156 | 160 |
| 157 if (num_chunks_ == 0) | 161 if (num_chunks_ == 0 && !delay_eof_chunk_) |
| 158 return ERR_UNEXPECTED; | 162 return ERR_UNEXPECTED; |
| 159 | 163 |
| 160 if (buf_len > kMagicChunkSize && num_chunks_ > 1) { | 164 if (buf_len > kMagicChunkSize && (num_chunks_ > 1 || delay_eof_chunk_)) { |
| 161 user_buf_ = buf; | 165 user_buf_ = buf; |
| 162 callback_ = callback; | 166 callback_ = callback; |
| 163 MessageLoop::current()->PostTask( | 167 MessageLoop::current()->PostTask( |
| 164 FROM_HERE, | 168 FROM_HERE, |
| 165 base::Bind(&MockHttpStream::CompleteRead, weak_factory_.GetWeakPtr())); | 169 base::Bind(&MockHttpStream::CompleteRead, weak_factory_.GetWeakPtr())); |
| 166 return ERR_IO_PENDING; | 170 return ERR_IO_PENDING; |
| 167 } | 171 } |
| 168 | 172 |
| 169 num_chunks_--; | 173 num_chunks_--; |
| 170 if (!num_chunks_) | 174 if (!num_chunks_) |
| 171 is_complete_ = true; | 175 is_complete_ = true; |
| 172 | 176 |
| 173 return buf_len; | 177 return buf_len; |
| 174 } | 178 } |
| 175 | 179 |
| 176 void MockHttpStream::CompleteRead() { | 180 void MockHttpStream::CompleteRead() { |
| 177 CompletionCallback callback = callback_; | 181 CompletionCallback callback = callback_; |
| 178 std::memset(user_buf_->data(), 1, kMagicChunkSize); | 182 std::memset(user_buf_->data(), 1, kMagicChunkSize); |
| 179 user_buf_ = NULL; | 183 user_buf_ = NULL; |
| 180 callback_.Reset(); | 184 callback_.Reset(); |
| 181 num_chunks_--; | 185 if (num_chunks_) { |
| 182 if (!num_chunks_) | 186 num_chunks_--; |
| 187 if (!num_chunks_ && !delay_eof_chunk_) | |
| 188 is_complete_ = true; | |
| 189 callback.Run(kMagicChunkSize); | |
| 190 } else { | |
| 183 is_complete_ = true; | 191 is_complete_ = true; |
| 184 callback.Run(kMagicChunkSize); | 192 callback.Run(0); |
| 193 } | |
| 185 } | 194 } |
| 186 | 195 |
| 187 class HttpResponseBodyDrainerTest : public testing::Test { | 196 class HttpResponseBodyDrainerTest : public testing::Test { |
| 188 protected: | 197 protected: |
| 189 HttpResponseBodyDrainerTest() | 198 HttpResponseBodyDrainerTest() |
| 190 : proxy_service_(ProxyService::CreateDirect()), | 199 : proxy_service_(ProxyService::CreateDirect()), |
| 191 ssl_config_service_(new SSLConfigServiceDefaults), | 200 ssl_config_service_(new SSLConfigServiceDefaults), |
| 192 http_server_properties_(new HttpServerPropertiesImpl), | 201 http_server_properties_(new HttpServerPropertiesImpl), |
| 193 session_(CreateNetworkSession()), | 202 session_(CreateNetworkSession()), |
| 194 mock_stream_(new MockHttpStream(&result_waiter_)), | 203 mock_stream_(new MockHttpStream(&result_waiter_)), |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 218 drainer_->Start(session_); | 227 drainer_->Start(session_); |
| 219 EXPECT_FALSE(result_waiter_.WaitForResult()); | 228 EXPECT_FALSE(result_waiter_.WaitForResult()); |
| 220 } | 229 } |
| 221 | 230 |
| 222 TEST_F(HttpResponseBodyDrainerTest, DrainBodyAsyncOK) { | 231 TEST_F(HttpResponseBodyDrainerTest, DrainBodyAsyncOK) { |
| 223 mock_stream_->set_num_chunks(3); | 232 mock_stream_->set_num_chunks(3); |
| 224 drainer_->Start(session_); | 233 drainer_->Start(session_); |
| 225 EXPECT_FALSE(result_waiter_.WaitForResult()); | 234 EXPECT_FALSE(result_waiter_.WaitForResult()); |
| 226 } | 235 } |
| 227 | 236 |
| 237 TEST_F(HttpResponseBodyDrainerTest, DrainBodyAsyncDelayedOK) { | |
| 238 mock_stream_->set_num_chunks(3); | |
| 239 mock_stream_->DelayEofChunk(); | |
| 240 drainer_->Start(session_); | |
| 241 EXPECT_FALSE(result_waiter_.WaitForResult()); | |
| 242 } | |
| 243 | |
| 228 TEST_F(HttpResponseBodyDrainerTest, DrainBodySizeEqualsDrainBuffer) { | 244 TEST_F(HttpResponseBodyDrainerTest, DrainBodySizeEqualsDrainBuffer) { |
| 229 mock_stream_->set_num_chunks( | 245 mock_stream_->set_num_chunks( |
| 230 HttpResponseBodyDrainer::kDrainBodyBufferSize / kMagicChunkSize); | 246 HttpResponseBodyDrainer::kDrainBodyBufferSize / kMagicChunkSize); |
| 231 drainer_->Start(session_); | 247 drainer_->Start(session_); |
| 232 EXPECT_FALSE(result_waiter_.WaitForResult()); | 248 EXPECT_FALSE(result_waiter_.WaitForResult()); |
| 233 } | 249 } |
| 234 | 250 |
| 235 TEST_F(HttpResponseBodyDrainerTest, DrainBodyTimeOut) { | 251 TEST_F(HttpResponseBodyDrainerTest, DrainBodyTimeOut) { |
| 236 mock_stream_->set_num_chunks(2); | 252 mock_stream_->set_num_chunks(2); |
| 237 mock_stream_->StallReadsForever(); | 253 mock_stream_->StallReadsForever(); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 268 | 284 |
| 269 TEST_F(HttpResponseBodyDrainerTest, StartWithNothingToDo) { | 285 TEST_F(HttpResponseBodyDrainerTest, StartWithNothingToDo) { |
| 270 mock_stream_->set_num_chunks(0); | 286 mock_stream_->set_num_chunks(0); |
| 271 drainer_->StartWithSize(session_, 0); | 287 drainer_->StartWithSize(session_, 0); |
| 272 EXPECT_FALSE(result_waiter_.WaitForResult()); | 288 EXPECT_FALSE(result_waiter_.WaitForResult()); |
| 273 } | 289 } |
| 274 | 290 |
| 275 } // namespace | 291 } // namespace |
| 276 | 292 |
| 277 } // namespace net | 293 } // namespace net |
| OLD | NEW |