winlin

add http delivery framework

@@ -85,13 +85,6 @@ http_stream { @@ -85,13 +85,6 @@ http_stream {
85 # for example, user use ip to access the stream: rtmp://192.168.1.2/live/livestream. 85 # for example, user use ip to access the stream: rtmp://192.168.1.2/live/livestream.
86 # for which cannot identify the required vhost. 86 # for which cannot identify the required vhost.
87 vhost __defaultVhost__ { 87 vhost __defaultVhost__ {
88 - enabled on;  
89 - gop_cache on;  
90 - http {  
91 - enabled on;  
92 - mount /;  
93 - dir ./objs/nginx/html;  
94 - }  
95 } 88 }
96 89
97 # vhost for http 90 # vhost for http
@@ -103,9 +96,11 @@ vhost http.srs.com { @@ -103,9 +96,11 @@ vhost http.srs.com {
103 enabled on; 96 enabled on;
104 # the virtual directory root for this vhost to mount at 97 # the virtual directory root for this vhost to mount at
105 # for example, if mount to /hls, user access by http://server/hls 98 # for example, if mount to /hls, user access by http://server/hls
  99 + # default: /
106 mount /hls; 100 mount /hls;
107 # main dir of vhost, 101 # main dir of vhost,
108 # to delivery HTTP stream of this vhost. 102 # to delivery HTTP stream of this vhost.
  103 + # default: ./objs/nginx/html
109 dir ./objs/nginx/html; 104 dir ./objs/nginx/html;
110 } 105 }
111 } 106 }
@@ -286,7 +286,7 @@ int SrsConfDirective::parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type) @@ -286,7 +286,7 @@ int SrsConfDirective::parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type)
286 } 286 }
287 287
288 // see: ngx_conf_read_token 288 // see: ngx_conf_read_token
289 -int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<string>& args) 289 +int SrsConfDirective::read_token(SrsFileBuffer* buffer, vector<string>& args)
290 { 290 {
291 int ret = ERROR_SUCCESS; 291 int ret = ERROR_SUCCESS;
292 292
@@ -427,6 +427,11 @@ int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<string>& arg @@ -427,6 +427,11 @@ int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<string>& arg
427 return ret; 427 return ret;
428 } 428 }
429 429
  430 +bool SrsConfDirective::is_vhost()
  431 +{
  432 + return name == "vhost";
  433 +}
  434 +
430 SrsConfig::SrsConfig() 435 SrsConfig::SrsConfig()
431 { 436 {
432 show_help = false; 437 show_help = false;
@@ -777,6 +782,11 @@ bool SrsConfig::get_deamon() @@ -777,6 +782,11 @@ bool SrsConfig::get_deamon()
777 return true; 782 return true;
778 } 783 }
779 784
  785 +SrsConfDirective* SrsConfig::get_root()
  786 +{
  787 + return root;
  788 +}
  789 +
780 int SrsConfig::get_max_connections() 790 int SrsConfig::get_max_connections()
781 { 791 {
782 srs_assert(root); 792 srs_assert(root);
@@ -835,6 +845,21 @@ int SrsConfig::get_pithy_print_forwarder() @@ -835,6 +845,21 @@ int SrsConfig::get_pithy_print_forwarder()
835 return ::atoi(pithy->arg0().c_str()); 845 return ::atoi(pithy->arg0().c_str());
836 } 846 }
837 847
  848 +int SrsConfig::get_pithy_print_encoder()
  849 +{
  850 + SrsConfDirective* pithy = root->get("encoder");
  851 + if (!pithy) {
  852 + return SRS_STAGE_ENCODER_INTERVAL_MS;
  853 + }
  854 +
  855 + pithy = pithy->get("forwarder");
  856 + if (!pithy) {
  857 + return SRS_STAGE_ENCODER_INTERVAL_MS;
  858 + }
  859 +
  860 + return ::atoi(pithy->arg0().c_str());
  861 +}
  862 +
838 int SrsConfig::get_pithy_print_hls() 863 int SrsConfig::get_pithy_print_hls()
839 { 864 {
840 SrsConfDirective* pithy = root->get("pithy_print"); 865 SrsConfDirective* pithy = root->get("pithy_print");
@@ -850,6 +875,21 @@ int SrsConfig::get_pithy_print_hls() @@ -850,6 +875,21 @@ int SrsConfig::get_pithy_print_hls()
850 return ::atoi(pithy->arg0().c_str()); 875 return ::atoi(pithy->arg0().c_str());
851 } 876 }
852 877
  878 +int SrsConfig::get_pithy_print_play()
  879 +{
  880 + SrsConfDirective* pithy = root->get("pithy_print");
  881 + if (!pithy) {
  882 + return SRS_STAGE_PLAY_USER_INTERVAL_MS;
  883 + }
  884 +
  885 + pithy = pithy->get("play");
  886 + if (!pithy) {
  887 + return SRS_STAGE_PLAY_USER_INTERVAL_MS;
  888 + }
  889 +
  890 + return ::atoi(pithy->arg0().c_str());
  891 +}
  892 +
853 SrsConfDirective* SrsConfig::get_vhost(string vhost) 893 SrsConfDirective* SrsConfig::get_vhost(string vhost)
854 { 894 {
855 srs_assert(root); 895 srs_assert(root);
@@ -857,7 +897,7 @@ SrsConfDirective* SrsConfig::get_vhost(string vhost) @@ -857,7 +897,7 @@ SrsConfDirective* SrsConfig::get_vhost(string vhost)
857 for (int i = 0; i < (int)root->directives.size(); i++) { 897 for (int i = 0; i < (int)root->directives.size(); i++) {
858 SrsConfDirective* conf = root->at(i); 898 SrsConfDirective* conf = root->at(i);
859 899
860 - if (conf->name != "vhost") { 900 + if (!conf->is_vhost()) {
861 continue; 901 continue;
862 } 902 }
863 903
@@ -1116,7 +1156,7 @@ SrsConfDirective* SrsConfig::get_refer_publish(string vhost) @@ -1116,7 +1156,7 @@ SrsConfDirective* SrsConfig::get_refer_publish(string vhost)
1116 return conf->get("refer_publish"); 1156 return conf->get("refer_publish");
1117 } 1157 }
1118 1158
1119 -int SrsConfig::get_chunk_size(const std::string &vhost) 1159 +int SrsConfig::get_chunk_size(const string &vhost)
1120 { 1160 {
1121 SrsConfDirective* conf = get_vhost(vhost); 1161 SrsConfDirective* conf = get_vhost(vhost);
1122 1162
@@ -1271,7 +1311,7 @@ string SrsConfig::get_transcode_ffmpeg(SrsConfDirective* transcode) @@ -1271,7 +1311,7 @@ string SrsConfig::get_transcode_ffmpeg(SrsConfDirective* transcode)
1271 return conf->arg0(); 1311 return conf->arg0();
1272 } 1312 }
1273 1313
1274 -void SrsConfig::get_transcode_engines(SrsConfDirective* transcode, std::vector<SrsConfDirective*>& engines) 1314 +void SrsConfig::get_transcode_engines(SrsConfDirective* transcode, vector<SrsConfDirective*>& engines)
1275 { 1315 {
1276 if (!transcode) { 1316 if (!transcode) {
1277 return; 1317 return;
@@ -1414,7 +1454,7 @@ string SrsConfig::get_engine_vpreset(SrsConfDirective* engine) @@ -1414,7 +1454,7 @@ string SrsConfig::get_engine_vpreset(SrsConfDirective* engine)
1414 return conf->arg0(); 1454 return conf->arg0();
1415 } 1455 }
1416 1456
1417 -void SrsConfig::get_engine_vparams(SrsConfDirective* engine, std::vector<string>& vparams) 1457 +void SrsConfig::get_engine_vparams(SrsConfDirective* engine, vector<string>& vparams)
1418 { 1458 {
1419 if (!engine) { 1459 if (!engine) {
1420 return; 1460 return;
@@ -1436,7 +1476,7 @@ void SrsConfig::get_engine_vparams(SrsConfDirective* engine, std::vector<string> @@ -1436,7 +1476,7 @@ void SrsConfig::get_engine_vparams(SrsConfDirective* engine, std::vector<string>
1436 } 1476 }
1437 } 1477 }
1438 1478
1439 -void SrsConfig::get_engine_vfilter(SrsConfDirective* engine, std::vector<string>& vfilter) 1479 +void SrsConfig::get_engine_vfilter(SrsConfDirective* engine, vector<string>& vfilter)
1440 { 1480 {
1441 if (!engine) { 1481 if (!engine) {
1442 return; 1482 return;
@@ -1514,7 +1554,7 @@ int SrsConfig::get_engine_achannels(SrsConfDirective* engine) @@ -1514,7 +1554,7 @@ int SrsConfig::get_engine_achannels(SrsConfDirective* engine)
1514 return ::atoi(conf->arg0().c_str()); 1554 return ::atoi(conf->arg0().c_str());
1515 } 1555 }
1516 1556
1517 -void SrsConfig::get_engine_aparams(SrsConfDirective* engine, std::vector<string>& aparams) 1557 +void SrsConfig::get_engine_aparams(SrsConfDirective* engine, vector<string>& aparams)
1518 { 1558 {
1519 if (!engine) { 1559 if (!engine) {
1520 return; 1560 return;
@@ -1754,34 +1794,68 @@ int SrsConfig::get_http_stream_listen() @@ -1754,34 +1794,68 @@ int SrsConfig::get_http_stream_listen()
1754 return 8080; 1794 return 8080;
1755 } 1795 }
1756 1796
1757 -int SrsConfig::get_pithy_print_encoder() 1797 +bool SrsConfig::get_vhost_http_enabled(string vhost)
1758 { 1798 {
1759 - SrsConfDirective* pithy = root->get("encoder");  
1760 - if (!pithy) {  
1761 - return SRS_STAGE_ENCODER_INTERVAL_MS; 1799 + SrsConfDirective* conf = get_vhost(vhost);
  1800 + if (!conf) {
  1801 + return false;
1762 } 1802 }
1763 1803
1764 - pithy = pithy->get("forwarder");  
1765 - if (!pithy) {  
1766 - return SRS_STAGE_ENCODER_INTERVAL_MS; 1804 + conf = conf->get("http");
  1805 + if (!conf) {
  1806 + return false;
1767 } 1807 }
1768 1808
1769 - return ::atoi(pithy->arg0().c_str()); 1809 + conf = conf->get("enabled");
  1810 + if (!conf) {
  1811 + return false;
  1812 + }
  1813 +
  1814 + if (conf->arg0() == "on") {
  1815 + return true;
  1816 + }
  1817 +
  1818 + return false;
1770 } 1819 }
1771 1820
1772 -int SrsConfig::get_pithy_print_play() 1821 +string SrsConfig::get_vhost_http_mount(string vhost)
1773 { 1822 {
1774 - SrsConfDirective* pithy = root->get("pithy_print");  
1775 - if (!pithy) {  
1776 - return SRS_STAGE_PLAY_USER_INTERVAL_MS; 1823 + SrsConfDirective* conf = get_vhost(vhost);
  1824 + if (!conf) {
  1825 + return SRS_CONF_DEFAULT_HTTP_MOUNT;
1777 } 1826 }
1778 1827
1779 - pithy = pithy->get("play");  
1780 - if (!pithy) {  
1781 - return SRS_STAGE_PLAY_USER_INTERVAL_MS; 1828 + conf = conf->get("http");
  1829 + if (!conf) {
  1830 + return SRS_CONF_DEFAULT_HTTP_MOUNT;
1782 } 1831 }
1783 1832
1784 - return ::atoi(pithy->arg0().c_str()); 1833 + conf = conf->get("mount");
  1834 + if (!conf || conf->arg0().empty()) {
  1835 + return SRS_CONF_DEFAULT_HTTP_MOUNT;
  1836 + }
  1837 +
  1838 + return conf->arg0();
  1839 +}
  1840 +
  1841 +string SrsConfig::get_vhost_http_dir(string vhost)
  1842 +{
  1843 + SrsConfDirective* conf = get_vhost(vhost);
  1844 + if (!conf) {
  1845 + return SRS_CONF_DEFAULT_HTTP_DIR;
  1846 + }
  1847 +
  1848 + conf = conf->get("http");
  1849 + if (!conf) {
  1850 + return SRS_CONF_DEFAULT_HTTP_DIR;
  1851 + }
  1852 +
  1853 + conf = conf->get("dir");
  1854 + if (!conf || conf->arg0().empty()) {
  1855 + return SRS_CONF_DEFAULT_HTTP_DIR;
  1856 + }
  1857 +
  1858 + return conf->arg0();
1785 } 1859 }
1786 1860
1787 bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b) 1861 bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b)
@@ -56,6 +56,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -56,6 +56,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56 // the interval in seconds for bandwidth check 56 // the interval in seconds for bandwidth check
57 #define SRS_CONF_DEFAULT_BANDWIDTH_LIMIT_KBPS 1000 57 #define SRS_CONF_DEFAULT_BANDWIDTH_LIMIT_KBPS 1000
58 58
  59 +#define SRS_CONF_DEFAULT_HTTP_MOUNT "/"
  60 +#define SRS_CONF_DEFAULT_HTTP_DIR SRS_CONF_DEFAULT_HLS_PATH
  61 +
59 #define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300 62 #define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300
60 #define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100 63 #define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100
61 #define SRS_STAGE_FORWARDER_INTERVAL_MS 2000 64 #define SRS_STAGE_FORWARDER_INTERVAL_MS 2000
@@ -86,6 +89,8 @@ public: @@ -86,6 +89,8 @@ public:
86 enum SrsDirectiveType{parse_file, parse_block}; 89 enum SrsDirectiveType{parse_file, parse_block};
87 virtual int parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type); 90 virtual int parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type);
88 virtual int read_token(SrsFileBuffer* buffer, std::vector<std::string>& args); 91 virtual int read_token(SrsFileBuffer* buffer, std::vector<std::string>& args);
  92 +public:
  93 + virtual bool is_vhost();
89 }; 94 };
90 95
91 /** 96 /**
@@ -118,6 +123,7 @@ private: @@ -118,6 +123,7 @@ private:
118 virtual void print_help(char** argv); 123 virtual void print_help(char** argv);
119 // global section 124 // global section
120 public: 125 public:
  126 + virtual SrsConfDirective* get_root();
121 virtual bool get_deamon(); 127 virtual bool get_deamon();
122 virtual int get_max_connections(); 128 virtual int get_max_connections();
123 virtual SrsConfDirective* get_listen(); 129 virtual SrsConfDirective* get_listen();
@@ -201,6 +207,10 @@ private: @@ -201,6 +207,10 @@ private:
201 public: 207 public:
202 virtual bool get_http_stream_enabled(); 208 virtual bool get_http_stream_enabled();
203 virtual int get_http_stream_listen(); 209 virtual int get_http_stream_listen();
  210 +public:
  211 + virtual bool get_vhost_http_enabled(std::string vhost);
  212 + virtual std::string get_vhost_http_mount(std::string vhost);
  213 + virtual std::string get_vhost_http_dir(std::string vhost);
204 }; 214 };
205 215
206 /** 216 /**
@@ -325,8 +325,7 @@ SrsHttpHandler* SrsHttpHandler::create_http_api() @@ -325,8 +325,7 @@ SrsHttpHandler* SrsHttpHandler::create_http_api()
325 325
326 SrsHttpHandler* SrsHttpHandler::create_http_stream() 326 SrsHttpHandler* SrsHttpHandler::create_http_stream()
327 { 327 {
328 - // TODO: FIXME: use http stream handler instead.  
329 - return new SrsHttpHandler(); 328 + return new SrsHttpRoot();
330 } 329 }
331 330
332 SrsHttpMessage::SrsHttpMessage() 331 SrsHttpMessage::SrsHttpMessage()
@@ -32,16 +32,151 @@ using namespace std; @@ -32,16 +32,151 @@ using namespace std;
32 #include <srs_kernel_error.hpp> 32 #include <srs_kernel_error.hpp>
33 #include <srs_app_socket.hpp> 33 #include <srs_app_socket.hpp>
34 #include <srs_app_http.hpp> 34 #include <srs_app_http.hpp>
35 -#include <srs_kernel_buffer.hpp>  
36 #include <srs_core_autofree.hpp> 35 #include <srs_core_autofree.hpp>
  36 +#include <srs_app_json.hpp>
  37 +#include <srs_app_config.hpp>
37 38
38 -#define SRS_HTTP_HEADER_BUFFER 1024 39 +SrsHttpRoot::SrsHttpRoot()
  40 +{
  41 + // TODO: FIXME: support reload vhosts.
  42 +}
  43 +
  44 +SrsHttpRoot::~SrsHttpRoot()
  45 +{
  46 +}
  47 +
  48 +int SrsHttpRoot::initialize()
  49 +{
  50 + int ret = ERROR_SUCCESS;
  51 +
  52 + SrsConfDirective* root = _srs_config->get_root();
  53 + for (int i = 0; i < (int)root->directives.size(); i++) {
  54 + SrsConfDirective* conf = root->at(i);
  55 +
  56 + if (!conf->is_vhost()) {
  57 + continue;
  58 + }
  59 +
  60 + std::string vhost = conf->arg0();
  61 + if (!_srs_config->get_vhost_http_enabled(vhost)) {
  62 + continue;
  63 + }
  64 +
  65 + std::string mount = _srs_config->get_vhost_http_mount(vhost);
  66 + std::string dir = _srs_config->get_vhost_http_dir(vhost);
  67 +
  68 + handlers.push_back(new SrsHttpVhost(vhost, mount, dir));
  69 + }
  70 +
  71 + return ret;
  72 +}
  73 +
  74 +bool SrsHttpRoot::is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase)
  75 +{
  76 + if (!SrsHttpHandler::is_handler_valid(req, status_code, reason_phrase)) {
  77 + return false;
  78 + }
  79 +
  80 + if (req->match()->matched_url.length() != 1) {
  81 + status_code = HTTP_NotFound;
  82 + reason_phrase = HTTP_NotFound_str;
  83 + return false;
  84 + }
  85 +
  86 + return true;
  87 +}
  88 +
  89 +bool SrsHttpRoot::can_handle(const char* path, int length, const char** pchild)
  90 +{
  91 + // reset the child path to path,
  92 + // for child to reparse the path.
  93 + *pchild = path;
  94 +
  95 + // only compare the first char.
  96 + return srs_path_equals("/", path, 1);
  97 +}
  98 +
  99 +int SrsHttpRoot::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
  100 +{
  101 + std::stringstream ss;
  102 +
  103 + ss << JOBJECT_START
  104 + << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
  105 + << JFIELD_ORG("urls", JOBJECT_START);
  106 +
  107 + vector<SrsHttpHandler*>::iterator it;
  108 + for (it = handlers.begin(); it != handlers.end(); ++it) {
  109 + SrsHttpVhost* handler = dynamic_cast<SrsHttpVhost*>(*it);
  110 + srs_assert(handler);
  111 +
  112 + ss << JFIELD_ORG(handler->mount(), JOBJECT_START)
  113 + << JFIELD_STR("mount", handler->mount()) << JFIELD_CONT
  114 + << JFIELD_STR("vhost", handler->vhost()) << JFIELD_CONT
  115 + << JFIELD_STR("dir", handler->dir())
  116 + << JOBJECT_END;
  117 +
  118 + if (it + 1 != handlers.end()) {
  119 + ss << JFIELD_CONT;
  120 + }
  121 + }
  122 +
  123 + ss << JOBJECT_END
  124 + << JOBJECT_END;
  125 +
  126 + return res_json(skt, req, ss.str());
  127 +}
  128 +
  129 +SrsHttpVhost::SrsHttpVhost(std::string vhost, std::string mount, std::string dir)
  130 +{
  131 + _vhost = vhost;
  132 + _mount = mount;
  133 + _dir = dir;
  134 +}
  135 +
  136 +SrsHttpVhost::~SrsHttpVhost()
  137 +{
  138 +}
  139 +
  140 +bool SrsHttpVhost::can_handle(const char* path, int length, const char** /*pchild*/)
  141 +{
  142 + return srs_path_equals("/api", path, length);
  143 +}
  144 +
  145 +int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
  146 +{
  147 + std::stringstream ss;
  148 +
  149 + ss << JOBJECT_START
  150 + << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
  151 + << JFIELD_ORG("urls", JOBJECT_START)
  152 + << JFIELD_STR("v1", "the api version 1.0")
  153 + << JOBJECT_END
  154 + << JOBJECT_END;
  155 +
  156 + return res_json(skt, req, ss.str());
  157 +}
  158 +
  159 +string SrsHttpVhost::vhost()
  160 +{
  161 + return _vhost;
  162 +}
  163 +
  164 +string SrsHttpVhost::mount()
  165 +{
  166 + return _mount;
  167 +}
  168 +
  169 +string SrsHttpVhost::dir()
  170 +{
  171 + return _dir;
  172 +}
39 173
40 SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler) 174 SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler)
41 : SrsConnection(srs_server, client_stfd) 175 : SrsConnection(srs_server, client_stfd)
42 { 176 {
43 parser = new SrsHttpParser(); 177 parser = new SrsHttpParser();
44 handler = _handler; 178 handler = _handler;
  179 + requires_crossdomain = false;
45 } 180 }
46 181
47 SrsHttpConn::~SrsHttpConn() 182 SrsHttpConn::~SrsHttpConn()
@@ -96,34 +231,41 @@ int SrsHttpConn::do_cycle() @@ -96,34 +231,41 @@ int SrsHttpConn::do_cycle()
96 int SrsHttpConn::process_request(SrsSocket* skt, SrsHttpMessage* req) 231 int SrsHttpConn::process_request(SrsSocket* skt, SrsHttpMessage* req)
97 { 232 {
98 int ret = ERROR_SUCCESS; 233 int ret = ERROR_SUCCESS;
  234 +
  235 + // parse uri to schema/server:port/path?query
  236 + if ((ret = req->parse_uri()) != ERROR_SUCCESS) {
  237 + return ret;
  238 + }
99 239
100 - if (req->method() == HTTP_OPTIONS) {  
101 - char data[] = "HTTP/1.1 200 OK" __CRLF  
102 - "Content-Length: 0"__CRLF  
103 - "Server: SRS/"RTMP_SIG_SRS_VERSION""__CRLF  
104 - "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT"__CRLF  
105 - "Access-Control-Allow-Origin: *"__CRLF  
106 - "Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE"__CRLF  
107 - "Access-Control-Allow-Headers: Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type"__CRLF  
108 - "Content-Type: text/html;charset=utf-8"__CRLFCRLF  
109 - "";  
110 - return skt->write(data, sizeof(data), NULL);  
111 - } else {  
112 - std::string tilte = "SRS/"RTMP_SIG_SRS_VERSION;  
113 - tilte += " hello http/1.1 server~\n";  
114 -  
115 - std::stringstream ss;  
116 - ss << "HTTP/1.1 200 OK " << __CRLF  
117 - << "Content-Length: "<< tilte.length() + req->body_size() << __CRLF  
118 - << "Server: SRS/"RTMP_SIG_SRS_VERSION"" << __CRLF  
119 - << "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF  
120 - << "Access-Control-Allow-Origin: *" << __CRLF  
121 - << "Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE" << __CRLF  
122 - << "Access-Control-Allow-Headers: Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type" << __CRLF  
123 - << "Content-Type: text/html;charset=utf-8" << __CRLFCRLF  
124 - << tilte << req->body().c_str()  
125 - << "";  
126 - return skt->write(ss.str().c_str(), ss.str().length(), NULL); 240 + srs_trace("http request parsed, method=%d, url=%s, content-length=%"PRId64"",
  241 + req->method(), req->url().c_str(), req->content_length());
  242 +
  243 + // TODO: maybe need to parse the url.
  244 + std::string url = req->path();
  245 +
  246 + SrsHttpHandlerMatch* p = NULL;
  247 + if ((ret = handler->best_match(url.data(), url.length(), &p)) != ERROR_SUCCESS) {
  248 + srs_warn("failed to find the best match handler for url. ret=%d", ret);
  249 + return ret;
  250 + }
  251 +
  252 + // if success, p and pstart should be valid.
  253 + srs_assert(p);
  254 + srs_assert(p->handler);
  255 + srs_assert(p->matched_url.length() <= url.length());
  256 + srs_info("best match handler, matched_url=%s", p->matched_url.c_str());
  257 +
  258 + req->set_match(p);
  259 + req->set_requires_crossdomain(requires_crossdomain);
  260 +
  261 + // use handler to process request.
  262 + if ((ret = p->handler->process_request(skt, req)) != ERROR_SUCCESS) {
  263 + srs_warn("handler failed to process http request. ret=%d", ret);
  264 + return ret;
  265 + }
  266 +
  267 + if (req->requires_crossdomain()) {
  268 + requires_crossdomain = true;
127 } 269 }
128 270
129 return ret; 271 return ret;
@@ -34,19 +34,50 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -34,19 +34,50 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 34
35 #include <srs_app_st.hpp> 35 #include <srs_app_st.hpp>
36 #include <srs_app_conn.hpp> 36 #include <srs_app_conn.hpp>
37 -  
38 -#include <http_parser.h> 37 +#include <srs_app_http.hpp>
39 38
40 class SrsSocket; 39 class SrsSocket;
41 class SrsHttpParser; 40 class SrsHttpParser;
42 class SrsHttpMessage; 41 class SrsHttpMessage;
43 class SrsHttpHandler; 42 class SrsHttpHandler;
44 43
  44 +// for http root.
  45 +class SrsHttpRoot : public SrsHttpHandler
  46 +{
  47 +public:
  48 + SrsHttpRoot();
  49 + virtual ~SrsHttpRoot();
  50 +public:
  51 + virtual int initialize();
  52 + virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase);
  53 + virtual bool can_handle(const char* path, int length, const char** pchild);
  54 + virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
  55 +};
  56 +
  57 +class SrsHttpVhost : public SrsHttpHandler
  58 +{
  59 +private:
  60 + std::string _vhost;
  61 + std::string _mount;
  62 + std::string _dir;
  63 +public:
  64 + SrsHttpVhost(std::string vhost, std::string mount, std::string dir);
  65 + virtual ~SrsHttpVhost();
  66 +public:
  67 + virtual bool can_handle(const char* path, int length, const char** pchild);
  68 + virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
  69 +public:
  70 + virtual std::string vhost();
  71 + virtual std::string mount();
  72 + virtual std::string dir();
  73 +};
  74 +
45 class SrsHttpConn : public SrsConnection 75 class SrsHttpConn : public SrsConnection
46 { 76 {
47 private: 77 private:
48 SrsHttpParser* parser; 78 SrsHttpParser* parser;
49 SrsHttpHandler* handler; 79 SrsHttpHandler* handler;
  80 + bool requires_crossdomain;
50 public: 81 public:
51 SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler); 82 SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler);
52 virtual ~SrsHttpConn(); 83 virtual ~SrsHttpConn();
@@ -36,5 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -36,5 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 #define JFIELD_ERROR(ret) "\"" << "code" << "\":" << ret 36 #define JFIELD_ERROR(ret) "\"" << "code" << "\":" << ret
37 #define JFIELD_CONT "," 37 #define JFIELD_CONT ","
38 #define JOBJECT_END "}" 38 #define JOBJECT_END "}"
  39 +#define JARRAY_START "["
  40 +#define JARRAY_END "]"
39 41
40 #endif 42 #endif