1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

merge the app http to conn.

This commit is contained in:
winlin 2015-05-22 22:34:03 +08:00
parent ce1bb6c605
commit f0ae66a081
10 changed files with 1276 additions and 1275 deletions

View file

@ -30,14 +30,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core.hpp>
#ifdef SRS_AUTO_HTTP_SERVER
#ifdef SRS_AUTO_HTTP_PARSER
#include <http_parser.h>
#endif
#if defined(SRS_AUTO_HTTP_PARSER) || defined(SRS_AUTO_HTTP_SERVER)
#include <map>
#include <string>
#include <vector>
#include <srs_app_st.hpp>
#include <srs_app_conn.hpp>
#include <srs_http_stack.hpp>
#include <srs_app_http.hpp>
#include <srs_app_reload.hpp>
#include <srs_kernel_file.hpp>
#include <srs_app_thread.hpp>
#include <srs_app_conn.hpp>
class SrsServer;
class SrsSource;
@ -53,6 +62,309 @@ class ISrsHttpMessage;
class SrsHttpHandler;
class SrsMessageQueue;
class SrsSharedPtrMessage;
class SrsRequest;
class SrsFastBuffer;
class SrsHttpUri;
class SrsConnection;
class SrsHttpMessage;
#endif
#ifdef SRS_AUTO_HTTP_PARSER
/**
* response writer use st socket
*/
class SrsHttpResponseWriter : public ISrsHttpResponseWriter
{
private:
SrsStSocket* skt;
SrsHttpHeader* hdr;
private:
// reply header has been (logically) written
bool header_wrote;
// status code passed to WriteHeader
int status;
private:
// explicitly-declared Content-Length; or -1
int64_t content_length;
// number of bytes written in body
int64_t written;
private:
// wroteHeader tells whether the header's been written to "the
// wire" (or rather: w.conn.buf). this is unlike
// (*response).wroteHeader, which tells only whether it was
// logically written.
bool header_sent;
public:
SrsHttpResponseWriter(SrsStSocket* io);
virtual ~SrsHttpResponseWriter();
public:
virtual int final_request();
virtual SrsHttpHeader* header();
virtual int write(char* data, int size);
virtual void write_header(int code);
virtual int send_header(char* data, int size);
};
/**
* response reader use st socket.
*/
class SrsHttpResponseReader : virtual public ISrsHttpResponseReader
{
private:
SrsStSocket* skt;
SrsHttpMessage* owner;
SrsFastBuffer* buffer;
bool is_eof;
// the left bytes in chunk.
int nb_left_chunk;
// the number of bytes of current chunk.
int nb_chunk;
// already read total bytes.
int64_t nb_total_read;
public:
SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io);
virtual ~SrsHttpResponseReader();
public:
/**
* initialize the response reader with buffer.
*/
virtual int initialize(SrsFastBuffer* buffer);
// interface ISrsHttpResponseReader
public:
virtual bool eof();
virtual int read(char* data, int nb_data, int* nb_read);
private:
virtual int read_chunked(char* data, int nb_data, int* nb_read);
virtual int read_specified(char* data, int nb_data, int* nb_read);
};
// for http header.
typedef std::pair<std::string, std::string> SrsHttpHeaderField;
// A Request represents an HTTP request received by a server
// or to be sent by a client.
//
// The field semantics differ slightly between client and server
// usage. In addition to the notes on the fields below, see the
// documentation for Request.Write and RoundTripper.
/**
* the http message, request or response.
*/
class SrsHttpMessage : public ISrsHttpMessage
{
private:
/**
* parsed url.
*/
std::string _url;
/**
* the extension of file, for example, .flv
*/
std::string _ext;
/**
* parsed http header.
*/
http_parser _header;
/**
* body object, reader object.
* @remark, user can get body in string by get_body().
*/
SrsHttpResponseReader* _body;
/**
* whether the body is chunked.
*/
bool chunked;
/**
* whether the request indicates should keep alive
* for the http connection.
*/
bool keep_alive;
/**
* uri parser
*/
SrsHttpUri* _uri;
/**
* use a buffer to read and send ts file.
*/
// TODO: FIXME: remove it.
char* _http_ts_send_buffer;
// http headers
std::vector<SrsHttpHeaderField> _headers;
// the query map
std::map<std::string, std::string> _query;
// the transport connection, can be NULL.
SrsConnection* conn;
public:
SrsHttpMessage(SrsStSocket* io, SrsConnection* c);
virtual ~SrsHttpMessage();
public:
/**
* set the original messages, then update the message.
*/
virtual int update(std::string url, http_parser* header,
SrsFastBuffer* body, std::vector<SrsHttpHeaderField>& headers
);
private:
virtual SrsConnection* connection();
public:
virtual u_int8_t method();
virtual u_int16_t status_code();
/**
* method helpers.
*/
virtual std::string method_str();
virtual bool is_http_get();
virtual bool is_http_put();
virtual bool is_http_post();
virtual bool is_http_delete();
virtual bool is_http_options();
/**
* whether body is chunked encoding, for reader only.
*/
virtual bool is_chunked();
/**
* whether should keep the connection alive.
*/
virtual bool is_keep_alive();
/**
* the uri contains the host and path.
*/
virtual std::string uri();
/**
* the url maybe the path.
*/
virtual std::string url();
virtual std::string host();
virtual std::string path();
virtual std::string ext();
public:
/**
* read body to string.
* @remark for small http body.
*/
virtual int body_read_all(std::string& body);
/**
* get the body reader, to read one by one.
* @remark when body is very large, or chunked, use this.
*/
virtual ISrsHttpResponseReader* body_reader();
/**
* the content length, -1 for chunked or not set.
*/
virtual int64_t content_length();
/**
* get the param in query string,
* for instance, query is "start=100&end=200",
* then query_get("start") is "100", and query_get("end") is "200"
*/
virtual std::string query_get(std::string key);
/**
* get the headers.
*/
virtual int request_header_count();
virtual std::string request_header_key_at(int index);
virtual std::string request_header_value_at(int index);
virtual std::string get_request_header(std::string name);
public:
/**
* convert the http message to a request.
* @remark user must free the return request.
*/
virtual SrsRequest* to_request(std::string vhost);
};
/**
* wrapper for http-parser,
* provides HTTP message originted service.
*/
class SrsHttpParser
{
private:
http_parser_settings settings;
http_parser parser;
// the global parse buffer.
SrsFastBuffer* buffer;
private:
// http parse data, reset before parse message.
bool expect_field_name;
std::string field_name;
std::string field_value;
SrsHttpParseState state;
http_parser header;
std::string url;
std::vector<SrsHttpHeaderField> headers;
int header_parsed;
public:
SrsHttpParser();
virtual ~SrsHttpParser();
public:
/**
* 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(SrsStSocket* skt, SrsConnection* conn, ISrsHttpMessage** ppmsg);
private:
/**
* parse the HTTP message to member field: msg.
*/
virtual int parse_message_imp(SrsStSocket* 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);
};
/**
* used to resolve the http uri.
*/
class SrsHttpUri
{
private:
std::string url;
std::string schema;
std::string host;
int port;
std::string path;
std::string query;
public:
SrsHttpUri();
virtual ~SrsHttpUri();
public:
/**
* initialize the http uri.
*/
virtual int initialize(std::string _url);
public:
virtual const char* get_url();
virtual const char* get_schema();
virtual const char* get_host();
virtual int get_port();
virtual const char* get_path();
virtual const char* get_query();
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);
};
#endif
#ifdef SRS_AUTO_HTTP_SERVER
/**
* the flv vod stream supports flv?start=offset-bytes.