15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_SOCKET_BUFFERED_WRITE_STREAM_SOCKET_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_SOCKET_BUFFERED_WRITE_STREAM_SOCKET_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/basictypes.h"
93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/stream_socket.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TimeDelta;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AddressList;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GrowableIOBuffer;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IPEndPoint;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A StreamSocket decorator. All functions are passed through to the wrapped
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// socket, except for Write().
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Writes are buffered locally so that multiple Write()s to this class are
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// issued as only one Write() to the wrapped socket. This is useful to force
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// multiple requests to be issued in a single packet, as is needed to trigger
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// edge cases in HTTP pipelining.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that the Write() always returns synchronously. It will either buffer the
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// entire input or return the most recently reported error.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are no bounds on the local buffer size. Use carefully.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE BufferedWriteStreamSocket : public StreamSocket {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  explicit BufferedWriteStreamSocket(scoped_ptr<StreamSocket> socket_to_wrap);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~BufferedWriteStreamSocket();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket interface
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Read(IOBuffer* buf, int buf_len,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const CompletionCallback& callback) OVERRIDE;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Write(IOBuffer* buf, int buf_len,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const CompletionCallback& callback) OVERRIDE;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool SetReceiveBufferSize(int32 size) OVERRIDE;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool SetSendBufferSize(int32 size) OVERRIDE;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StreamSocket interface
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Connect(const CompletionCallback& callback) OVERRIDE;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Disconnect() OVERRIDE;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsConnected() const OVERRIDE;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsConnectedAndIdle() const OVERRIDE;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const BoundNetLog& NetLog() const OVERRIDE;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetSubresourceSpeculation() OVERRIDE;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetOmniboxSpeculation() OVERRIDE;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool WasEverUsed() const OVERRIDE;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool UsingTCPFastOpen() const OVERRIDE;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool WasNpnNegotiated() const OVERRIDE;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual NextProto GetNegotiatedProtocol() const OVERRIDE;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoDelayedWrite();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnIOComplete(int result);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<StreamSocket> wrapped_socket_;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<GrowableIOBuffer> io_buffer_;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<GrowableIOBuffer> backup_buffer_;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool callback_pending_;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool wrapped_write_in_progress_;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error_;
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::WeakPtrFactory<BufferedWriteStreamSocket> weak_factory_;
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BufferedWriteStreamSocket);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_SOCKET_STREAM_SOCKET_H_
84