/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef RTC_BASE_SOCKETADAPTERS_H_
#define RTC_BASE_SOCKETADAPTERS_H_

#include <string>

#include "rtc_base/asyncsocket.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/cryptstring.h"

namespace rtc {

struct HttpAuthContext;
class ByteBufferReader;
class ByteBufferWriter;

///////////////////////////////////////////////////////////////////////////////

// Implements a socket adapter that can buffer and process data internally,
// as in the case of connecting to a proxy, where you must speak the proxy
// protocol before commencing normal socket behavior.
class BufferedReadAdapter : public AsyncSocketAdapter {
 public:
  BufferedReadAdapter(AsyncSocket* socket, size_t buffer_size);
  ~BufferedReadAdapter() override;

  int Send(const void* pv, size_t cb) override;
  int Recv(void* pv, size_t cb, int64_t* timestamp) override;

 protected:
  int DirectSend(const void* pv, size_t cb) {
    return AsyncSocketAdapter::Send(pv, cb);
  }

  void BufferInput(bool on = true);
  virtual void ProcessInput(char* data, size_t* len) = 0;

  void OnReadEvent(AsyncSocket* socket) override;

 private:
  char* buffer_;
  size_t buffer_size_, data_len_;
  bool buffering_;
  RTC_DISALLOW_COPY_AND_ASSIGN(BufferedReadAdapter);
};

///////////////////////////////////////////////////////////////////////////////

// Interface for implementing proxy server sockets.
class AsyncProxyServerSocket : public BufferedReadAdapter {
 public:
  AsyncProxyServerSocket(AsyncSocket* socket, size_t buffer_size);
  ~AsyncProxyServerSocket() override;
  sigslot::signal2<AsyncProxyServerSocket*, const SocketAddress&>
      SignalConnectRequest;
  virtual void SendConnectResult(int err, const SocketAddress& addr) = 0;
};

///////////////////////////////////////////////////////////////////////////////

// Implements a socket adapter that performs the client side of a
// fake SSL handshake. Used for "ssltcp" P2P functionality.
class AsyncSSLSocket : public BufferedReadAdapter {
 public:
  explicit AsyncSSLSocket(AsyncSocket* socket);

  int Connect(const SocketAddress& addr) override;

 protected:
  void OnConnectEvent(AsyncSocket* socket) override;
  void ProcessInput(char* data, size_t* len) override;
  RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSSLSocket);
};

// Implements a socket adapter that performs the server side of a
// fake SSL handshake. Used when implementing a relay server that does "ssltcp".
class AsyncSSLServerSocket : public BufferedReadAdapter {
 public:
  explicit AsyncSSLServerSocket(AsyncSocket* socket);

 protected:
  void ProcessInput(char* data, size_t* len) override;
  RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSSLServerSocket);
};

///////////////////////////////////////////////////////////////////////////////

// Implements a socket adapter that speaks the HTTP/S proxy protocol.
class AsyncHttpsProxySocket : public BufferedReadAdapter {
 public:
  AsyncHttpsProxySocket(AsyncSocket* socket,
                        const std::string& user_agent,
                        const SocketAddress& proxy,
                        const std::string& username,
                        const CryptString& password);
  ~AsyncHttpsProxySocket() override;

  // If connect is forced, the adapter will always issue an HTTP CONNECT to the
  // target address.  Otherwise, it will connect only if the destination port
  // is not port 80.
  void SetForceConnect(bool force) { force_connect_ = force; }

  int Connect(const SocketAddress& addr) override;
  SocketAddress GetRemoteAddress() const override;
  int Close() override;
  ConnState GetState() const override;

 protected:
  void OnConnectEvent(AsyncSocket* socket) override;
  void OnCloseEvent(AsyncSocket* socket, int err) override;
  void ProcessInput(char* data, size_t* len) override;

  bool ShouldIssueConnect() const;
  void SendRequest();
  void ProcessLine(char* data, size_t len);
  void EndResponse();
  void Error(int error);

 private:
  SocketAddress proxy_, dest_;
  std::string agent_, user_, headers_;
  CryptString pass_;
  bool force_connect_;
  size_t content_length_;
  int defer_error_;
  bool expect_close_;
  enum ProxyState {
    PS_INIT,
    PS_LEADER,
    PS_AUTHENTICATE,
    PS_SKIP_HEADERS,
    PS_ERROR_HEADERS,
    PS_TUNNEL_HEADERS,
    PS_SKIP_BODY,
    PS_TUNNEL,
    PS_WAIT_CLOSE,
    PS_ERROR
  } state_;
  HttpAuthContext* context_;
  std::string unknown_mechanisms_;
  RTC_DISALLOW_COPY_AND_ASSIGN(AsyncHttpsProxySocket);
};

///////////////////////////////////////////////////////////////////////////////

// Implements a socket adapter that speaks the SOCKS proxy protocol.
class AsyncSocksProxySocket : public BufferedReadAdapter {
 public:
  AsyncSocksProxySocket(AsyncSocket* socket,
                        const SocketAddress& proxy,
                        const std::string& username,
                        const CryptString& password);
  ~AsyncSocksProxySocket() override;

  int Connect(const SocketAddress& addr) override;
  SocketAddress GetRemoteAddress() const override;
  int Close() override;
  ConnState GetState() const override;

 protected:
  void OnConnectEvent(AsyncSocket* socket) override;
  void ProcessInput(char* data, size_t* len) override;

  void SendHello();
  void SendConnect();
  void SendAuth();
  void Error(int error);

 private:
  enum State { SS_INIT, SS_HELLO, SS_AUTH, SS_CONNECT, SS_TUNNEL, SS_ERROR };
  State state_;
  SocketAddress proxy_, dest_;
  std::string user_;
  CryptString pass_;
  RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSocksProxySocket);
};

// Implements a proxy server socket for the SOCKS protocol.
class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket {
 public:
  explicit AsyncSocksProxyServerSocket(AsyncSocket* socket);

 private:
  void ProcessInput(char* data, size_t* len) override;
  void DirectSend(const ByteBufferWriter& buf);

  void HandleHello(ByteBufferReader* request);
  void SendHelloReply(uint8_t method);
  void HandleAuth(ByteBufferReader* request);
  void SendAuthReply(uint8_t result);
  void HandleConnect(ByteBufferReader* request);
  void SendConnectResult(int result, const SocketAddress& addr) override;

  void Error(int error);

  static const int kBufferSize = 1024;
  enum State {
    SS_HELLO,
    SS_AUTH,
    SS_CONNECT,
    SS_CONNECT_PENDING,
    SS_TUNNEL,
    SS_ERROR
  };
  State state_;
  RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSocksProxyServerSocket);
};

}  // namespace rtc

#endif  // RTC_BASE_SOCKETADAPTERS_H_
