winlin

create http handler framework

@@ -285,7 +285,7 @@ fi @@ -285,7 +285,7 @@ fi
285 ##################################################################################### 285 #####################################################################################
286 function write_nginx_html5() 286 function write_nginx_html5()
287 { 287 {
288 - cat<<END >> ${html_file} 288 + cat<<END > ${html_file}
289 <video width="640" height="360" 289 <video width="640" height="360"
290 autoplay controls autobuffer 290 autoplay controls autobuffer
291 src="${hls_stream}" 291 src="${hls_stream}"
@@ -398,7 +398,7 @@ if [ $__SRS_BUILD_NGINX = YES ]; then @@ -398,7 +398,7 @@ if [ $__SRS_BUILD_NGINX = YES ]; then
398 ln -sf `pwd`/research/players/nginx_index.html ${SRS_OBJS}/nginx/html/index.html 398 ln -sf `pwd`/research/players/nginx_index.html ${SRS_OBJS}/nginx/html/index.html
399 else 399 else
400 rm -f ${SRS_OBJS}/nginx/html/index.html && 400 rm -f ${SRS_OBJS}/nginx/html/index.html &&
401 - cat<<END >> ${SRS_OBJS}/nginx/html/index.html 401 + cat<<END > ${SRS_OBJS}/nginx/html/index.html
402 <!DOCTYPE html> 402 <!DOCTYPE html>
403 <html> 403 <html>
404 <head> 404 <head>
@@ -32,11 +32,101 @@ using namespace std; @@ -32,11 +32,101 @@ using namespace std;
32 #include <srs_kernel_error.hpp> 32 #include <srs_kernel_error.hpp>
33 #include <srs_kernel_log.hpp> 33 #include <srs_kernel_log.hpp>
34 #include <srs_app_socket.hpp> 34 #include <srs_app_socket.hpp>
  35 +#include <srs_app_http_api.hpp>
  36 +#include <srs_app_http_conn.hpp>
35 37
36 #define SRS_DEFAULT_HTTP_PORT 80 38 #define SRS_DEFAULT_HTTP_PORT 80
37 39
38 #define SRS_HTTP_HEADER_BUFFER 1024 40 #define SRS_HTTP_HEADER_BUFFER 1024
39 41
  42 +SrsHttpHandler::SrsHttpHandler()
  43 +{
  44 +}
  45 +
  46 +SrsHttpHandler::~SrsHttpHandler()
  47 +{
  48 + std::vector<SrsHttpHandler*>::iterator it;
  49 + for (it = handlers.begin(); it != handlers.end(); ++it) {
  50 + SrsHttpHandler* handler = *it;
  51 + srs_freep(handler);
  52 + }
  53 + handlers.clear();
  54 +}
  55 +
  56 +int SrsHttpHandler::initialize()
  57 +{
  58 + int ret = ERROR_SUCCESS;
  59 + return ret;
  60 +}
  61 +
  62 +bool SrsHttpHandler::can_handle(const char* /*path*/, int /*length*/)
  63 +{
  64 + return false;
  65 +}
  66 +
  67 +int SrsHttpHandler::process_request(SrsSocket* /*skt*/, SrsHttpMessage* /*req*/, const char* /*path*/, int /*length*/)
  68 +{
  69 + int ret = ERROR_SUCCESS;
  70 + return ret;
  71 +}
  72 +
  73 +int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandler** phandler, const char** pstart, int* plength)
  74 +{
  75 + int ret = ERROR_SUCCESS;
  76 +
  77 + for (;;) {
  78 + // ensure cur is not NULL.
  79 + // ensure p not NULL and has bytes to parse.
  80 + if (!path || length <= 0) {
  81 + break;
  82 + }
  83 +
  84 + const char* p = NULL;
  85 + for (p = path + 1; p - path < length && *p != __PATH_SEP; p++) {
  86 + }
  87 +
  88 + // whether the handler can handler the node.
  89 + int node_size = p - path;
  90 + if (!can_handle(path, node_size)) {
  91 + break;
  92 + }
  93 +
  94 + *phandler = this;
  95 + *pstart = path;
  96 + *plength = node_size;
  97 +
  98 + std::vector<SrsHttpHandler*>::iterator it;
  99 + for (it = handlers.begin(); it != handlers.end(); ++it) {
  100 + SrsHttpHandler* handler = *it;
  101 + // matched, donot search.
  102 + if (handler->best_match(p, length - node_size, phandler, pstart, plength) == ERROR_SUCCESS) {
  103 + break;
  104 + }
  105 + }
  106 +
  107 + // whatever, donot loop.
  108 + break;
  109 + }
  110 +
  111 + if (*phandler == NULL) {
  112 + ret = ERROR_HTTP_HANDLER_MATCH_URL;
  113 + return ret;
  114 + }
  115 +
  116 + return ret;
  117 +}
  118 +
  119 +SrsHttpHandler* SrsHttpHandler::create_http_api()
  120 +{
  121 + return new SrsApiRoot();
  122 +}
  123 +
  124 +SrsHttpHandler* SrsHttpHandler::create_http_stream()
  125 +{
  126 + // TODO: FIXME: use http stream handler instead.
  127 + return new SrsHttpHandler();
  128 +}
  129 +
40 SrsHttpMessage::SrsHttpMessage() 130 SrsHttpMessage::SrsHttpMessage()
41 { 131 {
42 _body = new SrsBuffer(); 132 _body = new SrsBuffer();
@@ -32,6 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -32,6 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #ifdef SRS_HTTP_PARSER 32 #ifdef SRS_HTTP_PARSER
33 33
34 #include <string> 34 #include <string>
  35 +#include <vector>
35 36
36 #include <http_parser.h> 37 #include <http_parser.h>
37 38
@@ -40,6 +41,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -40,6 +41,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 class SrsBuffer; 41 class SrsBuffer;
41 class SrsRequest; 42 class SrsRequest;
42 class SrsSocket; 43 class SrsSocket;
  44 +class SrsHttpMessage;
43 45
44 // http specification 46 // http specification
45 // CR = <US-ASCII CR, carriage return (13)> 47 // CR = <US-ASCII CR, carriage return (13)>
@@ -57,6 +59,10 @@ class SrsSocket; @@ -57,6 +59,10 @@ class SrsSocket;
57 #define __CRLF "\r\n" // 0x0D0A 59 #define __CRLF "\r\n" // 0x0D0A
58 #define __CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A 60 #define __CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A
59 61
  62 +// linux path seprator
  63 +#define __PATH_SEP '/'
  64 +
  65 +// state of message
60 enum SrsHttpParseState { 66 enum SrsHttpParseState {
61 SrsHttpParseStateInit = 0, 67 SrsHttpParseStateInit = 0,
62 SrsHttpParseStateStart, 68 SrsHttpParseStateStart,
@@ -64,6 +70,48 @@ enum SrsHttpParseState { @@ -64,6 +70,48 @@ enum SrsHttpParseState {
64 }; 70 };
65 71
66 /** 72 /**
  73 +* resource handler for HTTP RESTful api.
  74 +*/
  75 +class SrsHttpHandler
  76 +{
  77 +protected:
  78 + /**
  79 + * we use handler chain to process request.
  80 + */
  81 + std::vector<SrsHttpHandler*> handlers;
  82 +public:
  83 + SrsHttpHandler();
  84 + virtual ~SrsHttpHandler();
  85 +public:
  86 + /**
  87 + * initialize the handler.
  88 + */
  89 + virtual int initialize();
  90 + /**
  91 + * whether current handler can handle the specified path.
  92 + */
  93 + virtual bool can_handle(const char* path, int length);
  94 + /**
  95 + * use the handler to process the request.
  96 + */
  97 + virtual int process_request(SrsSocket* skt, SrsHttpMessage* req, const char* path, int length);
  98 +public:
  99 + /**
  100 + * find the best matched handler
  101 + */
  102 + virtual int best_match(const char* path, int length, SrsHttpHandler** phandler, const char** pstart, int* plength);
  103 +public:
  104 + /**
  105 + * create http api resource handler.
  106 + */
  107 + static SrsHttpHandler* create_http_api();
  108 + /**
  109 + * create http stream resource handler.
  110 + */
  111 + static SrsHttpHandler* create_http_stream();
  112 +};
  113 +
  114 +/**
67 * the http message, request or response. 115 * the http message, request or response.
68 */ 116 */
69 class SrsHttpMessage 117 class SrsHttpMessage
@@ -34,10 +34,30 @@ using namespace std; @@ -34,10 +34,30 @@ using namespace std;
34 #include <srs_app_socket.hpp> 34 #include <srs_app_socket.hpp>
35 #include <srs_core_autofree.hpp> 35 #include <srs_core_autofree.hpp>
36 36
37 -SrsHttpApi::SrsHttpApi(SrsServer* srs_server, st_netfd_t client_stfd) 37 +SrsApiRoot::SrsApiRoot()
  38 +{
  39 +}
  40 +
  41 +SrsApiRoot::~SrsApiRoot()
  42 +{
  43 +}
  44 +
  45 +bool SrsApiRoot::can_handle(const char* /*path*/, int /*length*/)
  46 +{
  47 + return true;
  48 +}
  49 +
  50 +int SrsApiRoot::process_request(SrsSocket* /*skt*/, SrsHttpMessage* /*req*/, const char* /*path*/, int /*length*/)
  51 +{
  52 + int ret = ERROR_SUCCESS;
  53 + return ret;
  54 +}
  55 +
  56 +SrsHttpApi::SrsHttpApi(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler)
38 : SrsConnection(srs_server, client_stfd) 57 : SrsConnection(srs_server, client_stfd)
39 { 58 {
40 parser = new SrsHttpParser(); 59 parser = new SrsHttpParser();
  60 + handler = _handler;
41 } 61 }
42 62
43 SrsHttpApi::~SrsHttpApi() 63 SrsHttpApi::~SrsHttpApi()
@@ -93,6 +113,28 @@ int SrsHttpApi::process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -93,6 +113,28 @@ int SrsHttpApi::process_request(SrsSocket* skt, SrsHttpMessage* req)
93 { 113 {
94 int ret = ERROR_SUCCESS; 114 int ret = ERROR_SUCCESS;
95 115
  116 + // TODO: maybe need to parse the url.
  117 + std::string uri = req->url();
  118 +
  119 + int length = 0;
  120 + const char* start = NULL;
  121 + SrsHttpHandler* p = NULL;
  122 + if ((ret = handler->best_match(uri.data(), uri.length(), &p, &start, &length)) != ERROR_SUCCESS) {
  123 + srs_warn("failed to find the best match handler for url. ret=%d", ret);
  124 + return ret;
  125 + }
  126 +
  127 + // if success, p and pstart should be valid.
  128 + srs_assert(p);
  129 + srs_assert(start);
  130 + srs_assert(length <= (int)uri.length());
  131 +
  132 + // use handler to process request.
  133 + if ((ret = p->process_request(skt, req, start, length)) != ERROR_SUCCESS) {
  134 + srs_warn("handler failed to process http request. ret=%d", ret);
  135 + return ret;
  136 + }
  137 +
96 if (req->method() == HTTP_OPTIONS) { 138 if (req->method() == HTTP_OPTIONS) {
97 char data[] = "HTTP/1.1 200 OK" __CRLF 139 char data[] = "HTTP/1.1 200 OK" __CRLF
98 "Content-Length: 0"__CRLF 140 "Content-Length: 0"__CRLF
@@ -35,16 +35,30 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -35,16 +35,30 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 class SrsSocket; 35 class SrsSocket;
36 class SrsHttpMessage; 36 class SrsHttpMessage;
37 class SrsHttpParser; 37 class SrsHttpParser;
  38 +class SrsHttpHandler;
38 39
39 #include <srs_app_st.hpp> 40 #include <srs_app_st.hpp>
40 #include <srs_app_conn.hpp> 41 #include <srs_app_conn.hpp>
  42 +#include <srs_app_http.hpp>
  43 +
  44 +// for http root.
  45 +class SrsApiRoot : public SrsHttpHandler
  46 +{
  47 +public:
  48 + SrsApiRoot();
  49 + virtual ~SrsApiRoot();
  50 +public:
  51 + virtual bool can_handle(const char* path, int length);
  52 + virtual int process_request(SrsSocket* skt, SrsHttpMessage* req, const char* path, int length);
  53 +};
41 54
42 class SrsHttpApi : public SrsConnection 55 class SrsHttpApi : public SrsConnection
43 { 56 {
44 private: 57 private:
45 SrsHttpParser* parser; 58 SrsHttpParser* parser;
  59 + SrsHttpHandler* handler;
46 public: 60 public:
47 - SrsHttpApi(SrsServer* srs_server, st_netfd_t client_stfd); 61 + SrsHttpApi(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler);
48 virtual ~SrsHttpApi(); 62 virtual ~SrsHttpApi();
49 protected: 63 protected:
50 virtual int do_cycle(); 64 virtual int do_cycle();
@@ -37,10 +37,11 @@ using namespace std; @@ -37,10 +37,11 @@ using namespace std;
37 37
38 #define SRS_HTTP_HEADER_BUFFER 1024 38 #define SRS_HTTP_HEADER_BUFFER 1024
39 39
40 -SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd) 40 +SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler)
41 : SrsConnection(srs_server, client_stfd) 41 : SrsConnection(srs_server, client_stfd)
42 { 42 {
43 parser = new SrsHttpParser(); 43 parser = new SrsHttpParser();
  44 + handler = _handler;
44 } 45 }
45 46
46 SrsHttpConn::~SrsHttpConn() 47 SrsHttpConn::~SrsHttpConn()
@@ -40,13 +40,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -40,13 +40,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 class SrsSocket; 40 class SrsSocket;
41 class SrsHttpParser; 41 class SrsHttpParser;
42 class SrsHttpMessage; 42 class SrsHttpMessage;
  43 +class SrsHttpHandler;
43 44
44 class SrsHttpConn : public SrsConnection 45 class SrsHttpConn : public SrsConnection
45 { 46 {
46 private: 47 private:
47 SrsHttpParser* parser; 48 SrsHttpParser* parser;
  49 + SrsHttpHandler* handler;
48 public: 50 public:
49 - SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd); 51 + SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler);
50 virtual ~SrsHttpConn(); 52 virtual ~SrsHttpConn();
51 protected: 53 protected:
52 virtual int do_cycle(); 54 virtual int do_cycle();
@@ -40,6 +40,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -40,6 +40,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 #include <srs_kernel_utility.hpp> 40 #include <srs_kernel_utility.hpp>
41 #include <srs_app_http_api.hpp> 41 #include <srs_app_http_api.hpp>
42 #include <srs_app_http_conn.hpp> 42 #include <srs_app_http_conn.hpp>
  43 +#include <srs_app_http.hpp>
43 44
44 #define SERVER_LISTEN_BACKLOG 512 45 #define SERVER_LISTEN_BACKLOG 512
45 #define SRS_TIME_RESOLUTION_MS 500 46 #define SRS_TIME_RESOLUTION_MS 500
@@ -160,6 +161,13 @@ SrsServer::SrsServer() @@ -160,6 +161,13 @@ SrsServer::SrsServer()
160 161
161 srs_assert(_srs_config); 162 srs_assert(_srs_config);
162 _srs_config->subscribe(this); 163 _srs_config->subscribe(this);
  164 +
  165 +#ifdef SRS_HTTP_API
  166 + http_api_handler = SrsHttpHandler::create_http_api();
  167 +#endif
  168 +#ifdef SRS_HTTP_SERVER
  169 + http_stream_handler = SrsHttpHandler::create_http_stream();
  170 +#endif
163 } 171 }
164 172
165 SrsServer::~SrsServer() 173 SrsServer::~SrsServer()
@@ -176,11 +184,32 @@ SrsServer::~SrsServer() @@ -176,11 +184,32 @@ SrsServer::~SrsServer()
176 } 184 }
177 185
178 close_listeners(); 186 close_listeners();
  187 +
  188 +#ifdef SRS_HTTP_API
  189 + srs_freep(http_api_handler);
  190 +#endif
  191 +
  192 +#ifdef SRS_HTTP_SERVER
  193 + srs_freep(http_stream_handler);
  194 +#endif
179 } 195 }
180 196
181 int SrsServer::initialize() 197 int SrsServer::initialize()
182 { 198 {
183 int ret = ERROR_SUCCESS; 199 int ret = ERROR_SUCCESS;
  200 +
  201 +#ifdef SRS_HTTP_API
  202 + if ((ret = http_api_handler->initialize()) != ERROR_SUCCESS) {
  203 + return ret;
  204 + }
  205 +#endif
  206 +
  207 +#ifdef SRS_HTTP_SERVER
  208 + if ((ret = http_stream_handler->initialize()) != ERROR_SUCCESS) {
  209 + return ret;
  210 + }
  211 +#endif
  212 +
184 return ret; 213 return ret;
185 } 214 }
186 215
@@ -443,7 +472,7 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd) @@ -443,7 +472,7 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
443 conn = new SrsRtmpConn(this, client_stfd); 472 conn = new SrsRtmpConn(this, client_stfd);
444 } else if (type == SrsListenerHttpApi) { 473 } else if (type == SrsListenerHttpApi) {
445 #ifdef SRS_HTTP_API 474 #ifdef SRS_HTTP_API
446 - conn = new SrsHttpApi(this, client_stfd); 475 + conn = new SrsHttpApi(this, client_stfd, http_api_handler);
447 #else 476 #else
448 srs_warn("close http client for server not support http-api"); 477 srs_warn("close http client for server not support http-api");
449 srs_close_stfd(client_stfd); 478 srs_close_stfd(client_stfd);
@@ -451,7 +480,7 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd) @@ -451,7 +480,7 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
451 #endif 480 #endif
452 } else if (type == SrsListenerHttpStream) { 481 } else if (type == SrsListenerHttpStream) {
453 #ifdef SRS_HTTP_SERVER 482 #ifdef SRS_HTTP_SERVER
454 - conn = new SrsHttpConn(this, client_stfd); 483 + conn = new SrsHttpConn(this, client_stfd, http_stream_handler);
455 #else 484 #else
456 srs_warn("close http client for server not support http-server"); 485 srs_warn("close http client for server not support http-server");
457 srs_close_stfd(client_stfd); 486 srs_close_stfd(client_stfd);
@@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 38
39 class SrsServer; 39 class SrsServer;
40 class SrsConnection; 40 class SrsConnection;
  41 +class SrsHttpHandler;
41 42
42 // listener type for server to identify the connection, 43 // listener type for server to identify the connection,
43 // that is, use different type to process the connection. 44 // that is, use different type to process the connection.
@@ -76,6 +77,13 @@ class SrsServer : public ISrsReloadHandler @@ -76,6 +77,13 @@ class SrsServer : public ISrsReloadHandler
76 { 77 {
77 friend class SrsListener; 78 friend class SrsListener;
78 private: 79 private:
  80 +#ifdef SRS_HTTP_API
  81 + SrsHttpHandler* http_api_handler;
  82 +#endif
  83 +#ifdef SRS_HTTP_SERVER
  84 + SrsHttpHandler* http_stream_handler;
  85 +#endif
  86 +private:
79 std::vector<SrsConnection*> conns; 87 std::vector<SrsConnection*> conns;
80 std::vector<SrsListener*> listeners; 88 std::vector<SrsListener*> listeners;
81 bool signal_reload; 89 bool signal_reload;
@@ -157,6 +157,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -157,6 +157,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
157 #define ERROR_HTTP_PARSE_URI 800 157 #define ERROR_HTTP_PARSE_URI 800
158 #define ERROR_HTTP_DATA_INVLIAD 801 158 #define ERROR_HTTP_DATA_INVLIAD 801
159 #define ERROR_HTTP_PARSE_HEADER 802 159 #define ERROR_HTTP_PARSE_HEADER 802
  160 +#define ERROR_HTTP_HANDLER_MATCH_URL 803
160 161
161 // system control message, 162 // system control message,
162 // not an error, but special control logic. 163 // not an error, but special control logic.