Blame view

trunk/src/app/srs_app_http.hpp 8.0 KB
1 2 3
/*
The MIT License (MIT)
4
Copyright (c) 2013-2014 winlin
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
24 25
#ifndef SRS_APP_HTTP_HPP
#define SRS_APP_HTTP_HPP
26 27

/*
28
#include <srs_app_http.hpp>
29 30 31
*/
#include <srs_core.hpp>
32 33 34
#ifdef SRS_HTTP_PARSER

#include <string>
winlin authored
35
#include <vector>
36
#include <sstream>
37 38 39

#include <http_parser.h>
40
#include <srs_app_st.hpp>
winlin authored
41
42 43 44
class SrsBuffer;
class SrsRequest;
class SrsSocket;
45
class SrsHttpUri;
winlin authored
46
class SrsHttpMessage;
47
class SrsHttpHandler;
48
49
// http specification
50 51 52 53 54 55 56 57 58 59 60 61 62 63
// CR             = <US-ASCII CR, carriage return (13)>
#define __CR "\r" // 0x0D
// LF             = <US-ASCII LF, linefeed (10)>
#define __LF "\n" // 0x0A
// SP             = <US-ASCII SP, space (32)>
#define __SP " " // 0x20
// HT             = <US-ASCII HT, horizontal-tab (9)>
#define __HT "\x09" // 0x09

// HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all
// protocol elements except the entity-body (see appendix 19.3 for
// tolerant applications). 
#define __CRLF "\r\n" // 0x0D0A
#define __CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A
64
winlin authored
65 66
// linux path seprator
#define __PATH_SEP '/'
67 68 69 70 71 72
// query string seprator
#define __QUERY_SEP '?'

// compare the path.
// full compare, extractly match.
extern bool srs_path_equals(const char* expect, const char* path, int nb_path);
winlin authored
73 74

// state of message
75 76 77 78 79
enum SrsHttpParseState {
    SrsHttpParseStateInit = 0, 
    SrsHttpParseStateStart, 
    SrsHttpParseStateComplete
};
winlin authored
80
81
/**
82 83 84 85 86 87 88 89 90 91 92 93
* the matched handler info.
*/
class SrsHttpHandlerMatch
{
public:
    SrsHttpHandler* handler;
    std::string matched_url;
public:
    SrsHttpHandlerMatch();
};

/**
winlin authored
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
* resource handler for HTTP RESTful api.
*/
class SrsHttpHandler
{
protected:
    /**
    * we use handler chain to process request.
    */
    std::vector<SrsHttpHandler*> handlers;
public:
    SrsHttpHandler();
    virtual ~SrsHttpHandler();
public:
    /**
    * initialize the handler.
    */
    virtual int initialize();
    /**
    * whether current handler can handle the specified path.
113 114 115
    * @pchild set the next child path, if needed.
    *       for example, the root handler will reset pchild to path,
    *       to reparse the path use child handlers.
winlin authored
116
    */
117
    virtual bool can_handle(const char* path, int length, const char** pchild);
winlin authored
118 119
    /**
    * use the handler to process the request.
120
    * @remark sub classes should override the do_process_request.
winlin authored
121
    */
122
    virtual int process_request(SrsSocket* skt, SrsHttpMessage* req);
winlin authored
123 124 125 126
public:
    /**
    * find the best matched handler
    */
127 128 129 130 131
    virtual int best_match(const char* path, int length, SrsHttpHandlerMatch** ppmatch);
// factory methods
protected:
    virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
// response writer
winlin authored
132
public:
133 134
    virtual SrsHttpHandler* res_status_line(std::stringstream& ss);
    virtual SrsHttpHandler* res_content_type(std::stringstream& ss);
135
    virtual SrsHttpHandler* res_content_type_json(std::stringstream& ss);
136 137 138 139 140 141 142 143
    virtual SrsHttpHandler* res_content_length(std::stringstream& ss, int64_t length);
    virtual SrsHttpHandler* res_enable_crossdomain(std::stringstream& ss);
    virtual SrsHttpHandler* res_header_eof(std::stringstream& ss);
    virtual SrsHttpHandler* res_body(std::stringstream& ss, std::string body);
    virtual int res_flush(SrsSocket* skt, std::stringstream& ss);
public:
    virtual int res_options(SrsSocket* skt);
    virtual int res_text(SrsSocket* skt, std::string body);
144 145
    virtual int res_json(SrsSocket* skt, std::string json);
// object creator
146
public:
winlin authored
147 148 149 150 151 152 153 154 155 156 157
    /**
    * create http api resource handler.
    */
    static SrsHttpHandler* create_http_api();
    /**
    * create http stream resource handler.
    */
    static SrsHttpHandler* create_http_stream();
};

/**
158 159 160 161
* the http message, request or response.
*/
class SrsHttpMessage
{
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
private:
    /**
    * parsed url.
    */
    std::string _url;
    /**
    * parsed http header.
    */
    http_parser _header;
    /**
    * body object, in bytes.
    * @remark, user can get body in string by get_body().
    */
    SrsBuffer* _body;
    /**
    * parser state
    * @remark, user can use is_complete() to determine the state.
    */
    SrsHttpParseState _state;
181 182 183 184 185 186 187 188
    /**
    * uri parser
    */
    SrsHttpUri* _uri;
    /**
    * best matched handler.
    */
    SrsHttpHandlerMatch* _match;
189
public:
190 191
    SrsHttpMessage();
    virtual ~SrsHttpMessage();
192
public:
193
    virtual void reset();
194
    virtual int parse_uri();
195
public:
196
    virtual bool is_complete();
197 198
    virtual u_int8_t method();
    virtual std::string url();
199 200
    virtual std::string path();
    virtual std::string query();
201 202 203
    virtual std::string body();
    virtual int64_t body_size();
    virtual int64_t content_length();
204
    virtual SrsHttpHandlerMatch* match();
205 206 207
    virtual void set_url(std::string url);
    virtual void set_state(SrsHttpParseState state);
    virtual void set_header(http_parser* header);
208
    virtual void set_match(SrsHttpHandlerMatch* match);
209
    virtual void append_body(const char* body, int length);
210
};
winlin authored
211
212 213 214 215 216 217
/**
* wrapper for http-parser, 
* provides HTTP message originted service.
*/
class SrsHttpParser
{
218 219 220 221
private:
    http_parser_settings settings;
    http_parser parser;
    SrsHttpMessage* msg;
222 223 224 225
public:
    SrsHttpParser();
    virtual ~SrsHttpParser();
public:
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
    /**
    * initialize the http parser with specified type,
    * one parser can only parse request or response messages.
    */
    virtual int initialize(enum http_parser_type type);
    /**
    * always parse a http message,
    * that is, the *ppmsg always NOT-NULL when return success.
    * or error and *ppmsg must be NULL.
    * @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete().
    */
    virtual int parse_message(SrsSocket* skt, SrsHttpMessage** ppmsg);
private:
    /**
    * parse the HTTP message to member field: msg.
    */
    virtual int parse_message_imp(SrsSocket* skt);
private:
    static int on_message_begin(http_parser* parser);
    static int on_headers_complete(http_parser* parser);
    static int on_message_complete(http_parser* parser);
    static int on_url(http_parser* parser, const char* at, size_t length);
    static int on_header_field(http_parser* parser, const char* at, size_t length);
    static int on_header_value(http_parser* parser, const char* at, size_t length);
    static int on_body(http_parser* parser, const char* at, size_t length);
251
};
winlin authored
252 253 254 255 256 257 258 259 260 261 262 263

/**
* used to resolve the http uri.
*/
class SrsHttpUri
{
private:
    std::string url;
    std::string schema;
    std::string host;
    int port;
    std::string path;
264
    std::string query;
winlin authored
265
public:
266 267
    SrsHttpUri();
    virtual ~SrsHttpUri();
winlin authored
268
public:
269 270 271 272
    /**
    * initialize the http uri.
    */
    virtual int initialize(std::string _url);
winlin authored
273 274 275 276 277
public:
    virtual const char* get_url();
    virtual const char* get_schema();
    virtual const char* get_host();
    virtual int get_port();
278
    virtual const char* get_path();
279
    virtual const char* get_query();
winlin authored
280 281 282 283 284 285 286 287
private:
    /**
    * get the parsed url field.
    * @return return empty string if not set.
    */
    virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field);
};
288 289 290
#endif

#endif