正在显示
7 个修改的文件
包含
316 行增加
和
63 行删除
| @@ -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 |
-
请 注册 或 登录 后发表评论