blob: d798899c2159350027517c7fa3e1344142cc6504 [file] [log] [blame]
// Copyright 2018 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.
#ifndef NET_SOCKET_CONNECT_JOB_H_
#define NET_SOCKET_CONNECT_JOB_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/load_states.h"
#include "net/base/load_timing_info.h"
#include "net/base/net_export.h"
#include "net/base/request_priority.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/socket_tag.h"
namespace net {
class ClientSocketHandle;
class StreamSocket;
// ConnectJob provides an abstract interface for "connecting" a socket.
// The connection may involve host resolution, tcp connection, ssl connection,
// etc.
class NET_EXPORT_PRIVATE ConnectJob {
public:
// Alerts the delegate that the connection completed. |job| must be destroyed
// by the delegate. A std::unique_ptr<> isn't used because the caller of this
// function doesn't own |job|.
class NET_EXPORT_PRIVATE Delegate {
public:
Delegate() {}
virtual ~Delegate() {}
// Alerts the delegate that the connection completed. |job| must be
// destroyed by the delegate. A std::unique_ptr<> isn't used because the
// caller of this function doesn't own |job|.
virtual void OnConnectJobComplete(int result, ConnectJob* job) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
// A |timeout_duration| of 0 corresponds to no timeout. |group_name| is a
// caller-provided opaque string, only used for logging and the corresponding
// accessor.
ConnectJob(const std::string& group_name,
base::TimeDelta timeout_duration,
RequestPriority priority,
const SocketTag& socket_tag,
bool respect_limits,
Delegate* delegate,
const NetLogWithSource& net_log);
virtual ~ConnectJob();
// Accessors
const std::string& group_name() const { return group_name_; }
const NetLogWithSource& net_log() { return net_log_; }
RequestPriority priority() const { return priority_; }
bool respect_limits() const { return respect_limits_; }
// Releases ownership of the underlying socket to the caller. Returns the
// released socket, or nullptr if there was a connection error.
std::unique_ptr<StreamSocket> PassSocket();
void ChangePriority(RequestPriority priority);
// Begins connecting the socket. Returns OK on success, ERR_IO_PENDING if it
// cannot complete synchronously without blocking, or another net error code
// on error. In asynchronous completion, the ConnectJob will notify
// |delegate_| via OnConnectJobComplete. In both asynchronous and synchronous
// completion, ReleaseSocket() can be called to acquire the connected socket
// if it succeeded.
//
// On completion, the ConnectJob must be completed synchronously, since it
// doesn't bother to stop its timer when complete.
int Connect();
virtual LoadState GetLoadState() const = 0;
// If Connect returns an error (or OnConnectJobComplete reports an error
// result) this method will be called, allowing a SocketPool to add additional
// error state to the ClientSocketHandle (post late-binding).
//
// TODO(mmenke): This is a layering violation. Consider refactoring it to not
// depend on ClientSocketHandle. Fixing this will need to wait until after
// proxy tunnel auth has been refactored.
virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {}
const LoadTimingInfo::ConnectTiming& connect_timing() const {
return connect_timing_;
}
const NetLogWithSource& net_log() const { return net_log_; }
protected:
const SocketTag& socket_tag() const { return socket_tag_; }
void SetSocket(std::unique_ptr<StreamSocket> socket);
StreamSocket* socket() { return socket_.get(); }
void NotifyDelegateOfCompletion(int rv);
void ResetTimer(base::TimeDelta remaining_time);
// Connection establishment timing information.
// TODO(mmenke): This should be private.
LoadTimingInfo::ConnectTiming connect_timing_;
private:
virtual int ConnectInternal() = 0;
virtual void ChangePriorityInternal(RequestPriority priority) = 0;
void LogConnectStart();
void LogConnectCompletion(int net_error);
// Alerts the delegate that the ConnectJob has timed out.
void OnTimeout();
const std::string group_name_;
const base::TimeDelta timeout_duration_;
RequestPriority priority_;
const SocketTag socket_tag_;
const bool respect_limits_;
// Timer to abort jobs that take too long.
base::OneShotTimer timer_;
Delegate* delegate_;
std::unique_ptr<StreamSocket> socket_;
NetLogWithSource net_log_;
DISALLOW_COPY_AND_ASSIGN(ConnectJob);
};
} // namespace net
#endif // NET_SOCKET_CONNECT_JOB_H_