正在显示
5 个修改的文件
包含
172 行增加
和
0 行删除
@@ -34,6 +34,7 @@ using namespace std; | @@ -34,6 +34,7 @@ using namespace std; | ||
34 | #include <srs_app_socket.hpp> | 34 | #include <srs_app_socket.hpp> |
35 | #include <srs_app_http_api.hpp> | 35 | #include <srs_app_http_api.hpp> |
36 | #include <srs_app_http_conn.hpp> | 36 | #include <srs_app_http_conn.hpp> |
37 | +#include <srs_app_json.hpp> | ||
37 | 38 | ||
38 | #define SRS_DEFAULT_HTTP_PORT 80 | 39 | #define SRS_DEFAULT_HTTP_PORT 80 |
39 | 40 | ||
@@ -85,10 +86,39 @@ int SrsHttpHandler::process_request(SrsSocket* skt, SrsHttpMessage* req) | @@ -85,10 +86,39 @@ int SrsHttpHandler::process_request(SrsSocket* skt, SrsHttpMessage* req) | ||
85 | if (req->method() == HTTP_OPTIONS) { | 86 | if (req->method() == HTTP_OPTIONS) { |
86 | return res_options(skt); | 87 | return res_options(skt); |
87 | } | 88 | } |
89 | + | ||
90 | + int status_code; | ||
91 | + std::string reason_phrase; | ||
92 | + if (!is_handler_valid(req, status_code, reason_phrase)) { | ||
93 | + std::stringstream ss; | ||
94 | + | ||
95 | + ss << JOBJECT_START | ||
96 | + << JFIELD_ERROR(ERROR_HTTP_HANDLER_INVALID) << JFIELD_CONT | ||
97 | + << JFIELD_ORG("data", JOBJECT_START) | ||
98 | + << JFIELD_ORG("status_code", status_code) << JFIELD_CONT | ||
99 | + << JFIELD_STR("reason_phrase", reason_phrase) << JFIELD_CONT | ||
100 | + << JFIELD_STR("url", req->url()) | ||
101 | + << JOBJECT_END | ||
102 | + << JOBJECT_END; | ||
103 | + | ||
104 | + return res_error(skt, status_code, reason_phrase, ss.str()); | ||
105 | + } | ||
88 | 106 | ||
89 | return do_process_request(skt, req); | 107 | return do_process_request(skt, req); |
90 | } | 108 | } |
91 | 109 | ||
110 | +bool SrsHttpHandler::is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase) | ||
111 | +{ | ||
112 | + if (!req->match()->unmatched_url.empty()) { | ||
113 | + status_code = HTTP_NotFound; | ||
114 | + reason_phrase = HTTP_NotFound_str; | ||
115 | + | ||
116 | + return false; | ||
117 | + } | ||
118 | + | ||
119 | + return true; | ||
120 | +} | ||
121 | + | ||
92 | int SrsHttpHandler::do_process_request(SrsSocket* /*skt*/, SrsHttpMessage* /*req*/) | 122 | int SrsHttpHandler::do_process_request(SrsSocket* /*skt*/, SrsHttpMessage* /*req*/) |
93 | { | 123 | { |
94 | int ret = ERROR_SUCCESS; | 124 | int ret = ERROR_SUCCESS; |
@@ -156,6 +186,11 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandlerMatch | @@ -156,6 +186,11 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandlerMatch | ||
156 | (*ppmatch)->handler = handler; | 186 | (*ppmatch)->handler = handler; |
157 | (*ppmatch)->matched_url.append(match_start, match_length); | 187 | (*ppmatch)->matched_url.append(match_start, match_length); |
158 | 188 | ||
189 | + int unmatch_length = length - match_length; | ||
190 | + if (unmatch_length > 0) { | ||
191 | + (*ppmatch)->unmatched_url.append(match_start + match_length, unmatch_length); | ||
192 | + } | ||
193 | + | ||
159 | return ret; | 194 | return ret; |
160 | } | 195 | } |
161 | 196 | ||
@@ -166,6 +201,13 @@ SrsHttpHandler* SrsHttpHandler::res_status_line(std::stringstream& ss) | @@ -166,6 +201,13 @@ SrsHttpHandler* SrsHttpHandler::res_status_line(std::stringstream& ss) | ||
166 | return this; | 201 | return this; |
167 | } | 202 | } |
168 | 203 | ||
204 | +SrsHttpHandler* SrsHttpHandler::res_status_line_error(std::stringstream& ss, int code, std::string reason_phrase) | ||
205 | +{ | ||
206 | + ss << "HTTP/1.1 " << code << " " << reason_phrase << __CRLF | ||
207 | + << "Server: SRS/"RTMP_SIG_SRS_VERSION"" << __CRLF; | ||
208 | + return this; | ||
209 | +} | ||
210 | + | ||
169 | SrsHttpHandler* SrsHttpHandler::res_content_type(std::stringstream& ss) | 211 | SrsHttpHandler* SrsHttpHandler::res_content_type(std::stringstream& ss) |
170 | { | 212 | { |
171 | ss << "Content-Type: text/html;charset=utf-8" << __CRLF | 213 | ss << "Content-Type: text/html;charset=utf-8" << __CRLF |
@@ -248,6 +290,22 @@ int SrsHttpHandler::res_json(SrsSocket* skt, std::string json) | @@ -248,6 +290,22 @@ int SrsHttpHandler::res_json(SrsSocket* skt, std::string json) | ||
248 | return res_flush(skt, ss); | 290 | return res_flush(skt, ss); |
249 | } | 291 | } |
250 | 292 | ||
293 | +int SrsHttpHandler::res_error(SrsSocket* skt, int code, std::string reason_phrase, std::string body) | ||
294 | +{ | ||
295 | + std::stringstream ss; | ||
296 | + | ||
297 | + ss << "HTTP/1.1 " << code << " " << reason_phrase << __CRLF | ||
298 | + << "Server: SRS/"RTMP_SIG_SRS_VERSION"" << __CRLF; | ||
299 | + | ||
300 | + res_status_line_error(ss, code, reason_phrase) | ||
301 | + ->res_content_type_json(ss) | ||
302 | + ->res_content_length(ss, (int)body.length()) | ||
303 | + ->res_header_eof(ss) | ||
304 | + ->res_body(ss, body); | ||
305 | + | ||
306 | + return res_flush(skt, ss); | ||
307 | +} | ||
308 | + | ||
251 | SrsHttpHandler* SrsHttpHandler::create_http_api() | 309 | SrsHttpHandler* SrsHttpHandler::create_http_api() |
252 | { | 310 | { |
253 | return new SrsApiRoot(); | 311 | return new SrsApiRoot(); |
@@ -62,6 +62,89 @@ class SrsHttpHandler; | @@ -62,6 +62,89 @@ class SrsHttpHandler; | ||
62 | #define __CRLF "\r\n" // 0x0D0A | 62 | #define __CRLF "\r\n" // 0x0D0A |
63 | #define __CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A | 63 | #define __CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A |
64 | 64 | ||
65 | +// 6.1.1 Status Code and Reason Phrase | ||
66 | +#define HTTP_Continue 100 | ||
67 | +#define HTTP_SwitchingProtocols 101 | ||
68 | +#define HTTP_OK 200 | ||
69 | +#define HTTP_Created 201 | ||
70 | +#define HTTP_Accepted 202 | ||
71 | +#define HTTP_NonAuthoritativeInformation 203 | ||
72 | +#define HTTP_NoContent 204 | ||
73 | +#define HTTP_ResetContent 205 | ||
74 | +#define HTTP_PartialContent 206 | ||
75 | +#define HTTP_MultipleChoices 300 | ||
76 | +#define HTTP_MovedPermanently 301 | ||
77 | +#define HTTP_Found 302 | ||
78 | +#define HTTP_SeeOther 303 | ||
79 | +#define HTTP_NotModified 304 | ||
80 | +#define HTTP_UseProxy 305 | ||
81 | +#define HTTP_TemporaryRedirect 307 | ||
82 | +#define HTTP_BadRequest 400 | ||
83 | +#define HTTP_Unauthorized 401 | ||
84 | +#define HTTP_PaymentRequired 402 | ||
85 | +#define HTTP_Forbidden 403 | ||
86 | +#define HTTP_NotFound 404 | ||
87 | +#define HTTP_MethodNotAllowed 405 | ||
88 | +#define HTTP_NotAcceptable 406 | ||
89 | +#define HTTP_ProxyAuthenticationRequired 407 | ||
90 | +#define HTTP_RequestTimeout 408 | ||
91 | +#define HTTP_Conflict 409 | ||
92 | +#define HTTP_Gone 410 | ||
93 | +#define HTTP_LengthRequired 411 | ||
94 | +#define HTTP_PreconditionFailed 412 | ||
95 | +#define HTTP_RequestEntityTooLarge 413 | ||
96 | +#define HTTP_RequestURITooLarge 414 | ||
97 | +#define HTTP_UnsupportedMediaType 415 | ||
98 | +#define HTTP_RequestedRangeNotSatisfiable 416 | ||
99 | +#define HTTP_ExpectationFailed 417 | ||
100 | +#define HTTP_InternalServerError 500 | ||
101 | +#define HTTP_NotImplemented 501 | ||
102 | +#define HTTP_BadGateway 502 | ||
103 | +#define HTTP_ServiceUnavailable 503 | ||
104 | +#define HTTP_GatewayTimeout 504 | ||
105 | +#define HTTP_HTTPVersionNotSupported 505 | ||
106 | + | ||
107 | +#define HTTP_Continue_str "Continue" | ||
108 | +#define HTTP_SwitchingProtocols_str "Switching Protocols" | ||
109 | +#define HTTP_OK_str "OK" | ||
110 | +#define HTTP_Created_str "Created " | ||
111 | +#define HTTP_Accepted_str "Accepted" | ||
112 | +#define HTTP_NonAuthoritativeInformation_str "Non Authoritative Information " | ||
113 | +#define HTTP_NoContent_str "No Content " | ||
114 | +#define HTTP_ResetContent_str "Reset Content" | ||
115 | +#define HTTP_PartialContent_str "Partial Content" | ||
116 | +#define HTTP_MultipleChoices_str "Multiple Choices " | ||
117 | +#define HTTP_MovedPermanently_str "Moved Permanently" | ||
118 | +#define HTTP_Found_str "Found" | ||
119 | +#define HTTP_SeeOther_str "See Other" | ||
120 | +#define HTTP_NotModified_str "Not Modified " | ||
121 | +#define HTTP_UseProxy_str "Use Proxy" | ||
122 | +#define HTTP_TemporaryRedirect_str "Temporary Redirect " | ||
123 | +#define HTTP_BadRequest_str "Bad Request" | ||
124 | +#define HTTP_Unauthorized_str "Unauthorized" | ||
125 | +#define HTTP_PaymentRequired_str "Payment Required " | ||
126 | +#define HTTP_Forbidden_str "Forbidden " | ||
127 | +#define HTTP_NotFound_str "Not Found" | ||
128 | +#define HTTP_MethodNotAllowed_str "Method Not Allowed" | ||
129 | +#define HTTP_NotAcceptable_str "Not Acceptable " | ||
130 | +#define HTTP_ProxyAuthenticationRequired_str "Proxy Authentication Required " | ||
131 | +#define HTTP_RequestTimeout_str "Request Timeout" | ||
132 | +#define HTTP_Conflict_str "Conflict" | ||
133 | +#define HTTP_Gone_str "Gone" | ||
134 | +#define HTTP_LengthRequired_str "Length Required" | ||
135 | +#define HTTP_PreconditionFailed_str "Precondition Failed" | ||
136 | +#define HTTP_RequestEntityTooLarge_str "Request Entity Too Large " | ||
137 | +#define HTTP_RequestURITooLarge_str "Request URI Too Large" | ||
138 | +#define HTTP_UnsupportedMediaType_str "Unsupported Media Type" | ||
139 | +#define HTTP_RequestedRangeNotSatisfiable_str "Requested Range Not Satisfiable" | ||
140 | +#define HTTP_ExpectationFailed_str "Expectation Failed " | ||
141 | +#define HTTP_InternalServerError_str "Internal Server Error " | ||
142 | +#define HTTP_NotImplemented_str "Not Implemented" | ||
143 | +#define HTTP_BadGateway_str "Bad Gateway" | ||
144 | +#define HTTP_ServiceUnavailable_str "Service Unavailable" | ||
145 | +#define HTTP_GatewayTimeout_str "Gateway Timeout" | ||
146 | +#define HTTP_HTTPVersionNotSupported_str "HTTP Version Not Supported" | ||
147 | + | ||
65 | // linux path seprator | 148 | // linux path seprator |
66 | #define __PATH_SEP '/' | 149 | #define __PATH_SEP '/' |
67 | // query string seprator | 150 | // query string seprator |
@@ -86,6 +169,7 @@ class SrsHttpHandlerMatch | @@ -86,6 +169,7 @@ class SrsHttpHandlerMatch | ||
86 | public: | 169 | public: |
87 | SrsHttpHandler* handler; | 170 | SrsHttpHandler* handler; |
88 | std::string matched_url; | 171 | std::string matched_url; |
172 | + std::string unmatched_url; | ||
89 | public: | 173 | public: |
90 | SrsHttpHandlerMatch(); | 174 | SrsHttpHandlerMatch(); |
91 | }; | 175 | }; |
@@ -127,10 +211,22 @@ public: | @@ -127,10 +211,22 @@ public: | ||
127 | virtual int best_match(const char* path, int length, SrsHttpHandlerMatch** ppmatch); | 211 | virtual int best_match(const char* path, int length, SrsHttpHandlerMatch** ppmatch); |
128 | // factory methods | 212 | // factory methods |
129 | protected: | 213 | protected: |
214 | + /** | ||
215 | + * check whether the handler is valid. | ||
216 | + * for example, user access /apis, actually it's not found, | ||
217 | + * we will find the root handler to process it. | ||
218 | + * @remark user can override this method, and should invoke it first. | ||
219 | + * @see SrsApiRoot::is_handler_valid | ||
220 | + */ | ||
221 | + virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase); | ||
222 | + /** | ||
223 | + * do the actual process of request. | ||
224 | + */ | ||
130 | virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); | 225 | virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); |
131 | // response writer | 226 | // response writer |
132 | public: | 227 | public: |
133 | virtual SrsHttpHandler* res_status_line(std::stringstream& ss); | 228 | virtual SrsHttpHandler* res_status_line(std::stringstream& ss); |
229 | + virtual SrsHttpHandler* res_status_line_error(std::stringstream& ss, int code, std::string reason_phrase); | ||
134 | virtual SrsHttpHandler* res_content_type(std::stringstream& ss); | 230 | virtual SrsHttpHandler* res_content_type(std::stringstream& ss); |
135 | virtual SrsHttpHandler* res_content_type_json(std::stringstream& ss); | 231 | virtual SrsHttpHandler* res_content_type_json(std::stringstream& ss); |
136 | virtual SrsHttpHandler* res_content_length(std::stringstream& ss, int64_t length); | 232 | virtual SrsHttpHandler* res_content_length(std::stringstream& ss, int64_t length); |
@@ -142,6 +238,7 @@ public: | @@ -142,6 +238,7 @@ public: | ||
142 | virtual int res_options(SrsSocket* skt); | 238 | virtual int res_options(SrsSocket* skt); |
143 | virtual int res_text(SrsSocket* skt, std::string body); | 239 | virtual int res_text(SrsSocket* skt, std::string body); |
144 | virtual int res_json(SrsSocket* skt, std::string json); | 240 | virtual int res_json(SrsSocket* skt, std::string json); |
241 | + virtual int res_error(SrsSocket* skt, int code, std::string reason_phrase, std::string body); | ||
145 | // object creator | 242 | // object creator |
146 | public: | 243 | public: |
147 | /** | 244 | /** |
@@ -44,6 +44,21 @@ SrsApiRoot::~SrsApiRoot() | @@ -44,6 +44,21 @@ SrsApiRoot::~SrsApiRoot() | ||
44 | { | 44 | { |
45 | } | 45 | } |
46 | 46 | ||
47 | +bool SrsApiRoot::is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase) | ||
48 | +{ | ||
49 | + if (!SrsHttpHandler::is_handler_valid(req, status_code, reason_phrase)) { | ||
50 | + return false; | ||
51 | + } | ||
52 | + | ||
53 | + if (req->match()->matched_url.length() != 1) { | ||
54 | + status_code = HTTP_NotFound; | ||
55 | + reason_phrase = HTTP_NotFound_str; | ||
56 | + return false; | ||
57 | + } | ||
58 | + | ||
59 | + return true; | ||
60 | +} | ||
61 | + | ||
47 | bool SrsApiRoot::can_handle(const char* path, int length, const char** pchild) | 62 | bool SrsApiRoot::can_handle(const char* path, int length, const char** pchild) |
48 | { | 63 | { |
49 | // reset the child path to path, | 64 | // reset the child path to path, |
@@ -48,6 +48,7 @@ public: | @@ -48,6 +48,7 @@ public: | ||
48 | SrsApiRoot(); | 48 | SrsApiRoot(); |
49 | virtual ~SrsApiRoot(); | 49 | virtual ~SrsApiRoot(); |
50 | public: | 50 | public: |
51 | + virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase); | ||
51 | virtual bool can_handle(const char* path, int length, const char** pchild); | 52 | virtual bool can_handle(const char* path, int length, const char** pchild); |
52 | virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); | 53 | virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); |
53 | }; | 54 | }; |
@@ -158,6 +158,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -158,6 +158,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
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 | #define ERROR_HTTP_HANDLER_MATCH_URL 803 |
161 | +#define ERROR_HTTP_HANDLER_INVALID 804 | ||
161 | 162 | ||
162 | // system control message, | 163 | // system control message, |
163 | // not an error, but special control logic. | 164 | // not an error, but special control logic. |
-
请 注册 或 登录 后发表评论