1// Copyright (c) 2011 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.
4
5#ifndef NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_
6#define NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_
7#pragma once
8
9#include <string>
10#include <list>
11
12#include "base/basictypes.h"
13#include "base/memory/ref_counted.h"
14#include "net/base/completion_callback.h"
15#include "net/base/host_port_pair.h"
16#include "net/base/net_log.h"
17#include "net/http/http_auth_controller.h"
18#include "net/http/http_request_headers.h"
19#include "net/http/http_request_info.h"
20#include "net/http/http_response_info.h"
21#include "net/http/proxy_client_socket.h"
22#include "net/spdy/spdy_http_stream.h"
23#include "net/spdy/spdy_protocol.h"
24#include "net/spdy/spdy_session.h"
25#include "net/spdy/spdy_stream.h"
26
27
28class GURL;
29
30namespace net {
31
32class AddressList;
33class ClientSocketHandle;
34class HttpStream;
35class IOBuffer;
36class SpdySession;
37class SpdyStream;
38
39class SpdyProxyClientSocket : public ProxyClientSocket,
40                              public SpdyStream::Delegate {
41 public:
42  // Create a socket on top of the |spdy_stream| by sending a SYN_STREAM
43  // CONNECT frame for |endpoint|.  After the SYN_REPLY is received,
44  // any data read/written to the socket will be transferred in data
45  // frames.
46  SpdyProxyClientSocket(SpdyStream* spdy_stream,
47                        const std::string& user_agent,
48                        const HostPortPair& endpoint,
49                        const GURL& url,
50                        const HostPortPair& proxy_server,
51                        HttpAuthCache* auth_cache,
52                        HttpAuthHandlerFactory* auth_handler_factory);
53
54
55  // On destruction Disconnect() is called.
56  virtual ~SpdyProxyClientSocket();
57
58  const scoped_refptr<HttpAuthController>& auth_controller() {
59    return auth_;
60  }
61
62  // ProxyClientSocket methods:
63  virtual const HttpResponseInfo* GetConnectResponseInfo() const;
64
65  // In the event of a non-200 response to the CONNECT request, this
66  // method may be called to return an HttpStream in order to read
67  // the response body.
68  virtual HttpStream* CreateConnectResponseStream();
69
70  // ClientSocket methods:
71#ifdef ANDROID
72  virtual int Connect(CompletionCallback* callback, bool wait_for_connect,
73                        bool valid_uid, uid_t calling_uid);
74#else
75  virtual int Connect(CompletionCallback* callback);
76#endif
77  virtual void Disconnect();
78  virtual bool IsConnected() const;
79  virtual bool IsConnectedAndIdle() const;
80  virtual const BoundNetLog& NetLog() const;
81  virtual void SetSubresourceSpeculation();
82  virtual void SetOmniboxSpeculation();
83  virtual bool WasEverUsed() const;
84  virtual bool UsingTCPFastOpen() const;
85
86  // Socket methods:
87  virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
88  virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback);
89  virtual bool SetReceiveBufferSize(int32 size);
90  virtual bool SetSendBufferSize(int32 size);
91  virtual int GetPeerAddress(AddressList* address) const;
92  virtual int GetLocalAddress(IPEndPoint* address) const;
93
94  // SpdyStream::Delegate methods:
95  virtual bool OnSendHeadersComplete(int status);
96  virtual int OnSendBody();
97  virtual int OnSendBodyComplete(int status, bool* eof);
98  virtual int OnResponseReceived(const spdy::SpdyHeaderBlock& response,
99                                 base::Time response_time,
100                                 int status);
101  virtual void OnDataReceived(const char* data, int length);
102  virtual void OnDataSent(int length);
103  virtual void OnClose(int status);
104  virtual void set_chunk_callback(ChunkCallback* /*callback*/);
105
106 private:
107  enum State {
108    STATE_DISCONNECTED,
109    STATE_GENERATE_AUTH_TOKEN,
110    STATE_GENERATE_AUTH_TOKEN_COMPLETE,
111    STATE_SEND_REQUEST,
112    STATE_SEND_REQUEST_COMPLETE,
113    STATE_READ_REPLY_COMPLETE,
114    STATE_OPEN,
115    STATE_CLOSED
116  };
117
118  void OnIOComplete(int result);
119
120  int DoLoop(int last_io_result);
121  int DoGenerateAuthToken();
122  int DoGenerateAuthTokenComplete(int result);
123  int DoSendRequest();
124  int DoSendRequestComplete(int result);
125  int DoReadReplyComplete(int result);
126
127  // Populates |user_buffer_| with as much read data as possible
128  // and returns the number of bytes read.
129  int PopulateUserReadBuffer();
130
131  CompletionCallbackImpl<SpdyProxyClientSocket> io_callback_;
132  State next_state_;
133
134  // Pointer to the SPDY Stream that this sits on top of.
135  scoped_refptr<SpdyStream> spdy_stream_;
136
137  // Stores the callback to the layer above, called on completing Read() or
138  // Connect().
139  CompletionCallback* read_callback_;
140  // Stores the callback to the layer above, called on completing Write().
141  CompletionCallback* write_callback_;
142
143  // CONNECT request and response.
144  HttpRequestInfo request_;
145  HttpResponseInfo response_;
146
147  // The hostname and port of the endpoint.  This is not necessarily the one
148  // specified by the URL, due to Alternate-Protocol or fixed testing ports.
149  const HostPortPair endpoint_;
150  scoped_refptr<HttpAuthController> auth_;
151
152  // We buffer the response body as it arrives asynchronously from the stream.
153  std::list<scoped_refptr<DrainableIOBuffer> > read_buffer_;
154
155  // User provided buffer for the Read() response.
156  scoped_refptr<DrainableIOBuffer> user_buffer_;
157
158  // User specified number of bytes to be written.
159  int write_buffer_len_;
160  // Number of bytes written which have not been confirmed
161  int write_bytes_outstanding_;
162
163  // True if read has ever returned zero for eof.
164  bool eof_has_been_read_;
165  // True if the transport socket has ever sent data.
166  bool was_ever_used_;
167
168  scoped_ptr<SpdyHttpStream> response_stream_;
169
170  const BoundNetLog net_log_;
171
172  DISALLOW_COPY_AND_ASSIGN(SpdyProxyClientSocket);
173};
174
175}  // namespace net
176
177#endif  // NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_
178