1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/test/embedded_test_server/http_connection.h"
#include <utility>
#include "net/base/net_errors.h"
#include "net/socket/stream_socket.h"
namespace net {
namespace test_server {
HttpConnection::HttpConnection(scoped_ptr<StreamSocket> socket,
const HandleRequestCallback& callback)
: socket_(std::move(socket)),
callback_(callback),
read_buf_(new IOBufferWithSize(4096)),
weak_factory_(this) {}
HttpConnection::~HttpConnection() {
weak_factory_.InvalidateWeakPtrs();
}
void HttpConnection::SendResponseBytes(const std::string& response_string,
const SendCompleteCallback& callback) {
if (response_string.length() > 0) {
scoped_refptr<DrainableIOBuffer> write_buf(new DrainableIOBuffer(
new StringIOBuffer(response_string), response_string.length()));
SendInternal(callback, write_buf);
} else {
callback.Run();
}
}
int HttpConnection::ReadData(const CompletionCallback& callback) {
return socket_->Read(read_buf_.get(), read_buf_->size(), callback);
}
bool HttpConnection::ConsumeData(int size) {
request_parser_.ProcessChunk(base::StringPiece(read_buf_->data(), size));
if (request_parser_.ParseRequest() == HttpRequestParser::ACCEPTED) {
callback_.Run(this, request_parser_.GetRequest());
return true;
}
return false;
}
void HttpConnection::SendInternal(const base::Closure& callback,
scoped_refptr<DrainableIOBuffer> buf) {
while (buf->BytesRemaining() > 0) {
int rv = socket_->Write(buf.get(), buf->BytesRemaining(),
base::Bind(&HttpConnection::OnSendInternalDone,
base::Unretained(this), callback, buf));
if (rv == ERR_IO_PENDING)
return;
if (rv < 0)
break;
buf->DidConsume(rv);
}
// The HttpConnection will be deleted by the callback since we only need to
// serve a single request.
callback.Run();
}
void HttpConnection::OnSendInternalDone(const base::Closure& callback,
scoped_refptr<DrainableIOBuffer> buf,
int rv) {
if (rv < 0) {
callback.Run();
return;
}
buf->DidConsume(rv);
SendInternal(callback, buf);
}
base::WeakPtr<HttpConnection> HttpConnection::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
} // namespace test_server
} // namespace net
|