data_socket.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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. #ifndef EXAMPLES_PEERCONNECTION_SERVER_DATA_SOCKET_H_
  11. #define EXAMPLES_PEERCONNECTION_SERVER_DATA_SOCKET_H_
  12. #ifdef WIN32
  13. #include <winsock2.h>
  14. typedef int socklen_t;
  15. typedef SOCKET NativeSocket;
  16. #else
  17. #include <netinet/in.h>
  18. #include <sys/select.h>
  19. #include <sys/socket.h>
  20. #define closesocket close
  21. typedef int NativeSocket;
  22. #ifndef SOCKET_ERROR
  23. #define SOCKET_ERROR (-1)
  24. #endif
  25. #ifndef INVALID_SOCKET
  26. #define INVALID_SOCKET static_cast<NativeSocket>(-1)
  27. #endif
  28. #endif
  29. #include <string>
  30. class SocketBase {
  31. public:
  32. SocketBase() : socket_(INVALID_SOCKET) {}
  33. explicit SocketBase(NativeSocket socket) : socket_(socket) {}
  34. ~SocketBase() { Close(); }
  35. NativeSocket socket() const { return socket_; }
  36. bool valid() const { return socket_ != INVALID_SOCKET; }
  37. bool Create();
  38. void Close();
  39. protected:
  40. NativeSocket socket_;
  41. };
  42. // Represents an HTTP server socket.
  43. class DataSocket : public SocketBase {
  44. public:
  45. enum RequestMethod {
  46. INVALID,
  47. GET,
  48. POST,
  49. OPTIONS,
  50. };
  51. explicit DataSocket(NativeSocket socket)
  52. : SocketBase(socket), method_(INVALID), content_length_(0) {}
  53. ~DataSocket() {}
  54. static const char kCrossOriginAllowHeaders[];
  55. bool headers_received() const { return method_ != INVALID; }
  56. RequestMethod method() const { return method_; }
  57. const std::string& request_path() const { return request_path_; }
  58. std::string request_arguments() const;
  59. const std::string& data() const { return data_; }
  60. const std::string& content_type() const { return content_type_; }
  61. size_t content_length() const { return content_length_; }
  62. bool request_received() const {
  63. return headers_received() && (method_ != POST || data_received());
  64. }
  65. bool data_received() const {
  66. return method_ != POST || data_.length() >= content_length_;
  67. }
  68. // Checks if the request path (minus arguments) matches a given path.
  69. bool PathEquals(const char* path) const;
  70. // Called when we have received some data from clients.
  71. // Returns false if an error occurred.
  72. bool OnDataAvailable(bool* close_socket);
  73. // Send a raw buffer of bytes.
  74. bool Send(const std::string& data) const;
  75. // Send an HTTP response. The |status| should start with a valid HTTP
  76. // response code, followed by a string. E.g. "200 OK".
  77. // If |connection_close| is set to true, an extra "Connection: close" HTTP
  78. // header will be included. |content_type| is the mime content type, not
  79. // including the "Content-Type: " string.
  80. // |extra_headers| should be either empty or a list of headers where each
  81. // header terminates with "\r\n".
  82. // |data| is the body of the message. It's length will be specified via
  83. // a "Content-Length" header.
  84. bool Send(const std::string& status,
  85. bool connection_close,
  86. const std::string& content_type,
  87. const std::string& extra_headers,
  88. const std::string& data) const;
  89. // Clears all held state and prepares the socket for receiving a new request.
  90. void Clear();
  91. protected:
  92. // A fairly relaxed HTTP header parser. Parses the method, path and
  93. // content length (POST only) of a request.
  94. // Returns true if a valid request was received and no errors occurred.
  95. bool ParseHeaders();
  96. // Figures out whether the request is a GET or POST and what path is
  97. // being requested.
  98. bool ParseMethodAndPath(const char* begin, size_t len);
  99. // Determines the length of the body and it's mime type.
  100. bool ParseContentLengthAndType(const char* headers, size_t length);
  101. protected:
  102. RequestMethod method_;
  103. size_t content_length_;
  104. std::string content_type_;
  105. std::string request_path_;
  106. std::string request_headers_;
  107. std::string data_;
  108. };
  109. // The server socket. Accepts connections and generates DataSocket instances
  110. // for each new connection.
  111. class ListeningSocket : public SocketBase {
  112. public:
  113. ListeningSocket() {}
  114. bool Listen(unsigned short port);
  115. DataSocket* Accept() const;
  116. };
  117. #endif // EXAMPLES_PEERCONNECTION_SERVER_DATA_SOCKET_H_