1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_SOCKET_CLIENT_SOCKET_HANDLE_H_
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_SOCKET_CLIENT_SOCKET_HANDLE_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string>
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/time.h"
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/completion_callback.h"
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/load_states.h"
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h"
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/request_priority.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_response_info.h"
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket.h"
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket_pool.h"
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net {
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A container for a ClientSocket.
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The handle's |group_name| uniquely identifies the origin and type of the
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// connection.  It is used by the ClientSocketPool to group similar connected
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// client socket objects.
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ClientSocketHandle {
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  enum SocketReuseType {
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UNUSED = 0,   // unused socket that just finished connecting
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UNUSED_IDLE,  // unused socket that has been idle for awhile
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    REUSED_IDLE,  // previously used socket
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    NUM_TYPES,
3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  };
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ClientSocketHandle();
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ~ClientSocketHandle();
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initializes a ClientSocketHandle object, which involves talking to the
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ClientSocketPool to obtain a connected socket, possibly reusing one.  This
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // method returns either OK or ERR_IO_PENDING.  On ERR_IO_PENDING, |priority|
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is used to determine the placement in ClientSocketPool's wait list.
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If this method succeeds, then the socket member will be set to an existing
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // connected socket if an existing connected socket was available to reuse,
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // otherwise it will be set to a new connected socket.  Consumers can then
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // call is_reused() to see if the socket was reused.  If not reusing an
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // existing socket, ClientSocketPool may need to establish a new
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // connection using |socket_params|.
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This method returns ERR_IO_PENDING if it cannot complete synchronously, in
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // which case the consumer will be notified of completion via |callback|.
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the pool was not able to reuse an existing socket, the new socket
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // may report a recoverable error.  In this case, the return value will
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // indicate an error and the socket member will be set.  If it is determined
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // that the error is not recoverable, the Disconnect method should be used
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // on the socket, so that it does not get reused.
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A non-recoverable error may set additional state in the ClientSocketHandle
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to allow the caller to determine what went wrong.
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Init may be called multiple times.
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Profiling information for the request is saved to |net_log| if non-NULL.
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <typename SocketParams, typename PoolType>
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int Init(const std::string& group_name,
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           const scoped_refptr<SocketParams>& socket_params,
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott           RequestPriority priority,
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott           CompletionCallback* callback,
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick           PoolType* pool,
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           const BoundNetLog& net_log);
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // An initialized handle can be reset, which causes it to return to the
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // un-initialized state.  This releases the underlying socket, which in the
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // case of a socket that still has an established connection, indicates that
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the socket may be kept alive for use by a subsequent ClientSocketHandle.
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // NOTE: To prevent the socket from being kept alive, be sure to call its
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Disconnect method.  This will result in the ClientSocketPool deleting the
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ClientSocket.
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Reset();
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Used after Init() is called, but before the ClientSocketPool has
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // initialized the ClientSocketHandle.
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  LoadState GetLoadState() const;
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns true when Init() has completed successfully.
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool is_initialized() const { return is_initialized_; }
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the time tick when Init() was called.
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::TimeTicks init_time() const { return init_time_; }
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the time between Init() and when is_initialized() becomes true.
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::TimeDelta setup_time() const { return setup_time_; }
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Used by ClientSocketPool to initialize the ClientSocketHandle.
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_is_reused(bool is_reused) { is_reused_ = is_reused; }
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_socket(ClientSocket* s) { socket_.reset(s); }
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_idle_time(base::TimeDelta idle_time) { idle_time_ = idle_time; }
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_pool_id(int id) { pool_id_ = id; }
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_is_ssl_error(bool is_ssl_error) { is_ssl_error_ = is_ssl_error; }
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_ssl_error_response_info(const HttpResponseInfo& ssl_error_state) {
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ssl_error_response_info_ = ssl_error_state;
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void set_pending_http_proxy_connection(ClientSocketHandle* connection) {
1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    pending_http_proxy_connection_.reset(connection);
1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Only valid if there is no |socket_|.
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool is_ssl_error() const {
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(socket_.get() == NULL);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return is_ssl_error_;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // On an ERR_PROXY_AUTH_REQUESTED error, the |headers| and |auth_challenge|
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // fields are filled in. On an ERR_SSL_CLIENT_AUTH_CERT_NEEDED error,
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the |cert_request_info| field is set.
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const HttpResponseInfo& ssl_error_response_info() const {
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ssl_error_response_info_;
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle* release_pending_http_proxy_connection() {
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return pending_http_proxy_connection_.release();
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // These may only be used if is_initialized() is true.
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const std::string& group_name() const { return group_name_; }
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int id() const { return pool_id_; }
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ClientSocket* socket() { return socket_.get(); }
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ClientSocket* release_socket() { return socket_.release(); }
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool is_reused() const { return is_reused_; }
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::TimeDelta idle_time() const { return idle_time_; }
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  SocketReuseType reuse_type() const {
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (is_reused()) {
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return REUSED_IDLE;
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    } else if (idle_time() == base::TimeDelta()) {
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return UNUSED;
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    } else {
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return UNUSED_IDLE;
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Called on asynchronous completion of an Init() request.
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void OnIOComplete(int result);
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Called on completion (both asynchronous & synchronous) of an Init()
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // request.
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void HandleInitCompletion(int result);
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Resets the state of the ClientSocketHandle.  |cancel| indicates whether or
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // not to try to cancel the request with the ClientSocketPool.  Does not
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // reset the supplemental error state.
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void ResetInternal(bool cancel);
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Resets the supplemental error state.
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ResetErrorState();
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool is_initialized_;
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketPool* pool_;
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<ClientSocket> socket_;
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string group_name_;
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool is_reused_;
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CompletionCallbackImpl<ClientSocketHandle> callback_;
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CompletionCallback* user_callback_;
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::TimeDelta idle_time_;
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int pool_id_;  // See ClientSocketPool::ReleaseSocket() for an explanation.
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool is_ssl_error_;
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HttpResponseInfo ssl_error_response_info_;
1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<ClientSocketHandle> pending_http_proxy_connection_;
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::TimeTicks init_time_;
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::TimeDelta setup_time_;
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetLog::Source requesting_source_;
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(ClientSocketHandle);
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Template function implementation:
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename SocketParams, typename PoolType>
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint ClientSocketHandle::Init(const std::string& group_name,
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const scoped_refptr<SocketParams>& socket_params,
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                             RequestPriority priority,
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                             CompletionCallback* callback,
1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             PoolType* pool,
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const BoundNetLog& net_log) {
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  requesting_source_ = net_log.source();
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CHECK(!group_name.empty());
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that this will result in a compile error if the SocketParams has not
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // been registered for the PoolType via REGISTER_SOCKET_PARAMS_FOR_POOL
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (defined in client_socket_pool.h).
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CheckIsValidSocketParamsForPool<PoolType, SocketParams>();
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ResetInternal(true);
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResetErrorState();
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pool_ = pool;
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  group_name_ = group_name;
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  init_time_ = base::TimeTicks::Now();
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = pool_->RequestSocket(
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      group_name, &socket_params, priority, this, &callback_, net_log);
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv == ERR_IO_PENDING) {
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    user_callback_ = callback;
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else {
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    HandleInitCompletion(rv);
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return rv;
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // NET_SOCKET_CLIENT_SOCKET_HANDLE_H_
217