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 |