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.
4
5#ifndef NET_HTTP_HTTP_STREAM_FACTORY_IMPL_REQUEST_H_
6#define NET_HTTP_HTTP_STREAM_FACTORY_IMPL_REQUEST_H_
7
8#include <set>
9#include "base/memory/scoped_ptr.h"
10#include "net/base/net_log.h"
11#include "net/http/http_stream_factory_impl.h"
12#include "net/socket/ssl_client_socket.h"
13#include "net/spdy/spdy_session_key.h"
14#include "url/gurl.h"
15
16namespace net {
17
18class ClientSocketHandle;
19class HttpStream;
20class SpdySession;
21
22class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
23 public:
24  Request(const GURL& url,
25          HttpStreamFactoryImpl* factory,
26          HttpStreamRequest::Delegate* delegate,
27          WebSocketHandshakeStreamBase::CreateHelper*
28              websocket_handshake_stream_create_helper,
29          const BoundNetLog& net_log);
30  virtual ~Request();
31
32  // The GURL from the HttpRequestInfo the started the Request.
33  const GURL& url() const { return url_; }
34
35  // Called when the Job determines the appropriate |spdy_session_key| for the
36  // Request. Note that this does not mean that SPDY is necessarily supported
37  // for this SpdySessionKey, since we may need to wait for NPN to complete
38  // before knowing if SPDY is available.
39  void SetSpdySessionKey(const SpdySessionKey& spdy_session_key);
40  bool HasSpdySessionKey() const;
41
42  // Attaches |job| to this request. Does not mean that Request will use |job|,
43  // but Request will own |job|.
44  void AttachJob(HttpStreamFactoryImpl::Job* job);
45
46  // Marks completion of the request. Must be called before OnStreamReady().
47  // |job_net_log| is the BoundNetLog of the Job that fulfilled this request.
48  void Complete(bool was_npn_negotiated,
49                NextProto protocol_negotiated,
50                bool using_spdy,
51                const BoundNetLog& job_net_log);
52
53  // If this Request has a |spdy_session_key_|, remove this session from the
54  // SpdySessionRequestMap.
55  void RemoveRequestFromSpdySessionRequestMap();
56
57  // Called by an attached Job if it sets up a SpdySession.
58  void OnNewSpdySessionReady(Job* job,
59                             scoped_ptr<HttpStream> stream,
60                             const base::WeakPtr<SpdySession>& spdy_session,
61                             bool direct);
62
63  WebSocketHandshakeStreamBase::CreateHelper*
64  websocket_handshake_stream_create_helper() {
65    return websocket_handshake_stream_create_helper_;
66  }
67
68  // HttpStreamRequest::Delegate methods which we implement. Note we don't
69  // actually subclass HttpStreamRequest::Delegate.
70
71  void OnStreamReady(Job* job,
72                     const SSLConfig& used_ssl_config,
73                     const ProxyInfo& used_proxy_info,
74                     HttpStreamBase* stream);
75  void OnWebSocketHandshakeStreamReady(Job* job,
76                                       const SSLConfig& used_ssl_config,
77                                       const ProxyInfo& used_proxy_info,
78                                       WebSocketHandshakeStreamBase* stream);
79  void OnStreamFailed(Job* job, int status, const SSLConfig& used_ssl_config);
80  void OnCertificateError(Job* job,
81                          int status,
82                          const SSLConfig& used_ssl_config,
83                          const SSLInfo& ssl_info);
84  void OnNeedsProxyAuth(Job* job,
85                        const HttpResponseInfo& proxy_response,
86                        const SSLConfig& used_ssl_config,
87                        const ProxyInfo& used_proxy_info,
88                        HttpAuthController* auth_controller);
89  void OnNeedsClientAuth(Job* job,
90                         const SSLConfig& used_ssl_config,
91                         SSLCertRequestInfo* cert_info);
92  void OnHttpsProxyTunnelResponse(
93      Job *job,
94      const HttpResponseInfo& response_info,
95      const SSLConfig& used_ssl_config,
96      const ProxyInfo& used_proxy_info,
97      HttpStreamBase* stream);
98
99  // HttpStreamRequest methods.
100
101  virtual int RestartTunnelWithProxyAuth(
102      const AuthCredentials& credentials) OVERRIDE;
103  virtual void SetPriority(RequestPriority priority) OVERRIDE;
104  virtual LoadState GetLoadState() const OVERRIDE;
105  virtual bool was_npn_negotiated() const OVERRIDE;
106  virtual NextProto protocol_negotiated() const OVERRIDE;
107  virtual bool using_spdy() const OVERRIDE;
108
109 private:
110  // Used to orphan all jobs in |jobs_| other than |job| which becomes "bound"
111  // to the request.
112  void OrphanJobsExcept(Job* job);
113
114  // Used to orphan all jobs in |jobs_|.
115  void OrphanJobs();
116
117  // Called when a Job succeeds.
118  void OnJobSucceeded(Job* job);
119
120  const GURL url_;
121  HttpStreamFactoryImpl* const factory_;
122  WebSocketHandshakeStreamBase::CreateHelper* const
123      websocket_handshake_stream_create_helper_;
124  HttpStreamRequest::Delegate* const delegate_;
125  const BoundNetLog net_log_;
126
127  // At the point where Job is irrevocably tied to the Request, we set this.
128  scoped_ptr<Job> bound_job_;
129  std::set<HttpStreamFactoryImpl::Job*> jobs_;
130  scoped_ptr<const SpdySessionKey> spdy_session_key_;
131
132  bool completed_;
133  bool was_npn_negotiated_;
134  // Protocol negotiated with the server.
135  NextProto protocol_negotiated_;
136  bool using_spdy_;
137
138  DISALLOW_COPY_AND_ASSIGN(Request);
139};
140
141}  // namespace net
142
143#endif  // NET_HTTP_HTTP_STREAM_FACTORY_IMPL_REQUEST_H_
144