15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/* 25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle 35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2004--2005, 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// Copyright 2005 Google Inc. All Rights Reserved. 295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// 305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifndef TALK_BASE_HTTPBASE_H__ 335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define TALK_BASE_HTTPBASE_H__ 345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/httpcommon.h" 365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace talk_base { 385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass StreamInterface; 405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// HttpParser - Parses an HTTP stream provided via Process and end_of_input, and 435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// generates events for: 445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Structural Elements: Leader, Headers, Document Data 455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Events: End of Headers, End of Document, Errors 465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass HttpParser { 495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgpublic: 505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org enum ProcessResult { PR_CONTINUE, PR_BLOCK, PR_COMPLETE }; 515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpParser(); 525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual ~HttpParser(); 535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void reset(); 555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ProcessResult Process(const char* buffer, size_t len, size_t* processed, 565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpError* error); 575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool is_valid_end_of_input() const; 585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void complete(HttpError err); 595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t GetDataRemaining() const { return data_size_; } 615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgprotected: 635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ProcessResult ProcessLine(const char* line, size_t len, HttpError* error); 645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // HttpParser Interface 665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual ProcessResult ProcessLeader(const char* line, size_t len, 675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpError* error) = 0; 685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual ProcessResult ProcessHeader(const char* name, size_t nlen, 695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* value, size_t vlen, 705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpError* error) = 0; 715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual ProcessResult ProcessHeaderComplete(bool chunked, size_t& data_size, 725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpError* error) = 0; 735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual ProcessResult ProcessData(const char* data, size_t len, size_t& read, 745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpError* error) = 0; 755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual void OnComplete(HttpError err) = 0; 765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgprivate: 785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org enum State { 795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ST_LEADER, ST_HEADERS, 805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ST_CHUNKSIZE, ST_CHUNKTERM, ST_TRAILERS, 815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ST_DATA, ST_COMPLETE 825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } state_; 835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool chunked_; 845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t data_size_; 855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// IHttpNotify 895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgenum HttpMode { HM_NONE, HM_CONNECT, HM_RECV, HM_SEND }; 925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass IHttpNotify { 945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgpublic: 955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual ~IHttpNotify() {} 965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size) = 0; 975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual void onHttpComplete(HttpMode mode, HttpError err) = 0; 985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual void onHttpClosed(HttpError err) = 0; 995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// HttpBase - Provides a state machine for implementing HTTP-based components. 1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Attach HttpBase to a StreamInterface which represents a bidirectional HTTP 1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// stream, and then call send() or recv() to initiate sending or receiving one 1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// side of an HTTP transaction. By default, HttpBase operates as an I/O pump, 1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// moving data from the HTTP stream to the HttpData object and vice versa. 1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// However, it can also operate in stream mode, in which case the user of the 1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// stream interface drives I/O via calls to Read(). 1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass HttpBase 1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org: private HttpParser, 1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public sigslot::has_slots<> 1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org{ 1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgpublic: 1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpBase(); 1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual ~HttpBase(); 1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void notify(IHttpNotify* notify) { notify_ = notify; } 1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool attach(StreamInterface* stream); 1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org StreamInterface* stream() { return http_stream_; } 1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org StreamInterface* detach(); 1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool isConnected() const; 1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void send(HttpData* data); 1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void recv(HttpData* data); 1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void abort(HttpError err); 1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpMode mode() const { return mode_; } 1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void set_ignore_data(bool ignore) { ignore_data_ = ignore; } 1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool ignore_data() const { return ignore_data_; } 1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Obtaining this stream puts HttpBase into stream mode until the stream 1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // is closed. HttpBase can only expose one open stream interface at a time. 1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Further calls will return NULL. 1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org StreamInterface* GetDocumentStream(); 1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgprotected: 1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Do cleanup when the http stream closes (error may be 0 for a clean 1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // shutdown), and return the error code to signal. 1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpError HandleStreamClose(int error); 1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // DoReceiveLoop acts as a data pump, pulling data from the http stream, 1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // pushing it through the HttpParser, and then populating the HttpData object 1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // based on the callbacks from the parser. One of the most interesting 1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // callbacks is ProcessData, which provides the actual http document body. 1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // This data is then written to the HttpData::document. As a result, data 1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // flows from the network to the document, with some incidental protocol 1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // parsing in between. 1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Ideally, we would pass in the document* to DoReceiveLoop, to more easily 1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // support GetDocumentStream(). However, since the HttpParser is callback 1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // driven, we are forced to store the pointer somewhere until the callback 1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // is triggered. 1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Returns true if the received document has finished, and 1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // HttpParser::complete should be called. 1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool DoReceiveLoop(HttpError* err); 1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void read_and_process_data(); 1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void flush_data(); 1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool queue_headers(); 1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void do_complete(HttpError err = HE_NONE); 1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void OnHttpStreamEvent(StreamInterface* stream, int events, int error); 1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void OnDocumentEvent(StreamInterface* stream, int events, int error); 1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // HttpParser Interface 1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual ProcessResult ProcessLeader(const char* line, size_t len, 1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpError* error); 1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual ProcessResult ProcessHeader(const char* name, size_t nlen, 1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* value, size_t vlen, 1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpError* error); 1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual ProcessResult ProcessHeaderComplete(bool chunked, size_t& data_size, 1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpError* error); 1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual ProcessResult ProcessData(const char* data, size_t len, size_t& read, 1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpError* error); 1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual void OnComplete(HttpError err); 1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgprivate: 1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org class DocumentStream; 1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org friend class DocumentStream; 1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org enum { kBufferSize = 32 * 1024 }; 1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpMode mode_; 1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpData* data_; 1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org IHttpNotify* notify_; 1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org StreamInterface* http_stream_; 1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org DocumentStream* doc_stream_; 1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char buffer_[kBufferSize]; 1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t len_; 1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool ignore_data_, chunk_data_; 1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HttpData::const_iterator header_; 1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} // namespace talk_base 2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // TALK_BASE_HTTPBASE_H__ 202