tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

data_socket.h (4450B)


      1 /*
      2 *  Copyright 2011 The WebRTC Project Authors. All rights reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #ifndef EXAMPLES_PEERCONNECTION_SERVER_DATA_SOCKET_H_
     12 #define EXAMPLES_PEERCONNECTION_SERVER_DATA_SOCKET_H_
     13 
     14 #include <cstddef>
     15 #include <string>
     16 
     17 
     18 #ifdef WIN32
     19 #include <winsock2.h>
     20 typedef int socklen_t;
     21 typedef SOCKET NativeSocket;
     22 #else
     23 #define closesocket close
     24 typedef int NativeSocket;
     25 
     26 #ifndef SOCKET_ERROR
     27 #define SOCKET_ERROR (-1)
     28 #endif
     29 
     30 #ifndef INVALID_SOCKET
     31 #define INVALID_SOCKET static_cast<NativeSocket>(-1)
     32 #endif
     33 #endif
     34 
     35 class SocketBase {
     36 public:
     37  SocketBase() : socket_(INVALID_SOCKET) {}
     38  explicit SocketBase(NativeSocket socket) : socket_(socket) {}
     39  SocketBase(SocketBase& other) = delete;
     40  SocketBase& operator=(const SocketBase& other) = delete;
     41  ~SocketBase() { Close(); }
     42 
     43  NativeSocket socket() const { return socket_; }
     44  bool valid() const { return socket_ != INVALID_SOCKET; }
     45 
     46  bool Create();
     47  void Close();
     48 
     49 protected:
     50  NativeSocket socket_;
     51 };
     52 
     53 // Represents an HTTP server socket.
     54 class DataSocket : public SocketBase {
     55 public:
     56  enum RequestMethod {
     57    INVALID,
     58    GET,
     59    POST,
     60    OPTIONS,
     61  };
     62 
     63  explicit DataSocket(NativeSocket socket)
     64      : SocketBase(socket), method_(INVALID), content_length_(0) {}
     65 
     66  ~DataSocket() {}
     67 
     68  static const char kCrossOriginAllowHeaders[];
     69 
     70  bool headers_received() const { return method_ != INVALID; }
     71 
     72  RequestMethod method() const { return method_; }
     73 
     74  const std::string& request_path() const { return request_path_; }
     75  std::string request_arguments() const;
     76 
     77  const std::string& data() const { return data_; }
     78 
     79  const std::string& content_type() const { return content_type_; }
     80 
     81  size_t content_length() const { return content_length_; }
     82 
     83  bool request_received() const {
     84    return headers_received() && (method_ != POST || data_received());
     85  }
     86 
     87  bool data_received() const {
     88    return method_ != POST || data_.length() >= content_length_;
     89  }
     90 
     91  // Checks if the request path (minus arguments) matches a given path.
     92  bool PathEquals(const char* path) const;
     93 
     94  // Called when we have received some data from clients.
     95  // Returns false if an error occurred.
     96  bool OnDataAvailable(bool* close_socket);
     97 
     98  // Send a raw buffer of bytes.
     99  bool Send(const std::string& data) const;
    100 
    101  // Send an HTTP response.  The `status` should start with a valid HTTP
    102  // response code, followed by a string.  E.g. "200 OK".
    103  // If `connection_close` is set to true, an extra "Connection: close" HTTP
    104  // header will be included.  `content_type` is the mime content type, not
    105  // including the "Content-Type: " string.
    106  // `extra_headers` should be either empty or a list of headers where each
    107  // header terminates with "\r\n".
    108  // `data` is the body of the message.  It's length will be specified via
    109  // a "Content-Length" header.
    110  bool Send(const std::string& status,
    111            bool connection_close,
    112            const std::string& content_type,
    113            const std::string& extra_headers,
    114            const std::string& data) const;
    115 
    116  // Clears all held state and prepares the socket for receiving a new request.
    117  void Clear();
    118 
    119 protected:
    120  // A fairly relaxed HTTP header parser.  Parses the method, path and
    121  // content length (POST only) of a request.
    122  // Returns true if a valid request was received and no errors occurred.
    123  bool ParseHeaders();
    124 
    125  // Figures out whether the request is a GET or POST and what path is
    126  // being requested.
    127  bool ParseMethodAndPath(const char* begin, size_t len);
    128 
    129  // Determines the length of the body and it's mime type.
    130  bool ParseContentLengthAndType(const char* headers, size_t length);
    131 
    132 protected:
    133  RequestMethod method_;
    134  size_t content_length_;
    135  std::string content_type_;
    136  std::string request_path_;
    137  std::string request_headers_;
    138  std::string data_;
    139 };
    140 
    141 // The server socket.  Accepts connections and generates DataSocket instances
    142 // for each new connection.
    143 class ListeningSocket : public SocketBase {
    144 public:
    145  ListeningSocket() {}
    146 
    147  bool Listen(unsigned short port);
    148  DataSocket* Accept() const;
    149 };
    150 
    151 #endif  // EXAMPLES_PEERCONNECTION_SERVER_DATA_SOCKET_H_