1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "shill/http_proxy.h"
18 
19 #include <errno.h>
20 #include <netinet/in.h>
21 #include <linux/if.h>  // NOLINT - Needs definitions from netinet/in.h
22 #include <stdio.h>
23 #include <time.h>
24 
25 #include <string>
26 #include <vector>
27 
28 #include <base/bind.h>
29 #include <base/strings/string_number_conversions.h>
30 #include <base/strings/string_split.h>
31 #include <base/strings/string_util.h>
32 #include <base/strings/stringprintf.h>
33 
34 #include "shill/async_connection.h"
35 #include "shill/connection.h"
36 #include "shill/dns_client.h"
37 #include "shill/event_dispatcher.h"
38 #include "shill/logging.h"
39 #include "shill/net/ip_address.h"
40 #include "shill/net/sockets.h"
41 
42 using base::Bind;
43 using base::StringPrintf;
44 using std::string;
45 using std::vector;
46 
47 namespace shill {
48 
49 namespace Logging {
50 static auto kModuleLogScope = ScopeLogger::kHTTPProxy;
ObjectID(Connection * c)51 static string ObjectID(Connection* c) {
52   return c->interface_name();
53 }
54 }
55 
56 const int HTTPProxy::kClientHeaderTimeoutSeconds = 1;
57 const int HTTPProxy::kConnectTimeoutSeconds = 10;
58 const int HTTPProxy::kDNSTimeoutSeconds = 5;
59 const int HTTPProxy::kDefaultServerPort = 80;
60 const int HTTPProxy::kInputTimeoutSeconds = 30;
61 const size_t HTTPProxy::kMaxClientQueue = 10;
62 const size_t HTTPProxy::kMaxHeaderCount = 128;
63 const size_t HTTPProxy::kMaxHeaderSize = 2048;
64 const int HTTPProxy::kTransactionTimeoutSeconds = 600;
65 
66 const char HTTPProxy::kHTTPMethodConnect[] = "connect";
67 const char HTTPProxy::kHTTPMethodTerminator[] = " ";
68 const char HTTPProxy::kHTTPURLDelimiters[] = " /#?";
69 const char HTTPProxy::kHTTPURLPrefix[] = "http://";
70 const char HTTPProxy::kHTTPVersionPrefix[] = " HTTP/1";
71 const char HTTPProxy::kInternalErrorMsg[] = "Proxy Failed: Internal Error";
72 
HTTPProxy(ConnectionRefPtr connection)73 HTTPProxy::HTTPProxy(ConnectionRefPtr connection)
74     : state_(kStateIdle),
75       connection_(connection),
76       weak_ptr_factory_(this),
77       accept_callback_(Bind(&HTTPProxy::AcceptClient,
78                             weak_ptr_factory_.GetWeakPtr())),
79       connect_completion_callback_(Bind(&HTTPProxy::OnConnectCompletion,
80                                         weak_ptr_factory_.GetWeakPtr())),
81       dns_client_callback_(Bind(&HTTPProxy::GetDNSResult,
82                                 weak_ptr_factory_.GetWeakPtr())),
83       read_client_callback_(Bind(&HTTPProxy::ReadFromClient,
84                                  weak_ptr_factory_.GetWeakPtr())),
85       read_server_callback_(Bind(&HTTPProxy::ReadFromServer,
86                                  weak_ptr_factory_.GetWeakPtr())),
87       write_client_callback_(Bind(&HTTPProxy::WriteToClient,
88                                   weak_ptr_factory_.GetWeakPtr())),
89       write_server_callback_(Bind(&HTTPProxy::WriteToServer,
90                                   weak_ptr_factory_.GetWeakPtr())),
91       dispatcher_(nullptr),
92       proxy_port_(-1),
93       proxy_socket_(-1),
94       sockets_(nullptr),
95       client_socket_(-1),
96       server_port_(kDefaultServerPort),
97       server_socket_(-1),
98       is_route_requested_(false) { }
99 
~HTTPProxy()100 HTTPProxy::~HTTPProxy() {
101   Stop();
102 }
103 
Start(EventDispatcher * dispatcher,Sockets * sockets)104 bool HTTPProxy::Start(EventDispatcher* dispatcher,
105                       Sockets* sockets) {
106   SLOG(connection_.get(), 3) << "In " << __func__;
107 
108   if (sockets_) {
109     // We are already running.
110     return true;
111   }
112 
113   proxy_socket_ = sockets->Socket(PF_INET, SOCK_STREAM, 0);
114   if (proxy_socket_ < 0) {
115     PLOG(ERROR) << "Failed to open proxy socket";
116     return false;
117   }
118 
119   struct sockaddr_in addr;
120   socklen_t addrlen = sizeof(addr);
121   memset(&addr, 0, sizeof(addr));
122   addr.sin_family = AF_INET;
123   addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
124   if (sockets->Bind(proxy_socket_,
125                     reinterpret_cast<struct sockaddr*>(&addr),
126                     sizeof(addr)) < 0 ||
127       sockets->GetSockName(proxy_socket_,
128                            reinterpret_cast<struct sockaddr*>(&addr),
129                            &addrlen) < 0 ||
130       sockets->SetNonBlocking(proxy_socket_) < 0 ||
131       sockets->Listen(proxy_socket_, kMaxClientQueue) < 0) {
132     sockets->Close(proxy_socket_);
133     proxy_socket_ = -1;
134     PLOG(ERROR) << "HTTPProxy socket setup failed";
135     return false;
136   }
137 
138   accept_handler_.reset(
139       dispatcher->CreateReadyHandler(proxy_socket_, IOHandler::kModeInput,
140                                      accept_callback_));
141   dispatcher_ = dispatcher;
142   dns_client_.reset(new DNSClient(IPAddress::kFamilyIPv4,
143                                   connection_->interface_name(),
144                                   connection_->dns_servers(),
145                                   kDNSTimeoutSeconds * 1000,
146                                   dispatcher,
147                                   dns_client_callback_));
148   proxy_port_ = ntohs(addr.sin_port);
149   server_async_connection_.reset(
150       new AsyncConnection(connection_->interface_name(), dispatcher, sockets,
151                           connect_completion_callback_));
152   sockets_ = sockets;
153   state_ = kStateWaitConnection;
154   return true;
155 }
156 
Stop()157 void HTTPProxy::Stop() {
158   SLOG(connection_.get(), 3) << "In " << __func__;
159 
160   if (!sockets_) {
161     return;
162   }
163 
164   StopClient();
165 
166   accept_handler_.reset();
167   dispatcher_ = nullptr;
168   dns_client_.reset();
169   proxy_port_ = -1;
170   server_async_connection_.reset();
171   sockets_->Close(proxy_socket_);
172   proxy_socket_ = -1;
173   sockets_ = nullptr;
174   state_ = kStateIdle;
175 }
176 
177 // IOReadyHandler callback routine fired when a client connects to the
178 // proxy's socket.  We Accept() the client and start reading a request
179 // from it.
AcceptClient(int fd)180 void HTTPProxy::AcceptClient(int fd) {
181   SLOG(connection_.get(), 3) << "In " << __func__;
182 
183   int client_fd = sockets_->Accept(fd, nullptr, nullptr);
184   if (client_fd < 0) {
185     PLOG(ERROR) << "Client accept failed";
186     return;
187   }
188 
189   accept_handler_->Stop();
190 
191   client_socket_ = client_fd;
192 
193   sockets_->SetNonBlocking(client_socket_);
194   read_client_handler_.reset(dispatcher_->CreateInputHandler(
195       client_socket_,
196       read_client_callback_,
197       Bind(&HTTPProxy::OnReadError, weak_ptr_factory_.GetWeakPtr())));
198   // Overall transaction timeout.
199   transaction_timeout_.Reset(Bind(&HTTPProxy::StopClient,
200                                   weak_ptr_factory_.GetWeakPtr()));
201   dispatcher_->PostDelayedTask(transaction_timeout_.callback(),
202                                kTransactionTimeoutSeconds * 1000);
203 
204   state_ = kStateReadClientHeader;
205   StartIdleTimeout();
206 }
207 
ConnectServer(const IPAddress & address,int port)208 bool HTTPProxy::ConnectServer(const IPAddress& address, int port) {
209   state_ = kStateConnectServer;
210   if (!server_async_connection_->Start(address, port)) {
211     SendClientError(500, "Could not create socket to connect to server");
212     return false;
213   }
214   StartIdleTimeout();
215   return true;
216 }
217 
218 // DNSClient callback that fires when the DNS request completes.
GetDNSResult(const Error & error,const IPAddress & address)219 void HTTPProxy::GetDNSResult(const Error& error, const IPAddress& address) {
220   if (!error.IsSuccess()) {
221     SendClientError(502, string("Could not resolve hostname: ") +
222                     error.message());
223     return;
224   }
225   ConnectServer(address, server_port_);
226 }
227 
228 // IOReadyHandler callback routine which fires when the asynchronous Connect()
229 // to the remote server completes (or fails).
OnConnectCompletion(bool success,int fd)230 void HTTPProxy::OnConnectCompletion(bool success, int fd) {
231   if (!success) {
232     SendClientError(500, string("Socket connection delayed failure: ") +
233                     server_async_connection_->error());
234     return;
235   }
236   server_socket_ = fd;
237   state_ = kStateTunnelData;
238 
239   // If this was a "CONNECT" request, notify the client that the connection
240   // has been established by sending an "OK" response.
241   if (base::LowerCaseEqualsASCII(client_method_, kHTTPMethodConnect)) {
242     SetClientResponse(200, "OK", "", "");
243     StartReceive();
244   }
245 
246   StartTransmit();
247 }
248 
OnReadError(const string & error_msg)249 void HTTPProxy::OnReadError(const string& error_msg) {
250   StopClient();
251 }
252 
253 // Read through the header lines from the client, modifying or adding
254 // lines as necessary.  Perform final determination of the hostname/port
255 // we should connect to and either start a DNS request or connect to a
256 // numeric address.
ParseClientRequest()257 bool HTTPProxy::ParseClientRequest() {
258   SLOG(connection_.get(), 3) << "In " << __func__;
259 
260   string host;
261   bool found_via = false;
262   bool found_connection = false;
263   for (auto& header : client_headers_) {
264     if (base::StartsWith(header, "Host:",
265                          base::CompareCase::INSENSITIVE_ASCII)) {
266       host = header.substr(5);
267     } else if (base::StartsWith(header, "Via:",
268                                 base::CompareCase::INSENSITIVE_ASCII)) {
269       found_via = true;
270       header.append(StringPrintf(", %s shill-proxy", client_version_.c_str()));
271     } else if (base::StartsWith(header, "Connection:",
272                                 base::CompareCase::INSENSITIVE_ASCII)) {
273       found_connection = true;
274       header.assign("Connection: close");
275     } else if (base::StartsWith(header, "Proxy-Connection:",
276                                 base::CompareCase::INSENSITIVE_ASCII)) {
277       header.assign("Proxy-Connection: close");
278     }
279   }
280 
281   if (!found_connection) {
282     client_headers_.push_back("Connection: close");
283   }
284   if (!found_via) {
285     client_headers_.push_back(
286         StringPrintf("Via: %s shill-proxy", client_version_.c_str()));
287   }
288 
289   // Assemble the request as it will be sent to the server.
290   client_data_.Clear();
291   if (!base::LowerCaseEqualsASCII(client_method_, kHTTPMethodConnect)) {
292     for (const auto& header : client_headers_) {
293       client_data_.Append(ByteString(header + "\r\n", false));
294     }
295     client_data_.Append(ByteString(string("\r\n"), false));
296   }
297 
298   base::TrimWhitespaceASCII(host, base::TRIM_ALL, &host);
299   if (host.empty()) {
300     // Revert to using the hostname in the URL if no "Host:" header exists.
301     host = server_hostname_;
302   }
303 
304   if (host.empty()) {
305     SendClientError(400, "I don't know what host you want me to connect to");
306     return false;
307   }
308 
309   server_port_ = 80;
310   vector<string> host_parts = base::SplitString(
311       host, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
312 
313   if (host_parts.size() > 2) {
314     SendClientError(400, "Too many colons in hostname");
315     return false;
316   } else if (host_parts.size() == 2) {
317     server_hostname_ = host_parts[0];
318     if (!base::StringToInt(host_parts[1], &server_port_)) {
319       SendClientError(400, "Could not parse port number");
320       return false;
321     }
322   } else {
323     server_hostname_ = host;
324   }
325 
326   connection_->RequestRouting();
327   is_route_requested_ = true;
328 
329   IPAddress addr(IPAddress::kFamilyIPv4);
330   if (addr.SetAddressFromString(server_hostname_)) {
331     if (!ConnectServer(addr, server_port_)) {
332       return false;
333     }
334   } else {
335     SLOG(connection_.get(), 3) << "Looking up host: " << server_hostname_;
336     Error error;
337     if (!dns_client_->Start(server_hostname_, &error)) {
338       SendClientError(502, "Could not resolve hostname: " + error.message());
339       return false;
340     }
341     state_ = kStateLookupServer;
342   }
343   return true;
344 }
345 
346 // Accept a new line into the client headers.  Returns false if a parse
347 // error occurs.
ProcessLastHeaderLine()348 bool HTTPProxy::ProcessLastHeaderLine() {
349   string* header = &client_headers_.back();
350   base::TrimString(*header, "\r", header);
351 
352   if (header->empty()) {
353     // Empty line terminates client headers.
354     client_headers_.pop_back();
355     if (!ParseClientRequest()) {
356       return false;
357     }
358   }
359 
360   // Is this is the first header line?
361   if (client_headers_.size() == 1) {
362     if (!ReadClientHTTPMethod(header) ||
363         !ReadClientHTTPVersion(header) ||
364         !ReadClientHostname(header)) {
365       return false;
366     }
367   }
368 
369   if (client_headers_.size() >= kMaxHeaderCount) {
370     SendClientError(500, kInternalErrorMsg);
371     return false;
372   }
373 
374   return true;
375 }
376 
377 // Split input from client into header lines, and consume parsed lines
378 // from InputData.  The passed in |data| is modified to indicate the
379 // characters consumed.
ReadClientHeaders(InputData * data)380 bool HTTPProxy::ReadClientHeaders(InputData* data) {
381   unsigned char* ptr = data->buf;
382   unsigned char* end = ptr + data->len;
383 
384   if (client_headers_.empty()) {
385     client_headers_.push_back(string());
386   }
387 
388   for (; ptr < end && state_ == kStateReadClientHeader; ++ptr) {
389     if (*ptr == '\n') {
390       if (!ProcessLastHeaderLine()) {
391         return false;
392       }
393 
394       // Start a new line.  New chararacters we receive will be appended there.
395       client_headers_.push_back(string());
396       continue;
397     }
398 
399     string* header = &client_headers_.back();
400     // Is the first character of the header line a space or tab character?
401     if (header->empty() && (*ptr == ' ' || *ptr == '\t') &&
402         client_headers_.size() > 1) {
403       // Line Continuation: Add this character to the previous header line.
404       // This way, all of the data (including newlines and line continuation
405       // characters) related to a specific header will be contained within
406       // a single element of |client_headers_|, and manipulation of headers
407       // such as appending will be simpler.  This is accomplished by removing
408       // the empty line we started, and instead appending the whitespace
409       // and following characters to the previous line.
410       client_headers_.pop_back();
411       header = &client_headers_.back();
412       header->append("\r\n");
413     }
414 
415     if (header->length() >= kMaxHeaderSize) {
416       SendClientError(500, kInternalErrorMsg);
417       return false;
418     }
419     header->push_back(*ptr);
420   }
421 
422   // Return the remaining data to the caller -- this could be POST data
423   // or other non-header data sent with the client request.
424   data->buf = ptr;
425   data->len = end - ptr;
426 
427   return true;
428 }
429 
430 // Finds the URL in the first line of an HTTP client header, and extracts
431 // and removes the hostname (and port) from the URL.  Returns false if a
432 // parse error occurs, and true otherwise (whether or not the hostname was
433 // found).
ReadClientHostname(string * header)434 bool HTTPProxy::ReadClientHostname(string* header) {
435   const string http_url_prefix(kHTTPURLPrefix);
436   size_t url_idx = header->find(http_url_prefix);
437   if (url_idx != string::npos) {
438     size_t host_start = url_idx + http_url_prefix.length();
439     size_t host_end =
440       header->find_first_of(kHTTPURLDelimiters, host_start);
441     if (host_end != string::npos) {
442       server_hostname_ = header->substr(host_start,
443                                         host_end - host_start);
444       // Modify the URL passed upstream to remove "http://<hostname>".
445       header->erase(url_idx, host_end - url_idx);
446       if ((*header)[url_idx] != '/') {
447         header->insert(url_idx, "/");
448       }
449     } else {
450       LOG(ERROR) << "Could not find end of hostname in request.  Line was: "
451                  << *header;
452       SendClientError(500, kInternalErrorMsg);
453       return false;
454     }
455   }
456   return true;
457 }
458 
ReadClientHTTPMethod(string * header)459 bool HTTPProxy::ReadClientHTTPMethod(string* header) {
460   size_t method_end = header->find(kHTTPMethodTerminator);
461   if (method_end == string::npos || method_end == 0) {
462     LOG(ERROR) << "Could not parse HTTP method.  Line was: " << *header;
463     SendClientError(501, "Server could not parse HTTP method");
464     return false;
465   }
466   client_method_ = header->substr(0, method_end);
467   return true;
468 }
469 
470 // Extract the HTTP version number from the first line of the client headers.
471 // Returns true if found.
ReadClientHTTPVersion(string * header)472 bool HTTPProxy::ReadClientHTTPVersion(string* header) {
473   const string http_version_prefix(kHTTPVersionPrefix);
474   size_t http_ver_pos = header->find(http_version_prefix);
475   if (http_ver_pos != string::npos) {
476     client_version_ =
477       header->substr(http_ver_pos + http_version_prefix.length() - 1);
478   } else {
479     SendClientError(501, "Server only accepts HTTP/1.x requests");
480     return false;
481   }
482   return true;
483 }
484 
485 // IOInputHandler callback that fires when data is read from the client.
486 // This could be header data, or perhaps POST data that follows the headers.
ReadFromClient(InputData * data)487 void HTTPProxy::ReadFromClient(InputData* data) {
488   SLOG(connection_.get(), 3) << "In " << __func__ << " length " << data->len;
489 
490   if (data->len == 0) {
491     // EOF from client.
492     StopClient();
493     return;
494   }
495 
496   if (state_ == kStateReadClientHeader) {
497     if (!ReadClientHeaders(data)) {
498       return;
499     }
500     if (state_ == kStateReadClientHeader) {
501       // Still consuming client headers; restart the input timer.
502       StartIdleTimeout();
503       return;
504     }
505   }
506 
507   // Check data->len again since ReadClientHeaders() may have consumed some
508   // part of it.
509   if (data->len != 0) {
510     // The client sent some information after its headers.  Buffer the client
511     // input and temporarily disable input events from the client.
512     client_data_.Append(ByteString(data->buf, data->len));
513     read_client_handler_->Stop();
514     StartTransmit();
515   }
516 }
517 
518 // IOInputHandler callback which fires when data has been read from the
519 // server.
ReadFromServer(InputData * data)520 void HTTPProxy::ReadFromServer(InputData* data) {
521   SLOG(connection_.get(), 3) << "In " << __func__ << " length " << data->len;
522   if (data->len == 0) {
523     // Server closed connection.
524     if (server_data_.IsEmpty()) {
525       StopClient();
526       return;
527     }
528     state_ = kStateFlushResponse;
529   } else {
530     read_server_handler_->Stop();
531   }
532 
533   server_data_.Append(ByteString(data->buf, data->len));
534 
535   StartTransmit();
536 }
537 
538 // Return an HTTP error message back to the client.
SendClientError(int code,const string & error)539 void HTTPProxy::SendClientError(int code, const string& error) {
540   SLOG(connection_.get(), 3) << "In " << __func__;
541   LOG(ERROR) << "Sending error " << error;
542   SetClientResponse(code, "ERROR", "text/plain", error);
543   state_ = kStateFlushResponse;
544   StartTransmit();
545 }
546 
547 // Create an HTTP response message to be sent to the client.
SetClientResponse(int code,const string & type,const string & content_type,const string & message)548 void HTTPProxy::SetClientResponse(int code, const string& type,
549                                   const string& content_type,
550                                   const string& message) {
551   string content_line;
552   if (!message.empty() && !content_type.empty()) {
553     content_line = StringPrintf("Content-Type: %s\r\n", content_type.c_str());
554   }
555   string response = StringPrintf("HTTP/1.1 %d %s\r\n"
556                                  "%s\r\n"
557                                  "%s", code, type.c_str(),
558                                  content_line.c_str(),
559                                  message.c_str());
560   server_data_ = ByteString(response, false);
561 }
562 
563 // Start a timeout for "the next event".  This timeout augments the overall
564 // transaction timeout to make sure there is some activity occurring at
565 // reasonable intervals.
StartIdleTimeout()566 void HTTPProxy::StartIdleTimeout() {
567   int timeout_seconds = 0;
568   switch (state_) {
569     case kStateReadClientHeader:
570       timeout_seconds = kClientHeaderTimeoutSeconds;
571       break;
572     case kStateConnectServer:
573       timeout_seconds = kConnectTimeoutSeconds;
574       break;
575     case kStateLookupServer:
576       // DNSClient has its own internal timeout, so we need not set one here.
577       timeout_seconds = 0;
578       break;
579     default:
580       timeout_seconds = kInputTimeoutSeconds;
581       break;
582   }
583   idle_timeout_.Cancel();
584   if (timeout_seconds != 0) {
585     idle_timeout_.Reset(Bind(&HTTPProxy::StopClient,
586                              weak_ptr_factory_.GetWeakPtr()));
587     dispatcher_->PostDelayedTask(idle_timeout_.callback(),
588                                  timeout_seconds * 1000);
589   }
590 }
591 
592 // Start the various input handlers.  Listen for new data only if we have
593 // completely written the last data we've received to the other end.
StartReceive()594 void HTTPProxy::StartReceive() {
595   if (state_ == kStateTunnelData && client_data_.IsEmpty()) {
596     read_client_handler_->Start();
597   }
598   if (server_data_.IsEmpty()) {
599     if (state_ == kStateTunnelData) {
600       if (read_server_handler_.get()) {
601         read_server_handler_->Start();
602       } else {
603         read_server_handler_.reset(dispatcher_->CreateInputHandler(
604             server_socket_,
605             read_server_callback_,
606             Bind(&HTTPProxy::OnReadError, weak_ptr_factory_.GetWeakPtr())));
607       }
608     } else if (state_ == kStateFlushResponse) {
609       StopClient();
610       return;
611     }
612   }
613   StartIdleTimeout();
614 }
615 
616 // Start the various output-ready handlers for the endpoints we have
617 // data waiting for.
StartTransmit()618 void HTTPProxy::StartTransmit() {
619   if (state_ == kStateTunnelData && !client_data_.IsEmpty()) {
620     if (write_server_handler_.get()) {
621       write_server_handler_->Start();
622     } else {
623       write_server_handler_.reset(
624           dispatcher_->CreateReadyHandler(server_socket_,
625                                           IOHandler::kModeOutput,
626                                           write_server_callback_));
627     }
628   }
629   if ((state_ == kStateFlushResponse || state_ == kStateTunnelData) &&
630       !server_data_.IsEmpty()) {
631     if (write_client_handler_.get()) {
632       write_client_handler_->Start();
633     } else {
634       write_client_handler_.reset(
635           dispatcher_->CreateReadyHandler(client_socket_,
636                                           IOHandler::kModeOutput,
637                                           write_client_callback_));
638     }
639   }
640   StartIdleTimeout();
641 }
642 
643 // End the transaction with the current client, restart the IOHandler
644 // which alerts us to new clients connecting.  This function is called
645 // during various error conditions and is a callback for all timeouts.
StopClient()646 void HTTPProxy::StopClient() {
647   SLOG(connection_.get(), 3) << "In " << __func__;
648 
649   if (is_route_requested_) {
650     connection_->ReleaseRouting();
651     is_route_requested_ = false;
652   }
653   write_client_handler_.reset();
654   read_client_handler_.reset();
655   if (client_socket_ != -1) {
656     sockets_->Close(client_socket_);
657     client_socket_ = -1;
658   }
659   client_headers_.clear();
660   client_method_.clear();
661   client_version_.clear();
662   server_port_ = kDefaultServerPort;
663   write_server_handler_.reset();
664   read_server_handler_.reset();
665   if (server_socket_ != -1) {
666     sockets_->Close(server_socket_);
667     server_socket_ = -1;
668   }
669   server_hostname_.clear();
670   client_data_.Clear();
671   server_data_.Clear();
672   dns_client_->Stop();
673   server_async_connection_->Stop();
674   idle_timeout_.Cancel();
675   transaction_timeout_.Cancel();
676   accept_handler_->Start();
677   state_ = kStateWaitConnection;
678 }
679 
680 // Output ReadyHandler callback which fires when the client socket is
681 // ready for data to be sent to it.
WriteToClient(int fd)682 void HTTPProxy::WriteToClient(int fd) {
683   CHECK_EQ(client_socket_, fd);
684   int ret = sockets_->Send(fd, server_data_.GetConstData(),
685                            server_data_.GetLength(), 0);
686   SLOG(connection_.get(), 3) << "In " << __func__ << " wrote " << ret << " of "
687                              << server_data_.GetLength();
688   if (ret < 0) {
689     LOG(ERROR) << "Server write failed";
690     StopClient();
691     return;
692   }
693 
694   server_data_ = ByteString(server_data_.GetConstData() + ret,
695                             server_data_.GetLength() - ret);
696 
697   if (server_data_.IsEmpty()) {
698     write_client_handler_->Stop();
699   }
700 
701   StartReceive();
702 }
703 
704 // Output ReadyHandler callback which fires when the server socket is
705 // ready for data to be sent to it.
WriteToServer(int fd)706 void HTTPProxy::WriteToServer(int fd) {
707   CHECK_EQ(server_socket_, fd);
708   int ret = sockets_->Send(fd, client_data_.GetConstData(),
709                            client_data_.GetLength(), 0);
710   SLOG(connection_.get(), 3) << "In " << __func__ << " wrote " << ret << " of "
711                              << client_data_.GetLength();
712 
713   if (ret < 0) {
714     LOG(ERROR) << "Client write failed";
715     StopClient();
716     return;
717   }
718 
719   client_data_ = ByteString(client_data_.GetConstData() + ret,
720                             client_data_.GetLength() - ret);
721 
722   if (client_data_.IsEmpty()) {
723     write_server_handler_->Stop();
724   }
725 
726   StartReceive();
727 }
728 
729 }  // namespace shill
730