15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/* 25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle 35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2011, Google Inc. 45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without 65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met: 75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer. 105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer in the documentation 125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * and/or other materials provided with the distribution. 135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 3. The name of the author may not be used to endorse or promote products 145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * derived from this software without specific prior written permission. 155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */ 275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/examples/peerconnection/server/data_socket.h" 295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 30b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org#include <ctype.h> 315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <stdio.h> 325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <stdlib.h> 335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <string.h> 345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(POSIX) 355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <unistd.h> 365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/examples/peerconnection/server/utils.h" 395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kHeaderTerminator[] = "\r\n\r\n"; 415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int kHeaderTerminatorLength = sizeof(kHeaderTerminator) - 1; 425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// static 445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char DataSocket::kCrossOriginAllowHeaders[] = 455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Access-Control-Allow-Origin: *\r\n" 465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Access-Control-Allow-Credentials: true\r\n" 475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n" 485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Access-Control-Allow-Headers: Content-Type, " 495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Content-Length, Connection, Cache-Control\r\n" 505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Access-Control-Expose-Headers: Content-Length, X-Peer-Id\r\n"; 515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(WIN32) 535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass WinsockInitializer { 545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static WinsockInitializer singleton; 555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org WinsockInitializer() { 575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org WSADATA data; 585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org WSAStartup(MAKEWORD(1, 0), &data); 595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public: 625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ~WinsockInitializer() { WSACleanup(); } 635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgWinsockInitializer WinsockInitializer::singleton; 655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// 685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// SocketBase 695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// 705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool SocketBase::Create() { 725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(!valid()); 735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org socket_ = ::socket(AF_INET, SOCK_STREAM, 0); 745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return valid(); 755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid SocketBase::Close() { 785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (socket_ != INVALID_SOCKET) { 795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org closesocket(socket_); 805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org socket_ = INVALID_SOCKET; 815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// 855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// DataSocket 865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// 875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string DataSocket::request_arguments() const { 895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t args = request_path_.find('?'); 905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (args != std::string::npos) 915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return request_path_.substr(args + 1); 925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return ""; 935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DataSocket::PathEquals(const char* path) const { 965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(path); 975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t args = request_path_.find('?'); 985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (args != std::string::npos) 995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return request_path_.substr(0, args).compare(path) == 0; 1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return request_path_.compare(path) == 0; 1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DataSocket::OnDataAvailable(bool* close_socket) { 1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(valid()); 1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char buffer[0xfff] = {0}; 1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int bytes = recv(socket_, buffer, sizeof(buffer), 0); 1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (bytes == SOCKET_ERROR || bytes == 0) { 1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *close_socket = true; 1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *close_socket = false; 1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool ret = true; 1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (headers_received()) { 1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (method_ != POST) { 1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // unexpectedly received data. 1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ret = false; 1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org data_.append(buffer, bytes); 1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org request_headers_.append(buffer, bytes); 1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t found = request_headers_.find(kHeaderTerminator); 1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (found != std::string::npos) { 1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org data_ = request_headers_.substr(found + kHeaderTerminatorLength); 1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org request_headers_.resize(found + kHeaderTerminatorLength); 1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ret = ParseHeaders(); 1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return ret; 1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DataSocket::Send(const std::string& data) const { 135b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org return send(socket_, data.data(), static_cast<int>(data.length()), 0) != 136b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org SOCKET_ERROR; 1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DataSocket::Send(const std::string& status, bool connection_close, 1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string& content_type, 1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string& extra_headers, 1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string& data) const { 1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(valid()); 1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(!status.empty()); 1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string buffer("HTTP/1.1 " + status + "\r\n"); 1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org buffer += "Server: PeerConnectionTestServer/0.1\r\n" 1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Cache-Control: no-cache\r\n"; 1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (connection_close) 1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org buffer += "Connection: close\r\n"; 1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!content_type.empty()) 1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org buffer += "Content-Type: " + content_type + "\r\n"; 1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 156b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org buffer += "Content-Length: " + int2str(static_cast<int>(data.size())) + 157b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org "\r\n"; 1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!extra_headers.empty()) { 1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org buffer += extra_headers; 1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Extra headers are assumed to have a separator per header. 1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org buffer += kCrossOriginAllowHeaders; 1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org buffer += "\r\n"; 1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org buffer += data; 1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Send(buffer); 1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid DataSocket::Clear() { 1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org method_ = INVALID; 1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org content_length_ = 0; 1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org content_type_.clear(); 1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org request_path_.clear(); 1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org request_headers_.clear(); 1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org data_.clear(); 1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DataSocket::ParseHeaders() { 1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(!request_headers_.empty()); 1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(method_ == INVALID); 1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t i = request_headers_.find("\r\n"); 1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (i == std::string::npos) 1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!ParseMethodAndPath(request_headers_.data(), i)) 1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(method_ != INVALID); 1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(!request_path_.empty()); 1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (method_ == POST) { 1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* headers = request_headers_.data() + i + 2; 1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t len = request_headers_.length() - i - 2; 1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!ParseContentLengthAndType(headers, len)) 1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DataSocket::ParseMethodAndPath(const char* begin, size_t len) { 2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org struct { 2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* method_name; 2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t method_name_len; 2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org RequestMethod id; 2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } supported_methods[] = { 2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org { "GET", 3, GET }, 2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org { "POST", 4, POST }, 2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org { "OPTIONS", 7, OPTIONS }, 2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org }; 2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* path = NULL; 2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t i = 0; i < ARRAYSIZE(supported_methods); ++i) { 2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (len > supported_methods[i].method_name_len && 2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org isspace(begin[supported_methods[i].method_name_len]) && 2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org strncmp(begin, supported_methods[i].method_name, 2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org supported_methods[i].method_name_len) == 0) { 2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org method_ = supported_methods[i].id; 2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path = begin + supported_methods[i].method_name_len; 2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* end = begin + len; 2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!path || path >= end) 2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ++path; 2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org begin = path; 2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org while (!isspace(*path) && path < end) 2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ++path; 2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org request_path_.assign(begin, path - begin); 2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DataSocket::ParseContentLengthAndType(const char* headers, size_t length) { 2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(content_length_ == 0); 2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(content_type_.empty()); 2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* end = headers + length; 2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org while (headers && headers < end) { 2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!isspace(headers[0])) { 2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static const char kContentLength[] = "Content-Length:"; 2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static const char kContentType[] = "Content-Type:"; 2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if ((headers + ARRAYSIZE(kContentLength)) < end && 2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org strncmp(headers, kContentLength, 2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ARRAYSIZE(kContentLength) - 1) == 0) { 2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org headers += ARRAYSIZE(kContentLength) - 1; 2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org while (headers[0] == ' ') 2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ++headers; 2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org content_length_ = atoi(headers); 2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if ((headers + ARRAYSIZE(kContentType)) < end && 2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org strncmp(headers, kContentType, 2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ARRAYSIZE(kContentType) - 1) == 0) { 2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org headers += ARRAYSIZE(kContentType) - 1; 2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org while (headers[0] == ' ') 2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ++headers; 2635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* type_end = strstr(headers, "\r\n"); 2645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (type_end == NULL) 2655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org type_end = end; 2665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org content_type_.assign(headers, type_end); 2675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 2695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ++headers; 2705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org headers = strstr(headers, "\r\n"); 2725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (headers) 2735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org headers += 2; 2745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return !content_type_.empty() && content_length_ != 0; 2775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// 2805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// ListeningSocket 2815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// 2825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool ListeningSocket::Listen(unsigned short port) { 2845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(valid()); 2855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int enabled = 1; 2865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, 2875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org reinterpret_cast<const char*>(&enabled), sizeof(enabled)); 2885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org struct sockaddr_in addr = {0}; 2895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org addr.sin_family = AF_INET; 2905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org addr.sin_addr.s_addr = htonl(INADDR_ANY); 2915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org addr.sin_port = htons(port); 2925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (bind(socket_, reinterpret_cast<const sockaddr*>(&addr), 2935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sizeof(addr)) == SOCKET_ERROR) { 2945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org printf("bind failed\n"); 2955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return listen(socket_, 5) != SOCKET_ERROR; 2985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgDataSocket* ListeningSocket::Accept() const { 3015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org assert(valid()); 3025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org struct sockaddr_in addr = {0}; 3035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org socklen_t size = sizeof(addr); 3045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int client = accept(socket_, reinterpret_cast<sockaddr*>(&addr), &size); 3055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (client == INVALID_SOCKET) 3065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return NULL; 3075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return new DataSocket(client); 3095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 310