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.
5 #include "net/http/http_response_body_drainer.h"
7 #include "base/compiler_specific.h"
8 #include "base/logging.h"
9 #include "net/base/io_buffer.h"
10 #include "net/base/net_errors.h"
11 #include "net/http/http_network_session.h"
12 #include "net/http/http_stream.h"
16 HttpResponseBodyDrainer::HttpResponseBodyDrainer(HttpStream
* stream
)
18 next_state_(STATE_NONE
),
22 HttpResponseBodyDrainer::~HttpResponseBodyDrainer() {}
24 void HttpResponseBodyDrainer::Start(HttpNetworkSession
* session
) {
25 read_buf_
= new IOBuffer(kDrainBodyBufferSize
);
26 next_state_
= STATE_DRAIN_RESPONSE_BODY
;
29 if (rv
== ERR_IO_PENDING
) {
30 timer_
.Start(FROM_HERE
,
31 base::TimeDelta::FromSeconds(kTimeoutInSeconds
),
33 &HttpResponseBodyDrainer::OnTimerFired
);
35 session
->AddResponseDrainer(this);
42 int HttpResponseBodyDrainer::DoLoop(int result
) {
43 DCHECK_NE(next_state_
, STATE_NONE
);
47 State state
= next_state_
;
48 next_state_
= STATE_NONE
;
50 case STATE_DRAIN_RESPONSE_BODY
:
52 rv
= DoDrainResponseBody();
54 case STATE_DRAIN_RESPONSE_BODY_COMPLETE
:
55 rv
= DoDrainResponseBodyComplete(rv
);
58 NOTREACHED() << "bad state";
62 } while (rv
!= ERR_IO_PENDING
&& next_state_
!= STATE_NONE
);
67 int HttpResponseBodyDrainer::DoDrainResponseBody() {
68 next_state_
= STATE_DRAIN_RESPONSE_BODY_COMPLETE
;
70 return stream_
->ReadResponseBody(
72 kDrainBodyBufferSize
- total_read_
,
73 base::Bind(&HttpResponseBodyDrainer::OnIOComplete
,
74 base::Unretained(this)));
77 int HttpResponseBodyDrainer::DoDrainResponseBodyComplete(int result
) {
78 DCHECK_NE(ERR_IO_PENDING
, result
);
83 total_read_
+= result
;
84 if (stream_
->IsResponseBodyComplete())
87 DCHECK_LE(total_read_
, kDrainBodyBufferSize
);
88 if (total_read_
>= kDrainBodyBufferSize
)
89 return ERR_RESPONSE_BODY_TOO_BIG_TO_DRAIN
;
92 return ERR_CONNECTION_CLOSED
;
94 next_state_
= STATE_DRAIN_RESPONSE_BODY
;
98 void HttpResponseBodyDrainer::OnIOComplete(int result
) {
99 int rv
= DoLoop(result
);
100 if (rv
!= ERR_IO_PENDING
) {
106 void HttpResponseBodyDrainer::OnTimerFired() {
107 Finish(ERR_TIMED_OUT
);
110 void HttpResponseBodyDrainer::Finish(int result
) {
111 DCHECK_NE(ERR_IO_PENDING
, result
);
114 session_
->RemoveResponseDrainer(this);
117 stream_
->Close(true /* no keep-alive */);
119 DCHECK_EQ(OK
, result
);
120 stream_
->Close(false /* keep-alive */);