blob: 350a7224475876ff3e06d6e8dcc85c0c9fbd793e [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_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_
#define NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_
#include <memory>
#include "base/memory/weak_ptr.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_export.h"
#include "net/spdy/spdy_read_queue.h"
#include "net/spdy/spdy_stream.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/websockets/websocket_basic_stream.h"
namespace net {
class ClientSocketHandle;
class IOBuffer;
class SpdyBuffer;
// Trivial adapter to make WebSocketBasicStream use a TCP/IP or TLS socket.
class NET_EXPORT_PRIVATE WebSocketClientSocketHandleAdapter
: public WebSocketBasicStream::Adapter {
public:
WebSocketClientSocketHandleAdapter() = delete;
explicit WebSocketClientSocketHandleAdapter(
std::unique_ptr<ClientSocketHandle> connection);
~WebSocketClientSocketHandleAdapter() override;
int Read(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) override;
int Write(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback,
const NetworkTrafficAnnotationTag& traffic_annotation) override;
void Disconnect() override;
bool is_initialized() const override;
private:
std::unique_ptr<ClientSocketHandle> connection_;
};
// Adapter to make WebSocketBasicStream use an HTTP/2 stream.
// Sets itself as a delegate of the SpdyStream, and forwards headers-related
// methods to WebSocketHttp2HandshakeStream, which implements
// WebSocketSpdyStreamAdapter::Delegate. After the handshake, ownership of this
// object can be passed to WebSocketBasicStream, which can read and write using
// a ClientSocketHandle-like interface.
class NET_EXPORT_PRIVATE WebSocketSpdyStreamAdapter
: public WebSocketBasicStream::Adapter,
public SpdyStream::Delegate {
public:
// Interface for forwarding SpdyStream::Delegate methods necessary for the
// handshake.
class Delegate {
public:
virtual ~Delegate() = default;
virtual void OnHeadersSent() = 0;
virtual void OnHeadersReceived(
const spdy::SpdyHeaderBlock& response_headers) = 0;
// Might destroy |this|.
virtual void OnClose(int status) = 0;
};
// |delegate| must be valid until DetachDelegate() is called.
WebSocketSpdyStreamAdapter(base::WeakPtr<SpdyStream> stream,
Delegate* delegate,
NetLogWithSource net_log);
~WebSocketSpdyStreamAdapter() override;
// Called by WebSocketSpdyStreamAdapter::Delegate before it is destroyed.
void DetachDelegate();
// WebSocketBasicStream::Adapter methods.
int Read(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) override;
// Write() must not be called before Delegate::OnHeadersSent() is called.
// Write() always returns asynchronously.
int Write(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback,
const NetworkTrafficAnnotationTag& traffic_annotation) override;
void Disconnect() override;
bool is_initialized() const override;
// SpdyStream::Delegate methods.
void OnHeadersSent() override;
void OnHeadersReceived(
const spdy::SpdyHeaderBlock& response_headers,
const spdy::SpdyHeaderBlock* pushed_request_headers) override;
void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override;
void OnDataSent() override;
void OnTrailers(const spdy::SpdyHeaderBlock& trailers) override;
void OnClose(int status) override;
NetLogSource source_dependency() const override;
private:
// Copy data from read_data_ to read_buffer_.
int CopySavedReadDataIntoBuffer();
// Call WebSocketSpdyStreamAdapter::Delegate::OnClose().
void CallDelegateOnClose();
// True if SpdyStream::Delegate::OnHeadersSent() has been called.
// SpdyStream::SendData() must not be called before that.
bool headers_sent_;
// The underlying SpdyStream.
base::WeakPtr<SpdyStream> stream_;
// The error code with which SpdyStream was closed.
int stream_error_;
Delegate* delegate_;
// Buffer data pushed by SpdyStream until read through Read().
SpdyReadQueue read_data_;
// Read buffer and length used for both synchronous and asynchronous
// read operations.
IOBuffer* read_buffer_;
size_t read_length_;
// Read callback saved for asynchronous reads.
// Whenever |read_data_| is not empty, |read_callback_| must be null.
CompletionOnceCallback read_callback_;
// Write length saved to be passed to |write_callback_|. This is necessary
// because SpdyStream::Delegate::OnDataSent() does not pass number of bytes
// written.
int write_length_;
// Write callback saved for asynchronous writes (all writes are asynchronous).
CompletionOnceCallback write_callback_;
NetLogWithSource net_log_;
base::WeakPtrFactory<WebSocketSpdyStreamAdapter> weak_factory_;
};
} // namespace net
#endif // NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_