Skip to content

Commit

Permalink
[HttpStreamParser]: Flush buffers as soon as request is sent.
Browse files Browse the repository at this point in the history
This cl aims on reducing amount of memory used. Once request
is sent, flush buffers to free allocated memory.

BUG=622073

Review-Url: https://codereview.chromium.org/2130733003
Cr-Commit-Position: refs/heads/master@{#405128}
  • Loading branch information
maksim.sisov authored and Commit bot committed Jul 13, 2016
1 parent 5285fd0 commit a4fc935
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
33 changes: 32 additions & 1 deletion net/http/http_stream_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ int HttpStreamParser::ReadResponseHeaders(const CompletionCallback& callback) {
DCHECK(callback_.is_null());
DCHECK(!callback.is_null());
DCHECK_EQ(0, read_buf_unused_offset_);
DCHECK(SendRequestBuffersEmpty());

// This function can be called with io_state_ == STATE_DONE if the
// connection is closed after seeing just a 1xx response code.
Expand Down Expand Up @@ -369,6 +370,7 @@ int HttpStreamParser::ReadResponseBody(IOBuffer* buf, int buf_len,
DCHECK(callback_.is_null());
DCHECK(!callback.is_null());
DCHECK_LE(buf_len, kMaxBufSize);
DCHECK(SendRequestBuffersEmpty());
// Added to investigate crbug.com/499663.
CHECK(buf);

Expand Down Expand Up @@ -409,19 +411,27 @@ int HttpStreamParser::DoLoop(int result) {
case STATE_SEND_HEADERS:
DCHECK_EQ(OK, result);
result = DoSendHeaders();
DCHECK_NE(STATE_NONE, io_state_);
break;
case STATE_SEND_HEADERS_COMPLETE:
result = DoSendHeadersComplete(result);
DCHECK_NE(STATE_NONE, io_state_);
break;
case STATE_SEND_BODY:
DCHECK_EQ(OK, result);
result = DoSendBody();
DCHECK_NE(STATE_NONE, io_state_);
break;
case STATE_SEND_BODY_COMPLETE:
result = DoSendBodyComplete(result);
DCHECK_NE(STATE_NONE, io_state_);
break;
case STATE_SEND_REQUEST_READ_BODY_COMPLETE:
result = DoSendRequestReadBodyComplete(result);
DCHECK_NE(STATE_NONE, io_state_);
break;
case STATE_SEND_REQUEST_COMPLETE:
result = DoSendRequestComplete(result);
break;
case STATE_READ_HEADERS:
net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_PARSER_READ_HEADERS);
Expand Down Expand Up @@ -475,6 +485,7 @@ int HttpStreamParser::DoSendHeadersComplete(int result) {
// the headers were sent, but not all of the body way, and |result| is
// an error that this should try reading after, stash the error for now and
// act like the request was successfully sent.
io_state_ = STATE_SEND_REQUEST_COMPLETE;
if (request_headers_->BytesConsumed() >= request_headers_length_ &&
ShouldTryReadingOnUploadError(result)) {
upload_error_ = result;
Expand Down Expand Up @@ -506,6 +517,7 @@ int HttpStreamParser::DoSendHeadersComplete(int result) {
}

// Finished sending the request.
io_state_ = STATE_SEND_REQUEST_COMPLETE;
return OK;
}

Expand All @@ -520,6 +532,7 @@ int HttpStreamParser::DoSendBody() {

if (request_->upload_data_stream->is_chunked() && sent_last_chunk_) {
// Finished sending the request.
io_state_ = STATE_SEND_REQUEST_COMPLETE;
return OK;
}

Expand All @@ -534,6 +547,7 @@ int HttpStreamParser::DoSendBodyComplete(int result) {
if (result < 0) {
// If |result| is an error that this should try reading after, stash the
// error for now and act like the request was successfully sent.
io_state_ = STATE_SEND_REQUEST_COMPLETE;
if (ShouldTryReadingOnUploadError(result)) {
upload_error_ = result;
return OK;
Expand All @@ -551,8 +565,10 @@ int HttpStreamParser::DoSendBodyComplete(int result) {
int HttpStreamParser::DoSendRequestReadBodyComplete(int result) {
// |result| is the result of read from the request body from the last call to
// DoSendBody().
if (result < 0)
if (result < 0) {
io_state_ = STATE_SEND_REQUEST_COMPLETE;
return result;
}

// Chunked data needs to be encoded.
if (request_->upload_data_stream->is_chunked()) {
Expand All @@ -574,6 +590,7 @@ int HttpStreamParser::DoSendRequestReadBodyComplete(int result) {
DCHECK(request_->upload_data_stream->IsEOF());
DCHECK(!request_->upload_data_stream->is_chunked());
// Finished sending the request.
io_state_ = STATE_SEND_REQUEST_COMPLETE;
} else if (result > 0) {
request_body_send_buf_->DidAppend(result);
result = 0;
Expand All @@ -582,6 +599,15 @@ int HttpStreamParser::DoSendRequestReadBodyComplete(int result) {
return result;
}

int HttpStreamParser::DoSendRequestComplete(int result) {
DCHECK_NE(result, ERR_IO_PENDING);
request_headers_ = nullptr;
request_body_send_buf_ = nullptr;
request_body_read_buf_ = nullptr;

return result;
}

int HttpStreamParser::DoReadHeaders() {
io_state_ = STATE_READ_HEADERS_COMPLETE;

Expand Down Expand Up @@ -1194,4 +1220,9 @@ void HttpStreamParser::ValidateStatusLine(const std::string& status_line) {
HttpStatusLineValidator::STATUS_LINE_MAX);
}

bool HttpStreamParser::SendRequestBuffersEmpty() {
return request_headers_ == nullptr && request_body_send_buf_ == nullptr &&
request_body_send_buf_ == nullptr;
}

} // namespace net
5 changes: 5 additions & 0 deletions net/http/http_stream_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
STATE_SEND_BODY,
STATE_SEND_BODY_COMPLETE,
STATE_SEND_REQUEST_READ_BODY_COMPLETE,
STATE_SEND_REQUEST_COMPLETE,
STATE_READ_HEADERS,
STATE_READ_HEADERS_COMPLETE,
STATE_READ_BODY,
Expand Down Expand Up @@ -167,6 +168,7 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
int DoSendBody();
int DoSendBodyComplete(int result);
int DoSendRequestReadBodyComplete(int result);
int DoSendRequestComplete(int result);
int DoReadHeaders();
int DoReadHeadersComplete(int result);
int DoReadBody();
Expand All @@ -191,6 +193,9 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
// Uploads statistics about status line compliance with RFC 7230.
void ValidateStatusLine(const std::string& status_line);

// Check if buffers used to send the request are empty.
bool SendRequestBuffersEmpty();

// Next state of the request, when the current one completes.
State io_state_;

Expand Down

0 comments on commit a4fc935

Please sign in to comment.