正在显示
8 个修改的文件
包含
849 行增加
和
33 行删除
| @@ -62,7 +62,7 @@ int srs_go_http_response_json(ISrsGoHttpResponseWriter* w, string data) | @@ -62,7 +62,7 @@ int srs_go_http_response_json(ISrsGoHttpResponseWriter* w, string data) | ||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | // get the status text of code. | 64 | // get the status text of code. |
| 65 | -string srs_generate_status_text(int status) | 65 | +string srs_generate_http_status_text(int status) |
| 66 | { | 66 | { |
| 67 | static std::map<int, std::string> _status_map; | 67 | static std::map<int, std::string> _status_map; |
| 68 | if (_status_map.empty()) { | 68 | if (_status_map.empty()) { |
| @@ -212,7 +212,7 @@ void SrsGoHttpHeader::write(stringstream& ss) | @@ -212,7 +212,7 @@ void SrsGoHttpHeader::write(stringstream& ss) | ||
| 212 | { | 212 | { |
| 213 | std::map<std::string, std::string>::iterator it; | 213 | std::map<std::string, std::string>::iterator it; |
| 214 | for (it = headers.begin(); it != headers.end(); ++it) { | 214 | for (it = headers.begin(); it != headers.end(); ++it) { |
| 215 | - ss << it->first << ": " << it->second << __SRS_CRLF; | 215 | + ss << it->first << ": " << it->second << __SRS_HTTP_CRLF; |
| 216 | } | 216 | } |
| 217 | } | 217 | } |
| 218 | 218 | ||
| @@ -711,7 +711,7 @@ int SrsGoHttpResponseWriter::final_request() | @@ -711,7 +711,7 @@ int SrsGoHttpResponseWriter::final_request() | ||
| 711 | // complete the chunked encoding. | 711 | // complete the chunked encoding. |
| 712 | if (content_length == -1) { | 712 | if (content_length == -1) { |
| 713 | std::stringstream ss; | 713 | std::stringstream ss; |
| 714 | - ss << 0 << __SRS_CRLF << __SRS_CRLF; | 714 | + ss << 0 << __SRS_HTTP_CRLF << __SRS_HTTP_CRLF; |
| 715 | std::string ch = ss.str(); | 715 | std::string ch = ss.str(); |
| 716 | return skt->write((void*)ch.data(), (int)ch.length(), NULL); | 716 | return skt->write((void*)ch.data(), (int)ch.length(), NULL); |
| 717 | } | 717 | } |
| @@ -752,7 +752,7 @@ int SrsGoHttpResponseWriter::write(char* data, int size) | @@ -752,7 +752,7 @@ int SrsGoHttpResponseWriter::write(char* data, int size) | ||
| 752 | 752 | ||
| 753 | // send in chunked encoding. | 753 | // send in chunked encoding. |
| 754 | std::stringstream ss; | 754 | std::stringstream ss; |
| 755 | - ss << hex << size << __SRS_CRLF; | 755 | + ss << hex << size << __SRS_HTTP_CRLF; |
| 756 | std::string ch = ss.str(); | 756 | std::string ch = ss.str(); |
| 757 | if ((ret = skt->write((void*)ch.data(), (int)ch.length(), NULL)) != ERROR_SUCCESS) { | 757 | if ((ret = skt->write((void*)ch.data(), (int)ch.length(), NULL)) != ERROR_SUCCESS) { |
| 758 | return ret; | 758 | return ret; |
| @@ -760,7 +760,7 @@ int SrsGoHttpResponseWriter::write(char* data, int size) | @@ -760,7 +760,7 @@ int SrsGoHttpResponseWriter::write(char* data, int size) | ||
| 760 | if ((ret = skt->write((void*)data, size, NULL)) != ERROR_SUCCESS) { | 760 | if ((ret = skt->write((void*)data, size, NULL)) != ERROR_SUCCESS) { |
| 761 | return ret; | 761 | return ret; |
| 762 | } | 762 | } |
| 763 | - if ((ret = skt->write((void*)__SRS_CRLF, 2, NULL)) != ERROR_SUCCESS) { | 763 | + if ((ret = skt->write((void*)__SRS_HTTP_CRLF, 2, NULL)) != ERROR_SUCCESS) { |
| 764 | return ret; | 764 | return ret; |
| 765 | } | 765 | } |
| 766 | 766 | ||
| @@ -794,7 +794,7 @@ int SrsGoHttpResponseWriter::send_header(char* data, int size) | @@ -794,7 +794,7 @@ int SrsGoHttpResponseWriter::send_header(char* data, int size) | ||
| 794 | 794 | ||
| 795 | // status_line | 795 | // status_line |
| 796 | ss << "HTTP/1.1 " << status << " " | 796 | ss << "HTTP/1.1 " << status << " " |
| 797 | - << srs_generate_status_text(status) << __SRS_CRLF; | 797 | + << srs_generate_http_status_text(status) << __SRS_HTTP_CRLF; |
| 798 | 798 | ||
| 799 | // detect content type | 799 | // detect content type |
| 800 | if (srs_go_http_body_allowd(status)) { | 800 | if (srs_go_http_body_allowd(status)) { |
| @@ -820,7 +820,7 @@ int SrsGoHttpResponseWriter::send_header(char* data, int size) | @@ -820,7 +820,7 @@ int SrsGoHttpResponseWriter::send_header(char* data, int size) | ||
| 820 | hdr->write(ss); | 820 | hdr->write(ss); |
| 821 | 821 | ||
| 822 | // header_eof | 822 | // header_eof |
| 823 | - ss << __SRS_CRLF; | 823 | + ss << __SRS_HTTP_CRLF; |
| 824 | 824 | ||
| 825 | std::string buf = ss.str(); | 825 | std::string buf = ss.str(); |
| 826 | return skt->write((void*)buf.c_str(), buf.length(), NULL); | 826 | return skt->write((void*)buf.c_str(), buf.length(), NULL); |
| @@ -39,6 +39,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -39,6 +39,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 39 | #include <http_parser.h> | 39 | #include <http_parser.h> |
| 40 | 40 | ||
| 41 | #include <srs_app_st.hpp> | 41 | #include <srs_app_st.hpp> |
| 42 | +#include <srs_kernel_consts.hpp> | ||
| 42 | 43 | ||
| 43 | class SrsRequest; | 44 | class SrsRequest; |
| 44 | class SrsStSocket; | 45 | class SrsStSocket; |
| @@ -51,19 +52,19 @@ class ISrsGoHttpResponseWriter; | @@ -51,19 +52,19 @@ class ISrsGoHttpResponseWriter; | ||
| 51 | 52 | ||
| 52 | // http specification | 53 | // http specification |
| 53 | // CR = <US-ASCII CR, carriage return (13)> | 54 | // CR = <US-ASCII CR, carriage return (13)> |
| 54 | -#define __SRS_CR SRS_CONSTS_CR // 0x0D | 55 | +#define __SRS_HTTP_CR SRS_CONSTS_CR // 0x0D |
| 55 | // LF = <US-ASCII LF, linefeed (10)> | 56 | // LF = <US-ASCII LF, linefeed (10)> |
| 56 | -#define __SRS_LF SRS_CONSTS_LF // 0x0A | 57 | +#define __SRS_HTTP_LF SRS_CONSTS_LF // 0x0A |
| 57 | // SP = <US-ASCII SP, space (32)> | 58 | // SP = <US-ASCII SP, space (32)> |
| 58 | -#define __SRS_SP ' ' // 0x20 | 59 | +#define __SRS_HTTP_SP ' ' // 0x20 |
| 59 | // HT = <US-ASCII HT, horizontal-tab (9)> | 60 | // HT = <US-ASCII HT, horizontal-tab (9)> |
| 60 | -#define __SRS_HT '\x09' // 0x09 | 61 | +#define __SRS_HTTP_HT '\x09' // 0x09 |
| 61 | 62 | ||
| 62 | // HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all | 63 | // HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all |
| 63 | // protocol elements except the entity-body (see appendix 19.3 for | 64 | // protocol elements except the entity-body (see appendix 19.3 for |
| 64 | // tolerant applications). | 65 | // tolerant applications). |
| 65 | -#define __SRS_CRLF "\r\n" // 0x0D0A | ||
| 66 | -#define __SRS_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A | 66 | +#define __SRS_HTTP_CRLF "\r\n" // 0x0D0A |
| 67 | +#define __SRS_HTTP_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A | ||
| 67 | 68 | ||
| 68 | // @see SrsHttpMessage._http_ts_send_buffer | 69 | // @see SrsHttpMessage._http_ts_send_buffer |
| 69 | #define __SRS_HTTP_TS_SEND_BUFFER_SIZE 4096 | 70 | #define __SRS_HTTP_TS_SEND_BUFFER_SIZE 4096 |
| @@ -76,13 +76,13 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r | @@ -76,13 +76,13 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r | ||
| 76 | // POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s | 76 | // POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s |
| 77 | std::stringstream ss; | 77 | std::stringstream ss; |
| 78 | ss << "POST " << uri->get_path() << " " | 78 | ss << "POST " << uri->get_path() << " " |
| 79 | - << "HTTP/1.1" << __SRS_CRLF | ||
| 80 | - << "Host: " << uri->get_host() << __SRS_CRLF | ||
| 81 | - << "Connection: Keep-Alive" << __SRS_CRLF | ||
| 82 | - << "Content-Length: " << std::dec << req.length() << __SRS_CRLF | ||
| 83 | - << "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << __SRS_CRLF | ||
| 84 | - << "Content-Type: application/json" << __SRS_CRLF | ||
| 85 | - << __SRS_CRLF | 79 | + << "HTTP/1.1" << __SRS_HTTP_CRLF |
| 80 | + << "Host: " << uri->get_host() << __SRS_HTTP_CRLF | ||
| 81 | + << "Connection: Keep-Alive" << __SRS_HTTP_CRLF | ||
| 82 | + << "Content-Length: " << std::dec << req.length() << __SRS_HTTP_CRLF | ||
| 83 | + << "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << __SRS_HTTP_CRLF | ||
| 84 | + << "Content-Type: application/json" << __SRS_HTTP_CRLF | ||
| 85 | + << __SRS_HTTP_CRLF | ||
| 86 | << req; | 86 | << req; |
| 87 | 87 | ||
| 88 | SrsStSocket skt(stfd); | 88 | SrsStSocket skt(stfd); |
| @@ -32,6 +32,7 @@ using namespace std; | @@ -32,6 +32,7 @@ using namespace std; | ||
| 32 | #include <srs_app_st_socket.hpp> | 32 | #include <srs_app_st_socket.hpp> |
| 33 | #include <srs_kernel_log.hpp> | 33 | #include <srs_kernel_log.hpp> |
| 34 | #include <srs_app_utility.hpp> | 34 | #include <srs_app_utility.hpp> |
| 35 | +#include <srs_core_autofree.hpp> | ||
| 35 | 36 | ||
| 36 | #ifdef SRS_AUTO_STREAM_CASTER | 37 | #ifdef SRS_AUTO_STREAM_CASTER |
| 37 | 38 | ||
| @@ -76,6 +77,28 @@ int SrsRtspConn::do_cycle() | @@ -76,6 +77,28 @@ int SrsRtspConn::do_cycle() | ||
| 76 | std::string ip = srs_get_peer_ip(st_netfd_fileno(stfd)); | 77 | std::string ip = srs_get_peer_ip(st_netfd_fileno(stfd)); |
| 77 | srs_trace("rtsp: serve %s", ip.c_str()); | 78 | srs_trace("rtsp: serve %s", ip.c_str()); |
| 78 | 79 | ||
| 80 | + // consume all rtsp messages. | ||
| 81 | + for (;;) { | ||
| 82 | + SrsRtspRequest* req = NULL; | ||
| 83 | + if ((ret = rtsp->recv_message(&req)) != ERROR_SUCCESS) { | ||
| 84 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 85 | + srs_error("rtsp: recv request failed. ret=%d", ret); | ||
| 86 | + } | ||
| 87 | + return ret; | ||
| 88 | + } | ||
| 89 | + SrsAutoFree(SrsRtspRequest, req); | ||
| 90 | + srs_info("rtsp: got rtsp request"); | ||
| 91 | + | ||
| 92 | + if (req->is_options()) { | ||
| 93 | + if ((ret = rtsp->send_message(new SrsRtspOptionsResponse(req->seq))) != ERROR_SUCCESS) { | ||
| 94 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 95 | + srs_error("rtsp: send response failed. ret=%d", ret); | ||
| 96 | + } | ||
| 97 | + return ret; | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + } | ||
| 101 | + | ||
| 79 | return ret; | 102 | return ret; |
| 80 | } | 103 | } |
| 81 | 104 |
| @@ -265,43 +265,137 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -265,43 +265,137 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 265 | #define SRS_CONSTS_HTTP_Continue_str "Continue" | 265 | #define SRS_CONSTS_HTTP_Continue_str "Continue" |
| 266 | #define SRS_CONSTS_HTTP_SwitchingProtocols_str "Switching Protocols" | 266 | #define SRS_CONSTS_HTTP_SwitchingProtocols_str "Switching Protocols" |
| 267 | #define SRS_CONSTS_HTTP_OK_str "OK" | 267 | #define SRS_CONSTS_HTTP_OK_str "OK" |
| 268 | -#define SRS_CONSTS_HTTP_Created_str "Created " | 268 | +#define SRS_CONSTS_HTTP_Created_str "Created" |
| 269 | #define SRS_CONSTS_HTTP_Accepted_str "Accepted" | 269 | #define SRS_CONSTS_HTTP_Accepted_str "Accepted" |
| 270 | -#define SRS_CONSTS_HTTP_NonAuthoritativeInformation_str "Non Authoritative Information " | ||
| 271 | -#define SRS_CONSTS_HTTP_NoContent_str "No Content " | 270 | +#define SRS_CONSTS_HTTP_NonAuthoritativeInformation_str "Non Authoritative Information" |
| 271 | +#define SRS_CONSTS_HTTP_NoContent_str "No Content" | ||
| 272 | #define SRS_CONSTS_HTTP_ResetContent_str "Reset Content" | 272 | #define SRS_CONSTS_HTTP_ResetContent_str "Reset Content" |
| 273 | #define SRS_CONSTS_HTTP_PartialContent_str "Partial Content" | 273 | #define SRS_CONSTS_HTTP_PartialContent_str "Partial Content" |
| 274 | -#define SRS_CONSTS_HTTP_MultipleChoices_str "Multiple Choices " | 274 | +#define SRS_CONSTS_HTTP_MultipleChoices_str "Multiple Choices" |
| 275 | #define SRS_CONSTS_HTTP_MovedPermanently_str "Moved Permanently" | 275 | #define SRS_CONSTS_HTTP_MovedPermanently_str "Moved Permanently" |
| 276 | #define SRS_CONSTS_HTTP_Found_str "Found" | 276 | #define SRS_CONSTS_HTTP_Found_str "Found" |
| 277 | #define SRS_CONSTS_HTTP_SeeOther_str "See Other" | 277 | #define SRS_CONSTS_HTTP_SeeOther_str "See Other" |
| 278 | -#define SRS_CONSTS_HTTP_NotModified_str "Not Modified " | 278 | +#define SRS_CONSTS_HTTP_NotModified_str "Not Modified" |
| 279 | #define SRS_CONSTS_HTTP_UseProxy_str "Use Proxy" | 279 | #define SRS_CONSTS_HTTP_UseProxy_str "Use Proxy" |
| 280 | -#define SRS_CONSTS_HTTP_TemporaryRedirect_str "Temporary Redirect " | 280 | +#define SRS_CONSTS_HTTP_TemporaryRedirect_str "Temporary Redirect" |
| 281 | #define SRS_CONSTS_HTTP_BadRequest_str "Bad Request" | 281 | #define SRS_CONSTS_HTTP_BadRequest_str "Bad Request" |
| 282 | #define SRS_CONSTS_HTTP_Unauthorized_str "Unauthorized" | 282 | #define SRS_CONSTS_HTTP_Unauthorized_str "Unauthorized" |
| 283 | -#define SRS_CONSTS_HTTP_PaymentRequired_str "Payment Required " | ||
| 284 | -#define SRS_CONSTS_HTTP_Forbidden_str "Forbidden " | 283 | +#define SRS_CONSTS_HTTP_PaymentRequired_str "Payment Required" |
| 284 | +#define SRS_CONSTS_HTTP_Forbidden_str "Forbidden" | ||
| 285 | #define SRS_CONSTS_HTTP_NotFound_str "Not Found" | 285 | #define SRS_CONSTS_HTTP_NotFound_str "Not Found" |
| 286 | #define SRS_CONSTS_HTTP_MethodNotAllowed_str "Method Not Allowed" | 286 | #define SRS_CONSTS_HTTP_MethodNotAllowed_str "Method Not Allowed" |
| 287 | -#define SRS_CONSTS_HTTP_NotAcceptable_str "Not Acceptable " | ||
| 288 | -#define SRS_CONSTS_HTTP_ProxyAuthenticationRequired_str "Proxy Authentication Required " | 287 | +#define SRS_CONSTS_HTTP_NotAcceptable_str "Not Acceptable" |
| 288 | +#define SRS_CONSTS_HTTP_ProxyAuthenticationRequired_str "Proxy Authentication Required" | ||
| 289 | #define SRS_CONSTS_HTTP_RequestTimeout_str "Request Timeout" | 289 | #define SRS_CONSTS_HTTP_RequestTimeout_str "Request Timeout" |
| 290 | #define SRS_CONSTS_HTTP_Conflict_str "Conflict" | 290 | #define SRS_CONSTS_HTTP_Conflict_str "Conflict" |
| 291 | #define SRS_CONSTS_HTTP_Gone_str "Gone" | 291 | #define SRS_CONSTS_HTTP_Gone_str "Gone" |
| 292 | #define SRS_CONSTS_HTTP_LengthRequired_str "Length Required" | 292 | #define SRS_CONSTS_HTTP_LengthRequired_str "Length Required" |
| 293 | #define SRS_CONSTS_HTTP_PreconditionFailed_str "Precondition Failed" | 293 | #define SRS_CONSTS_HTTP_PreconditionFailed_str "Precondition Failed" |
| 294 | -#define SRS_CONSTS_HTTP_RequestEntityTooLarge_str "Request Entity Too Large " | 294 | +#define SRS_CONSTS_HTTP_RequestEntityTooLarge_str "Request Entity Too Large" |
| 295 | #define SRS_CONSTS_HTTP_RequestURITooLarge_str "Request URI Too Large" | 295 | #define SRS_CONSTS_HTTP_RequestURITooLarge_str "Request URI Too Large" |
| 296 | #define SRS_CONSTS_HTTP_UnsupportedMediaType_str "Unsupported Media Type" | 296 | #define SRS_CONSTS_HTTP_UnsupportedMediaType_str "Unsupported Media Type" |
| 297 | #define SRS_CONSTS_HTTP_RequestedRangeNotSatisfiable_str "Requested Range Not Satisfiable" | 297 | #define SRS_CONSTS_HTTP_RequestedRangeNotSatisfiable_str "Requested Range Not Satisfiable" |
| 298 | -#define SRS_CONSTS_HTTP_ExpectationFailed_str "Expectation Failed " | ||
| 299 | -#define SRS_CONSTS_HTTP_InternalServerError_str "Internal Server Error " | 298 | +#define SRS_CONSTS_HTTP_ExpectationFailed_str "Expectation Failed" |
| 299 | +#define SRS_CONSTS_HTTP_InternalServerError_str "Internal Server Error" | ||
| 300 | #define SRS_CONSTS_HTTP_NotImplemented_str "Not Implemented" | 300 | #define SRS_CONSTS_HTTP_NotImplemented_str "Not Implemented" |
| 301 | #define SRS_CONSTS_HTTP_BadGateway_str "Bad Gateway" | 301 | #define SRS_CONSTS_HTTP_BadGateway_str "Bad Gateway" |
| 302 | #define SRS_CONSTS_HTTP_ServiceUnavailable_str "Service Unavailable" | 302 | #define SRS_CONSTS_HTTP_ServiceUnavailable_str "Service Unavailable" |
| 303 | #define SRS_CONSTS_HTTP_GatewayTimeout_str "Gateway Timeout" | 303 | #define SRS_CONSTS_HTTP_GatewayTimeout_str "Gateway Timeout" |
| 304 | #define SRS_CONSTS_HTTP_HTTPVersionNotSupported_str "HTTP Version Not Supported" | 304 | #define SRS_CONSTS_HTTP_HTTPVersionNotSupported_str "HTTP Version Not Supported" |
| 305 | 305 | ||
| 306 | +/////////////////////////////////////////////////////////// | ||
| 307 | +// RTSP consts values | ||
| 308 | +/////////////////////////////////////////////////////////// | ||
| 309 | +// 7.1.1 Status Code and Reason Phrase | ||
| 310 | +#define SRS_CONSTS_RTSP_Continue 100 | ||
| 311 | +#define SRS_CONSTS_RTSP_OK 200 | ||
| 312 | +#define SRS_CONSTS_RTSP_Created 201 | ||
| 313 | +#define SRS_CONSTS_RTSP_LowOnStorageSpace 250 | ||
| 314 | +#define SRS_CONSTS_RTSP_MultipleChoices 300 | ||
| 315 | +#define SRS_CONSTS_RTSP_MovedPermanently 301 | ||
| 316 | +#define SRS_CONSTS_RTSP_MovedTemporarily 302 | ||
| 317 | +#define SRS_CONSTS_RTSP_SeeOther 303 | ||
| 318 | +#define SRS_CONSTS_RTSP_NotModified 304 | ||
| 319 | +#define SRS_CONSTS_RTSP_UseProxy 305 | ||
| 320 | +#define SRS_CONSTS_RTSP_BadRequest 400 | ||
| 321 | +#define SRS_CONSTS_RTSP_Unauthorized 401 | ||
| 322 | +#define SRS_CONSTS_RTSP_PaymentRequired 402 | ||
| 323 | +#define SRS_CONSTS_RTSP_Forbidden 403 | ||
| 324 | +#define SRS_CONSTS_RTSP_NotFound 404 | ||
| 325 | +#define SRS_CONSTS_RTSP_MethodNotAllowed 405 | ||
| 326 | +#define SRS_CONSTS_RTSP_NotAcceptable 406 | ||
| 327 | +#define SRS_CONSTS_RTSP_ProxyAuthenticationRequired 407 | ||
| 328 | +#define SRS_CONSTS_RTSP_RequestTimeout 408 | ||
| 329 | +#define SRS_CONSTS_RTSP_Gone 410 | ||
| 330 | +#define SRS_CONSTS_RTSP_LengthRequired 411 | ||
| 331 | +#define SRS_CONSTS_RTSP_PreconditionFailed 412 | ||
| 332 | +#define SRS_CONSTS_RTSP_RequestEntityTooLarge 413 | ||
| 333 | +#define SRS_CONSTS_RTSP_RequestURITooLarge 414 | ||
| 334 | +#define SRS_CONSTS_RTSP_UnsupportedMediaType 415 | ||
| 335 | +#define SRS_CONSTS_RTSP_ParameterNotUnderstood 451 | ||
| 336 | +#define SRS_CONSTS_RTSP_ConferenceNotFound 452 | ||
| 337 | +#define SRS_CONSTS_RTSP_NotEnoughBandwidth 453 | ||
| 338 | +#define SRS_CONSTS_RTSP_SessionNotFound 454 | ||
| 339 | +#define SRS_CONSTS_RTSP_MethodNotValidInThisState 455 | ||
| 340 | +#define SRS_CONSTS_RTSP_HeaderFieldNotValidForResource 456 | ||
| 341 | +#define SRS_CONSTS_RTSP_InvalidRange 457 | ||
| 342 | +#define SRS_CONSTS_RTSP_ParameterIsReadOnly 458 | ||
| 343 | +#define SRS_CONSTS_RTSP_AggregateOperationNotAllowed 459 | ||
| 344 | +#define SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed 460 | ||
| 345 | +#define SRS_CONSTS_RTSP_UnsupportedTransport 461 | ||
| 346 | +#define SRS_CONSTS_RTSP_DestinationUnreachable 462 | ||
| 347 | +#define SRS_CONSTS_RTSP_InternalServerError 500 | ||
| 348 | +#define SRS_CONSTS_RTSP_NotImplemented 501 | ||
| 349 | +#define SRS_CONSTS_RTSP_BadGateway 502 | ||
| 350 | +#define SRS_CONSTS_RTSP_ServiceUnavailable 503 | ||
| 351 | +#define SRS_CONSTS_RTSP_GatewayTimeout 504 | ||
| 352 | +#define SRS_CONSTS_RTSP_RTSPVersionNotSupported 505 | ||
| 353 | +#define SRS_CONSTS_RTSP_OptionNotSupported 551 | ||
| 354 | + | ||
| 355 | +#define SRS_CONSTS_RTSP_Continue_str "Continue" | ||
| 356 | +#define SRS_CONSTS_RTSP_OK_str "OK" | ||
| 357 | +#define SRS_CONSTS_RTSP_Created_str "Created" | ||
| 358 | +#define SRS_CONSTS_RTSP_LowOnStorageSpace_str "Low on Storage Space" | ||
| 359 | +#define SRS_CONSTS_RTSP_MultipleChoices_str "Multiple Choices" | ||
| 360 | +#define SRS_CONSTS_RTSP_MovedPermanently_str "Moved Permanently" | ||
| 361 | +#define SRS_CONSTS_RTSP_MovedTemporarily_str "Moved Temporarily" | ||
| 362 | +#define SRS_CONSTS_RTSP_SeeOther_str "See Other" | ||
| 363 | +#define SRS_CONSTS_RTSP_NotModified_str "Not Modified" | ||
| 364 | +#define SRS_CONSTS_RTSP_UseProxy_str "Use Proxy" | ||
| 365 | +#define SRS_CONSTS_RTSP_BadRequest_str "Bad Request" | ||
| 366 | +#define SRS_CONSTS_RTSP_Unauthorized_str "Unauthorized" | ||
| 367 | +#define SRS_CONSTS_RTSP_PaymentRequired_str "Payment Required" | ||
| 368 | +#define SRS_CONSTS_RTSP_Forbidden_str "Forbidden" | ||
| 369 | +#define SRS_CONSTS_RTSP_NotFound_str "Not Found" | ||
| 370 | +#define SRS_CONSTS_RTSP_MethodNotAllowed_str "Method Not Allowed" | ||
| 371 | +#define SRS_CONSTS_RTSP_NotAcceptable_str "Not Acceptable" | ||
| 372 | +#define SRS_CONSTS_RTSP_ProxyAuthenticationRequired_str "Proxy Authentication Required" | ||
| 373 | +#define SRS_CONSTS_RTSP_RequestTimeout_str "Request Timeout" | ||
| 374 | +#define SRS_CONSTS_RTSP_Gone_str "Gone" | ||
| 375 | +#define SRS_CONSTS_RTSP_LengthRequired_str "Length Required" | ||
| 376 | +#define SRS_CONSTS_RTSP_PreconditionFailed_str "Precondition Failed" | ||
| 377 | +#define SRS_CONSTS_RTSP_RequestEntityTooLarge_str "Request Entity Too Large" | ||
| 378 | +#define SRS_CONSTS_RTSP_RequestURITooLarge_str "Request URI Too Large" | ||
| 379 | +#define SRS_CONSTS_RTSP_UnsupportedMediaType_str "Unsupported Media Type" | ||
| 380 | +#define SRS_CONSTS_RTSP_ParameterNotUnderstood_str "Invalid parameter" | ||
| 381 | +#define SRS_CONSTS_RTSP_ConferenceNotFound_str "Illegal Conference Identifier" | ||
| 382 | +#define SRS_CONSTS_RTSP_NotEnoughBandwidth_str "Not Enough Bandwidth" | ||
| 383 | +#define SRS_CONSTS_RTSP_SessionNotFound_str "Session Not Found" | ||
| 384 | +#define SRS_CONSTS_RTSP_MethodNotValidInThisState_str "Method Not Valid In This State" | ||
| 385 | +#define SRS_CONSTS_RTSP_HeaderFieldNotValidForResource_str "Header Field Not Valid" | ||
| 386 | +#define SRS_CONSTS_RTSP_InvalidRange_str "Invalid Range" | ||
| 387 | +#define SRS_CONSTS_RTSP_ParameterIsReadOnly_str "Parameter Is Read-Only" | ||
| 388 | +#define SRS_CONSTS_RTSP_AggregateOperationNotAllowed_str "Aggregate Operation Not Allowed" | ||
| 389 | +#define SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed_str "Only Aggregate Operation Allowed" | ||
| 390 | +#define SRS_CONSTS_RTSP_UnsupportedTransport_str "Unsupported Transport" | ||
| 391 | +#define SRS_CONSTS_RTSP_DestinationUnreachable_str "Destination Unreachable" | ||
| 392 | +#define SRS_CONSTS_RTSP_InternalServerError_str "Internal Server Error" | ||
| 393 | +#define SRS_CONSTS_RTSP_NotImplemented_str "Not Implemented" | ||
| 394 | +#define SRS_CONSTS_RTSP_BadGateway_str "Bad Gateway" | ||
| 395 | +#define SRS_CONSTS_RTSP_ServiceUnavailable_str "Service Unavailable" | ||
| 396 | +#define SRS_CONSTS_RTSP_GatewayTimeout_str "Gateway Timeout" | ||
| 397 | +#define SRS_CONSTS_RTSP_RTSPVersionNotSupported_str "RTSP Version Not Supported" | ||
| 398 | +#define SRS_CONSTS_RTSP_OptionNotSupported_str "Option not support" | ||
| 399 | + | ||
| 306 | #endif | 400 | #endif |
| 307 | 401 |
| @@ -142,6 +142,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -142,6 +142,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 142 | #define ERROR_OpenSslComputeSharedKey 2039 | 142 | #define ERROR_OpenSslComputeSharedKey 2039 |
| 143 | #define ERROR_RTMP_MIC_CHUNKSIZE_CHANGED 2040 | 143 | #define ERROR_RTMP_MIC_CHUNKSIZE_CHANGED 2040 |
| 144 | #define ERROR_RTMP_MIC_CACHE_OVERFLOW 2041 | 144 | #define ERROR_RTMP_MIC_CACHE_OVERFLOW 2041 |
| 145 | +#define ERROR_RTSP_TOKEN_NOT_NORMAL 2042 | ||
| 146 | +#define ERROR_RTSP_REQUEST_HEADER_EOF 2043 | ||
| 145 | // | 147 | // |
| 146 | // system control message, | 148 | // system control message, |
| 147 | // not an error, but special control logic. | 149 | // not an error, but special control logic. |
| @@ -23,17 +23,465 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -23,17 +23,465 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 23 | 23 | ||
| 24 | #include <srs_rtsp_stack.hpp> | 24 | #include <srs_rtsp_stack.hpp> |
| 25 | 25 | ||
| 26 | +#include <stdlib.h> | ||
| 27 | +#include <map> | ||
| 28 | +using namespace std; | ||
| 29 | + | ||
| 26 | #include <srs_rtmp_io.hpp> | 30 | #include <srs_rtmp_io.hpp> |
| 31 | +#include <srs_kernel_buffer.hpp> | ||
| 32 | +#include <srs_kernel_error.hpp> | ||
| 33 | +#include <srs_kernel_log.hpp> | ||
| 34 | +#include <srs_kernel_consts.hpp> | ||
| 27 | 35 | ||
| 28 | #ifdef SRS_AUTO_STREAM_CASTER | 36 | #ifdef SRS_AUTO_STREAM_CASTER |
| 29 | 37 | ||
| 38 | +#define __SRS_RTSP_BUFFER 4096 | ||
| 39 | + | ||
| 40 | +// get the status text of code. | ||
| 41 | +string srs_generate_rtsp_status_text(int status) | ||
| 42 | +{ | ||
| 43 | + static std::map<int, std::string> _status_map; | ||
| 44 | + if (_status_map.empty()) { | ||
| 45 | + _status_map[SRS_CONSTS_RTSP_Continue ] = SRS_CONSTS_RTSP_Continue_str ; | ||
| 46 | + _status_map[SRS_CONSTS_RTSP_OK ] = SRS_CONSTS_RTSP_OK_str ; | ||
| 47 | + _status_map[SRS_CONSTS_RTSP_Created ] = SRS_CONSTS_RTSP_Created_str ; | ||
| 48 | + _status_map[SRS_CONSTS_RTSP_LowOnStorageSpace ] = SRS_CONSTS_RTSP_LowOnStorageSpace_str ; | ||
| 49 | + _status_map[SRS_CONSTS_RTSP_MultipleChoices ] = SRS_CONSTS_RTSP_MultipleChoices_str ; | ||
| 50 | + _status_map[SRS_CONSTS_RTSP_MovedPermanently ] = SRS_CONSTS_RTSP_MovedPermanently_str ; | ||
| 51 | + _status_map[SRS_CONSTS_RTSP_MovedTemporarily ] = SRS_CONSTS_RTSP_MovedTemporarily_str ; | ||
| 52 | + _status_map[SRS_CONSTS_RTSP_SeeOther ] = SRS_CONSTS_RTSP_SeeOther_str ; | ||
| 53 | + _status_map[SRS_CONSTS_RTSP_NotModified ] = SRS_CONSTS_RTSP_NotModified_str ; | ||
| 54 | + _status_map[SRS_CONSTS_RTSP_UseProxy ] = SRS_CONSTS_RTSP_UseProxy_str ; | ||
| 55 | + _status_map[SRS_CONSTS_RTSP_BadRequest ] = SRS_CONSTS_RTSP_BadRequest_str ; | ||
| 56 | + _status_map[SRS_CONSTS_RTSP_Unauthorized ] = SRS_CONSTS_RTSP_Unauthorized_str ; | ||
| 57 | + _status_map[SRS_CONSTS_RTSP_PaymentRequired ] = SRS_CONSTS_RTSP_PaymentRequired_str ; | ||
| 58 | + _status_map[SRS_CONSTS_RTSP_Forbidden ] = SRS_CONSTS_RTSP_Forbidden_str ; | ||
| 59 | + _status_map[SRS_CONSTS_RTSP_NotFound ] = SRS_CONSTS_RTSP_NotFound_str ; | ||
| 60 | + _status_map[SRS_CONSTS_RTSP_MethodNotAllowed ] = SRS_CONSTS_RTSP_MethodNotAllowed_str ; | ||
| 61 | + _status_map[SRS_CONSTS_RTSP_NotAcceptable ] = SRS_CONSTS_RTSP_NotAcceptable_str ; | ||
| 62 | + _status_map[SRS_CONSTS_RTSP_ProxyAuthenticationRequired ] = SRS_CONSTS_RTSP_ProxyAuthenticationRequired_str ; | ||
| 63 | + _status_map[SRS_CONSTS_RTSP_RequestTimeout ] = SRS_CONSTS_RTSP_RequestTimeout_str ; | ||
| 64 | + _status_map[SRS_CONSTS_RTSP_Gone ] = SRS_CONSTS_RTSP_Gone_str ; | ||
| 65 | + _status_map[SRS_CONSTS_RTSP_LengthRequired ] = SRS_CONSTS_RTSP_LengthRequired_str ; | ||
| 66 | + _status_map[SRS_CONSTS_RTSP_PreconditionFailed ] = SRS_CONSTS_RTSP_PreconditionFailed_str ; | ||
| 67 | + _status_map[SRS_CONSTS_RTSP_RequestEntityTooLarge ] = SRS_CONSTS_RTSP_RequestEntityTooLarge_str ; | ||
| 68 | + _status_map[SRS_CONSTS_RTSP_RequestURITooLarge ] = SRS_CONSTS_RTSP_RequestURITooLarge_str ; | ||
| 69 | + _status_map[SRS_CONSTS_RTSP_UnsupportedMediaType ] = SRS_CONSTS_RTSP_UnsupportedMediaType_str ; | ||
| 70 | + _status_map[SRS_CONSTS_RTSP_ParameterNotUnderstood ] = SRS_CONSTS_RTSP_ParameterNotUnderstood_str ; | ||
| 71 | + _status_map[SRS_CONSTS_RTSP_ConferenceNotFound ] = SRS_CONSTS_RTSP_ConferenceNotFound_str ; | ||
| 72 | + _status_map[SRS_CONSTS_RTSP_NotEnoughBandwidth ] = SRS_CONSTS_RTSP_NotEnoughBandwidth_str ; | ||
| 73 | + _status_map[SRS_CONSTS_RTSP_SessionNotFound ] = SRS_CONSTS_RTSP_SessionNotFound_str ; | ||
| 74 | + _status_map[SRS_CONSTS_RTSP_MethodNotValidInThisState ] = SRS_CONSTS_RTSP_MethodNotValidInThisState_str ; | ||
| 75 | + _status_map[SRS_CONSTS_RTSP_HeaderFieldNotValidForResource ] = SRS_CONSTS_RTSP_HeaderFieldNotValidForResource_str ; | ||
| 76 | + _status_map[SRS_CONSTS_RTSP_InvalidRange ] = SRS_CONSTS_RTSP_InvalidRange_str ; | ||
| 77 | + _status_map[SRS_CONSTS_RTSP_ParameterIsReadOnly ] = SRS_CONSTS_RTSP_ParameterIsReadOnly_str ; | ||
| 78 | + _status_map[SRS_CONSTS_RTSP_AggregateOperationNotAllowed ] = SRS_CONSTS_RTSP_AggregateOperationNotAllowed_str ; | ||
| 79 | + _status_map[SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed ] = SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed_str ; | ||
| 80 | + _status_map[SRS_CONSTS_RTSP_UnsupportedTransport ] = SRS_CONSTS_RTSP_UnsupportedTransport_str ; | ||
| 81 | + _status_map[SRS_CONSTS_RTSP_DestinationUnreachable ] = SRS_CONSTS_RTSP_DestinationUnreachable_str ; | ||
| 82 | + _status_map[SRS_CONSTS_RTSP_InternalServerError ] = SRS_CONSTS_RTSP_InternalServerError_str ; | ||
| 83 | + _status_map[SRS_CONSTS_RTSP_NotImplemented ] = SRS_CONSTS_RTSP_NotImplemented_str ; | ||
| 84 | + _status_map[SRS_CONSTS_RTSP_BadGateway ] = SRS_CONSTS_RTSP_BadGateway_str ; | ||
| 85 | + _status_map[SRS_CONSTS_RTSP_ServiceUnavailable ] = SRS_CONSTS_RTSP_ServiceUnavailable_str ; | ||
| 86 | + _status_map[SRS_CONSTS_RTSP_GatewayTimeout ] = SRS_CONSTS_RTSP_GatewayTimeout_str ; | ||
| 87 | + _status_map[SRS_CONSTS_RTSP_RTSPVersionNotSupported ] = SRS_CONSTS_RTSP_RTSPVersionNotSupported_str ; | ||
| 88 | + _status_map[SRS_CONSTS_RTSP_OptionNotSupported ] = SRS_CONSTS_RTSP_OptionNotSupported_str ; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + std::string status_text; | ||
| 92 | + if (_status_map.find(status) == _status_map.end()) { | ||
| 93 | + status_text = "Status Unknown"; | ||
| 94 | + } else { | ||
| 95 | + status_text = _status_map[status]; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + return status_text; | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | +std::string srs_generate_rtsp_method_str(SrsRtspMethod method) | ||
| 102 | +{ | ||
| 103 | + switch (method) { | ||
| 104 | + case SrsRtspMethodDescribe: return __SRS_METHOD_DESCRIBE; | ||
| 105 | + case SrsRtspMethodAnnounce: return __SRS_METHOD_ANNOUNCE; | ||
| 106 | + case SrsRtspMethodGetParameter: return __SRS_METHOD_GET_PARAMETER; | ||
| 107 | + case SrsRtspMethodOptions: return __SRS_METHOD_OPTIONS; | ||
| 108 | + case SrsRtspMethodPause: return __SRS_METHOD_PAUSE; | ||
| 109 | + case SrsRtspMethodPlay: return __SRS_METHOD_PLAY; | ||
| 110 | + case SrsRtspMethodRecord: return __SRS_METHOD_RECORD; | ||
| 111 | + case SrsRtspMethodRedirect: return __SRS_METHOD_REDIRECT; | ||
| 112 | + case SrsRtspMethodSetup: return __SRS_METHOD_SETUP; | ||
| 113 | + case SrsRtspMethodSetParameter: return __SRS_METHOD_SET_PARAMETER; | ||
| 114 | + case SrsRtspMethodTeardown: return __SRS_METHOD_TEARDOWN; | ||
| 115 | + default: return "Unknown"; | ||
| 116 | + } | ||
| 117 | +} | ||
| 118 | + | ||
| 119 | +SrsRtspRequest::SrsRtspRequest() | ||
| 120 | +{ | ||
| 121 | + seq = 0; | ||
| 122 | +} | ||
| 123 | + | ||
| 124 | +SrsRtspRequest::~SrsRtspRequest() | ||
| 125 | +{ | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +bool SrsRtspRequest::is_options() | ||
| 129 | +{ | ||
| 130 | + return method == __SRS_METHOD_OPTIONS; | ||
| 131 | +} | ||
| 132 | + | ||
| 133 | +SrsRtspResponse::SrsRtspResponse(int cseq) | ||
| 134 | +{ | ||
| 135 | + seq = cseq; | ||
| 136 | + status = SRS_CONSTS_RTSP_OK; | ||
| 137 | +} | ||
| 138 | + | ||
| 139 | +SrsRtspResponse::~SrsRtspResponse() | ||
| 140 | +{ | ||
| 141 | +} | ||
| 142 | + | ||
| 143 | +stringstream& SrsRtspResponse::encode(stringstream& ss) | ||
| 144 | +{ | ||
| 145 | + // status line | ||
| 146 | + ss << __SRS_VERSION << __SRS_RTSP_SP | ||
| 147 | + << status << __SRS_RTSP_SP | ||
| 148 | + << srs_generate_rtsp_status_text(status) << __SRS_RTSP_CRLF; | ||
| 149 | + | ||
| 150 | + // cseq | ||
| 151 | + ss << __SRS_TOKEN_CSEQ << ":" << __SRS_RTSP_SP << seq << __SRS_RTSP_CRLF; | ||
| 152 | + | ||
| 153 | + // others. | ||
| 154 | + ss << "Cache-Control: no-store" << __SRS_RTSP_CRLF | ||
| 155 | + << "Pragma: no-cache" << __SRS_RTSP_CRLF | ||
| 156 | + << "Server: " << RTMP_SIG_SRS_SERVER << __SRS_RTSP_CRLF; | ||
| 157 | + | ||
| 158 | + return ss; | ||
| 159 | +} | ||
| 160 | + | ||
| 161 | +SrsRtspOptionsResponse::SrsRtspOptionsResponse(int cseq) : SrsRtspResponse(cseq) | ||
| 162 | +{ | ||
| 163 | + methods = (SrsRtspMethod)(SrsRtspMethodDescribe | SrsRtspMethodOptions | ||
| 164 | + | SrsRtspMethodPause | SrsRtspMethodPlay | SrsRtspMethodSetup | SrsRtspMethodTeardown | ||
| 165 | + | SrsRtspMethodAnnounce | SrsRtspMethodRecord); | ||
| 166 | +} | ||
| 167 | + | ||
| 168 | +SrsRtspOptionsResponse::~SrsRtspOptionsResponse() | ||
| 169 | +{ | ||
| 170 | +} | ||
| 171 | + | ||
| 172 | +stringstream& SrsRtspOptionsResponse::encode(stringstream& ss) | ||
| 173 | +{ | ||
| 174 | + SrsRtspResponse::encode(ss); | ||
| 175 | + | ||
| 176 | + SrsRtspMethod __methods[] = { | ||
| 177 | + SrsRtspMethodDescribe, | ||
| 178 | + SrsRtspMethodAnnounce, | ||
| 179 | + SrsRtspMethodGetParameter, | ||
| 180 | + SrsRtspMethodOptions, | ||
| 181 | + SrsRtspMethodPause, | ||
| 182 | + SrsRtspMethodPlay, | ||
| 183 | + SrsRtspMethodRecord, | ||
| 184 | + SrsRtspMethodRedirect, | ||
| 185 | + SrsRtspMethodSetup, | ||
| 186 | + SrsRtspMethodSetParameter, | ||
| 187 | + SrsRtspMethodTeardown, | ||
| 188 | + }; | ||
| 189 | + | ||
| 190 | + ss << __SRS_TOKEN_PUBLIC << ":" << __SRS_RTSP_SP; | ||
| 191 | + | ||
| 192 | + bool appended = false; | ||
| 193 | + int nb_methods = (int)(sizeof(__methods) / sizeof(SrsRtspMethod)); | ||
| 194 | + for (int i = 0; i < nb_methods; i++) { | ||
| 195 | + SrsRtspMethod method = __methods[i]; | ||
| 196 | + if (((int)methods & (int)method) != (int)method) { | ||
| 197 | + continue; | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + if (appended) { | ||
| 201 | + ss << ", "; | ||
| 202 | + } | ||
| 203 | + ss << srs_generate_rtsp_method_str(method); | ||
| 204 | + appended = true; | ||
| 205 | + } | ||
| 206 | + ss << __SRS_RTSP_CRLF; | ||
| 207 | + | ||
| 208 | + // eof header. | ||
| 209 | + ss << __SRS_RTSP_CRLF; | ||
| 210 | + | ||
| 211 | + return ss; | ||
| 212 | +} | ||
| 213 | + | ||
| 30 | SrsRtspStack::SrsRtspStack(ISrsProtocolReaderWriter* s) | 214 | SrsRtspStack::SrsRtspStack(ISrsProtocolReaderWriter* s) |
| 31 | { | 215 | { |
| 216 | + buf = new SrsSimpleBuffer(); | ||
| 32 | skt = s; | 217 | skt = s; |
| 33 | } | 218 | } |
| 34 | 219 | ||
| 35 | SrsRtspStack::~SrsRtspStack() | 220 | SrsRtspStack::~SrsRtspStack() |
| 36 | { | 221 | { |
| 222 | + srs_freep(buf); | ||
| 223 | +} | ||
| 224 | + | ||
| 225 | +int SrsRtspStack::recv_message(SrsRtspRequest** preq) | ||
| 226 | +{ | ||
| 227 | + int ret = ERROR_SUCCESS; | ||
| 228 | + | ||
| 229 | + SrsRtspRequest* req = new SrsRtspRequest(); | ||
| 230 | + if ((ret = do_recv_message(req)) != ERROR_SUCCESS) { | ||
| 231 | + srs_freep(req); | ||
| 232 | + return ret; | ||
| 233 | + } | ||
| 234 | + | ||
| 235 | + *preq = req; | ||
| 236 | + | ||
| 237 | + return ret; | ||
| 238 | +} | ||
| 239 | + | ||
| 240 | +int SrsRtspStack::send_message(SrsRtspResponse* res) | ||
| 241 | +{ | ||
| 242 | + int ret = ERROR_SUCCESS; | ||
| 243 | + | ||
| 244 | + std::stringstream ss; | ||
| 245 | + // encode the message to string. | ||
| 246 | + res->encode(ss); | ||
| 247 | + | ||
| 248 | + std::string str = ss.str(); | ||
| 249 | + srs_assert(!str.empty()); | ||
| 250 | + | ||
| 251 | + if ((ret = skt->write((char*)str.c_str(), (int)str.length(), NULL)) != ERROR_SUCCESS) { | ||
| 252 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 253 | + srs_error("rtsp: send response failed. ret=%d", ret); | ||
| 254 | + } | ||
| 255 | + return ret; | ||
| 256 | + } | ||
| 257 | + srs_info("rtsp: send response ok"); | ||
| 258 | + | ||
| 259 | + return ret; | ||
| 260 | +} | ||
| 261 | + | ||
| 262 | +int SrsRtspStack::do_recv_message(SrsRtspRequest* req) | ||
| 263 | +{ | ||
| 264 | + int ret = ERROR_SUCCESS; | ||
| 265 | + | ||
| 266 | + // parse request line. | ||
| 267 | + if ((ret = recv_token_normal(req->method)) != ERROR_SUCCESS) { | ||
| 268 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 269 | + srs_error("rtsp: parse method failed. ret=%d", ret); | ||
| 270 | + } | ||
| 271 | + return ret; | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + if ((ret = recv_token_normal(req->uri)) != ERROR_SUCCESS) { | ||
| 275 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 276 | + srs_error("rtsp: parse uri failed. ret=%d", ret); | ||
| 277 | + } | ||
| 278 | + return ret; | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + if ((ret = recv_token_eof(req->version)) != ERROR_SUCCESS) { | ||
| 282 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 283 | + srs_error("rtsp: parse version failed. ret=%d", ret); | ||
| 284 | + } | ||
| 285 | + return ret; | ||
| 286 | + } | ||
| 287 | + | ||
| 288 | + // parse headers. | ||
| 289 | + for (;;) { | ||
| 290 | + // parse the header name | ||
| 291 | + std::string token; | ||
| 292 | + if ((ret = recv_token_normal(token)) != ERROR_SUCCESS) { | ||
| 293 | + if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) { | ||
| 294 | + ret = ERROR_SUCCESS; | ||
| 295 | + srs_info("rtsp: message header parsed"); | ||
| 296 | + break; | ||
| 297 | + } | ||
| 298 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 299 | + srs_error("rtsp: parse token failed. ret=%d", ret); | ||
| 300 | + } | ||
| 301 | + return ret; | ||
| 302 | + } | ||
| 303 | + | ||
| 304 | + // parse the header value according by header name | ||
| 305 | + if (token == __SRS_TOKEN_CSEQ) { | ||
| 306 | + std::string seq; | ||
| 307 | + if ((ret = recv_token_eof(seq)) != ERROR_SUCCESS) { | ||
| 308 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 309 | + srs_error("rtsp: parse seq failed. ret=%d", ret); | ||
| 310 | + } | ||
| 311 | + return ret; | ||
| 312 | + } | ||
| 313 | + req->seq = ::atoi(seq.c_str()); | ||
| 314 | + } else { | ||
| 315 | + // unknown header name, parse util EOF. | ||
| 316 | + SrsRtspTokenState state = SrsRtspTokenStateNormal; | ||
| 317 | + while (state == SrsRtspTokenStateNormal) { | ||
| 318 | + std::string value; | ||
| 319 | + if ((ret = recv_token(value, state)) != ERROR_SUCCESS) { | ||
| 320 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 321 | + srs_error("rtsp: parse token failed. ret=%d", ret); | ||
| 322 | + } | ||
| 323 | + return ret; | ||
| 324 | + } | ||
| 325 | + srs_trace("rtsp: ignore header %s=%s", token.c_str(), value.c_str()); | ||
| 326 | + } | ||
| 327 | + } | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + // parse body. | ||
| 331 | + | ||
| 332 | + return ret; | ||
| 333 | +} | ||
| 334 | + | ||
| 335 | +int SrsRtspStack::recv_token_normal(std::string& token) | ||
| 336 | +{ | ||
| 337 | + int ret = ERROR_SUCCESS; | ||
| 338 | + | ||
| 339 | + SrsRtspTokenState state; | ||
| 340 | + | ||
| 341 | + if ((ret = recv_token(token, state)) != ERROR_SUCCESS) { | ||
| 342 | + if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) { | ||
| 343 | + return ret; | ||
| 344 | + } | ||
| 345 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 346 | + srs_error("rtsp: parse token failed. ret=%d", ret); | ||
| 347 | + } | ||
| 348 | + return ret; | ||
| 349 | + } | ||
| 350 | + | ||
| 351 | + if (state != SrsRtspTokenStateNormal) { | ||
| 352 | + ret = ERROR_RTSP_TOKEN_NOT_NORMAL; | ||
| 353 | + srs_error("rtsp: parse normal token failed, state=%d. ret=%d", state, ret); | ||
| 354 | + return ret; | ||
| 355 | + } | ||
| 356 | + | ||
| 357 | + return ret; | ||
| 358 | +} | ||
| 359 | + | ||
| 360 | +int SrsRtspStack::recv_token_eof(std::string& token) | ||
| 361 | +{ | ||
| 362 | + int ret = ERROR_SUCCESS; | ||
| 363 | + | ||
| 364 | + SrsRtspTokenState state; | ||
| 365 | + | ||
| 366 | + if ((ret = recv_token(token, state)) != ERROR_SUCCESS) { | ||
| 367 | + if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) { | ||
| 368 | + return ret; | ||
| 369 | + } | ||
| 370 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 371 | + srs_error("rtsp: parse token failed. ret=%d", ret); | ||
| 372 | + } | ||
| 373 | + return ret; | ||
| 374 | + } | ||
| 375 | + | ||
| 376 | + if (state != SrsRtspTokenStateEOF) { | ||
| 377 | + ret = ERROR_RTSP_TOKEN_NOT_NORMAL; | ||
| 378 | + srs_error("rtsp: parse eof token failed, state=%d. ret=%d", state, ret); | ||
| 379 | + return ret; | ||
| 380 | + } | ||
| 381 | + | ||
| 382 | + return ret; | ||
| 383 | +} | ||
| 384 | + | ||
| 385 | +int SrsRtspStack::recv_token_util_eof(std::string& token) | ||
| 386 | +{ | ||
| 387 | + int ret = ERROR_SUCCESS; | ||
| 388 | + | ||
| 389 | + SrsRtspTokenState state; | ||
| 390 | + | ||
| 391 | + // use 0x00 as ignore the normal token flag. | ||
| 392 | + if ((ret = recv_token(token, state, 0x00)) != ERROR_SUCCESS) { | ||
| 393 | + if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) { | ||
| 394 | + return ret; | ||
| 395 | + } | ||
| 396 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 397 | + srs_error("rtsp: parse token failed. ret=%d", ret); | ||
| 398 | + } | ||
| 399 | + return ret; | ||
| 400 | + } | ||
| 401 | + | ||
| 402 | + if (state != SrsRtspTokenStateEOF) { | ||
| 403 | + ret = ERROR_RTSP_TOKEN_NOT_NORMAL; | ||
| 404 | + srs_error("rtsp: parse eof token failed, state=%d. ret=%d", state, ret); | ||
| 405 | + return ret; | ||
| 406 | + } | ||
| 407 | + | ||
| 408 | + return ret; | ||
| 409 | +} | ||
| 410 | + | ||
| 411 | +int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch) | ||
| 412 | +{ | ||
| 413 | + int ret = ERROR_SUCCESS; | ||
| 414 | + | ||
| 415 | + // whatever, default to error state. | ||
| 416 | + state = SrsRtspTokenStateError; | ||
| 417 | + | ||
| 418 | + // when buffer is empty, append bytes first. | ||
| 419 | + bool append_bytes = buf->length() == 0; | ||
| 420 | + | ||
| 421 | + // parse util token. | ||
| 422 | + for (;;) { | ||
| 423 | + // append bytes if required. | ||
| 424 | + if (append_bytes) { | ||
| 425 | + append_bytes = false; | ||
| 426 | + | ||
| 427 | + char buffer[__SRS_RTSP_BUFFER]; | ||
| 428 | + ssize_t nb_read = 0; | ||
| 429 | + if ((ret = skt->read(buffer, __SRS_RTSP_BUFFER, &nb_read)) != ERROR_SUCCESS) { | ||
| 430 | + if (!srs_is_client_gracefully_close(ret)) { | ||
| 431 | + srs_error("rtsp: io read failed. ret=%d", ret); | ||
| 432 | + } | ||
| 433 | + return ret; | ||
| 434 | + } | ||
| 435 | + srs_info("rtsp: io read %d bytes", nb_read); | ||
| 436 | + | ||
| 437 | + buf->append(buffer, nb_read); | ||
| 438 | + } | ||
| 439 | + | ||
| 440 | + // parse one by one. | ||
| 441 | + char* start = buf->bytes(); | ||
| 442 | + char* end = start + buf->length(); | ||
| 443 | + char* p = start; | ||
| 444 | + | ||
| 445 | + // find util SP/CR/LF, max 2 EOF, to finger out the EOF of message. | ||
| 446 | + for (; p < end && p[0] != normal_ch && p[0] != __SRS_RTSP_CR && p[0] != __SRS_RTSP_LF; p++) { | ||
| 447 | + } | ||
| 448 | + | ||
| 449 | + // matched. | ||
| 450 | + if (p < end) { | ||
| 451 | + // finger out the state. | ||
| 452 | + if (p[0] == normal_ch) { | ||
| 453 | + state = SrsRtspTokenStateNormal; | ||
| 454 | + } else { | ||
| 455 | + state = SrsRtspTokenStateEOF; | ||
| 456 | + } | ||
| 457 | + | ||
| 458 | + // got the token. | ||
| 459 | + int nb_token = p - start; | ||
| 460 | + // trim last ':' character. | ||
| 461 | + if (nb_token && p[-1] == ':') { | ||
| 462 | + nb_token--; | ||
| 463 | + } | ||
| 464 | + if (nb_token) { | ||
| 465 | + token.append(start, nb_token); | ||
| 466 | + } else { | ||
| 467 | + ret = ERROR_RTSP_REQUEST_HEADER_EOF; | ||
| 468 | + } | ||
| 469 | + | ||
| 470 | + // ignore SP/CR/LF | ||
| 471 | + for (int i = 0; i < 2 && p < end && (p[0] == normal_ch || p[0] == __SRS_RTSP_CR || p[0] == __SRS_RTSP_LF); p++, i++) { | ||
| 472 | + } | ||
| 473 | + | ||
| 474 | + // consume the token bytes. | ||
| 475 | + srs_assert(p - start); | ||
| 476 | + buf->erase(p - start); | ||
| 477 | + break; | ||
| 478 | + } | ||
| 479 | + | ||
| 480 | + // append more and parse again. | ||
| 481 | + append_bytes = true; | ||
| 482 | + } | ||
| 483 | + | ||
| 484 | + return ret; | ||
| 37 | } | 485 | } |
| 38 | 486 | ||
| 39 | #endif | 487 | #endif |
| @@ -30,10 +30,213 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -30,10 +30,213 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 30 | 30 | ||
| 31 | #include <srs_core.hpp> | 31 | #include <srs_core.hpp> |
| 32 | 32 | ||
| 33 | +#include <string> | ||
| 34 | +#include <sstream> | ||
| 35 | + | ||
| 36 | +#include <srs_kernel_consts.hpp> | ||
| 37 | + | ||
| 33 | #ifdef SRS_AUTO_STREAM_CASTER | 38 | #ifdef SRS_AUTO_STREAM_CASTER |
| 34 | 39 | ||
| 40 | +class SrsSimpleBuffer; | ||
| 35 | class ISrsProtocolReaderWriter; | 41 | class ISrsProtocolReaderWriter; |
| 36 | 42 | ||
| 43 | +// rtsp specification | ||
| 44 | +// CR = <US-ASCII CR, carriage return (13)> | ||
| 45 | +#define __SRS_RTSP_CR SRS_CONSTS_CR // 0x0D | ||
| 46 | +// LF = <US-ASCII LF, linefeed (10)> | ||
| 47 | +#define __SRS_RTSP_LF SRS_CONSTS_LF // 0x0A | ||
| 48 | +// SP = <US-ASCII SP, space (32)> | ||
| 49 | +#define __SRS_RTSP_SP ' ' // 0x20 | ||
| 50 | + | ||
| 51 | +// 4 RTSP Message | ||
| 52 | +// Lines are terminated by CRLF, but | ||
| 53 | +// receivers should be prepared to also interpret CR and LF by | ||
| 54 | +// themselves as line terminators. | ||
| 55 | +#define __SRS_RTSP_CRLF "\r\n" // 0x0D0A | ||
| 56 | +#define __SRS_RTSP_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A | ||
| 57 | + | ||
| 58 | +// RTSP token | ||
| 59 | +#define __SRS_TOKEN_CSEQ "CSeq" | ||
| 60 | +#define __SRS_TOKEN_PUBLIC "Public" | ||
| 61 | + | ||
| 62 | +// RTSP methods | ||
| 63 | +#define __SRS_METHOD_OPTIONS "OPTIONS" | ||
| 64 | +#define __SRS_METHOD_DESCRIBE "DESCRIBE" | ||
| 65 | +#define __SRS_METHOD_ANNOUNCE "ANNOUNCE" | ||
| 66 | +#define __SRS_METHOD_SETUP "SETUP" | ||
| 67 | +#define __SRS_METHOD_PLAY "PLAY" | ||
| 68 | +#define __SRS_METHOD_PAUSE "PAUSE" | ||
| 69 | +#define __SRS_METHOD_TEARDOWN "TEARDOWN" | ||
| 70 | +#define __SRS_METHOD_GET_PARAMETER "GET_PARAMETER" | ||
| 71 | +#define __SRS_METHOD_SET_PARAMETER "SET_PARAMETER" | ||
| 72 | +#define __SRS_METHOD_REDIRECT "REDIRECT" | ||
| 73 | +#define __SRS_METHOD_RECORD "RECORD" | ||
| 74 | +// Embedded (Interleaved) Binary Data | ||
| 75 | + | ||
| 76 | +// RTSP-Version | ||
| 77 | +#define __SRS_VERSION "RTSP/1.0" | ||
| 78 | + | ||
| 79 | +/** | ||
| 80 | +* the rtsp request message. | ||
| 81 | +* 6 Request | ||
| 82 | +* A request message from a client to a server or vice versa includes, | ||
| 83 | +* within the first line of that message, the method to be applied to | ||
| 84 | +* the resource, the identifier of the resource, and the protocol | ||
| 85 | +* version in use. | ||
| 86 | +* Request = Request-Line ; Section 6.1 | ||
| 87 | +* *( general-header ; Section 5 | ||
| 88 | +* | request-header ; Section 6.2 | ||
| 89 | +* | entity-header ) ; Section 8.1 | ||
| 90 | +* CRLF | ||
| 91 | +* [ message-body ] ; Section 4.3 | ||
| 92 | +*/ | ||
| 93 | +class SrsRtspRequest | ||
| 94 | +{ | ||
| 95 | +public: | ||
| 96 | + /** | ||
| 97 | + * 6.1 Request Line | ||
| 98 | + * Request-Line = Method SP Request-URI SP RTSP-Version CRLF | ||
| 99 | + */ | ||
| 100 | + std::string method; | ||
| 101 | + std::string uri; | ||
| 102 | + std::string version; | ||
| 103 | + /** | ||
| 104 | + * 12.17 CSeq | ||
| 105 | + * The CSeq field specifies the sequence number for an RTSP requestresponse | ||
| 106 | + * pair. This field MUST be present in all requests and | ||
| 107 | + * responses. For every RTSP request containing the given sequence | ||
| 108 | + * number, there will be a corresponding response having the same | ||
| 109 | + * number. Any retransmitted request must contain the same sequence | ||
| 110 | + * number as the original (i.e. the sequence number is not incremented | ||
| 111 | + * for retransmissions of the same request). | ||
| 112 | + */ | ||
| 113 | + int seq; | ||
| 114 | +public: | ||
| 115 | + SrsRtspRequest(); | ||
| 116 | + virtual ~SrsRtspRequest(); | ||
| 117 | +public: | ||
| 118 | + virtual bool is_options(); | ||
| 119 | +}; | ||
| 120 | + | ||
| 121 | +/** | ||
| 122 | +* the rtsp response message. | ||
| 123 | +* 7 Response | ||
| 124 | +* [H6] applies except that HTTP-Version is replaced by RTSP-Version. | ||
| 125 | +* Also, RTSP defines additional status codes and does not define some | ||
| 126 | +* HTTP codes. The valid response codes and the methods they can be used | ||
| 127 | +* with are defined in Table 1. | ||
| 128 | +* After receiving and interpreting a request message, the recipient | ||
| 129 | +* responds with an RTSP response message. | ||
| 130 | +* Response = Status-Line ; Section 7.1 | ||
| 131 | +* *( general-header ; Section 5 | ||
| 132 | +* | response-header ; Section 7.1.2 | ||
| 133 | +* | entity-header ) ; Section 8.1 | ||
| 134 | +* CRLF | ||
| 135 | +* [ message-body ] ; Section 4.3 | ||
| 136 | +*/ | ||
| 137 | +class SrsRtspResponse | ||
| 138 | +{ | ||
| 139 | +public: | ||
| 140 | + /** | ||
| 141 | + * 7.1 Status-Line | ||
| 142 | + * The first line of a Response message is the Status-Line, consisting | ||
| 143 | + * of the protocol version followed by a numeric status code, and the | ||
| 144 | + * textual phrase associated with the status code, with each element | ||
| 145 | + * separated by SP characters. No CR or LF is allowed except in the | ||
| 146 | + * final CRLF sequence. | ||
| 147 | + * Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF | ||
| 148 | + */ | ||
| 149 | + // @see about the version of rtsp, see __SRS_VERSION | ||
| 150 | + // @see about the status of rtsp, see SRS_CONSTS_RTSP_OK | ||
| 151 | + int status; | ||
| 152 | + /** | ||
| 153 | + * 12.17 CSeq | ||
| 154 | + * The CSeq field specifies the sequence number for an RTSP requestresponse | ||
| 155 | + * pair. This field MUST be present in all requests and | ||
| 156 | + * responses. For every RTSP request containing the given sequence | ||
| 157 | + * number, there will be a corresponding response having the same | ||
| 158 | + * number. Any retransmitted request must contain the same sequence | ||
| 159 | + * number as the original (i.e. the sequence number is not incremented | ||
| 160 | + * for retransmissions of the same request). | ||
| 161 | + */ | ||
| 162 | + int seq; | ||
| 163 | +public: | ||
| 164 | + SrsRtspResponse(int cseq); | ||
| 165 | + virtual ~SrsRtspResponse(); | ||
| 166 | +public: | ||
| 167 | + /** | ||
| 168 | + * encode message to string. | ||
| 169 | + */ | ||
| 170 | + virtual std::stringstream& encode(std::stringstream& ss); | ||
| 171 | +}; | ||
| 172 | + | ||
| 173 | +/** | ||
| 174 | +* 10 Method Definitions | ||
| 175 | +* The method token indicates the method to be performed on the resource | ||
| 176 | +* identified by the Request-URI. The method is case-sensitive. New | ||
| 177 | +* methods may be defined in the future. Method names may not start with | ||
| 178 | +* a $ character (decimal 24) and must be a token. Methods are | ||
| 179 | +* summarized in Table 2. | ||
| 180 | +* Notes on Table 2: PAUSE is recommended, but not required in that a | ||
| 181 | +* fully functional server can be built that does not support this | ||
| 182 | +* method, for example, for live feeds. If a server does not support a | ||
| 183 | +* particular method, it MUST return "501 Not Implemented" and a client | ||
| 184 | +* SHOULD not try this method again for this server. | ||
| 185 | +*/ | ||
| 186 | +enum SrsRtspMethod | ||
| 187 | +{ | ||
| 188 | + SrsRtspMethodDescribe = 0x0001, | ||
| 189 | + SrsRtspMethodAnnounce = 0x0002, | ||
| 190 | + SrsRtspMethodGetParameter = 0x0004, | ||
| 191 | + SrsRtspMethodOptions = 0x0008, | ||
| 192 | + SrsRtspMethodPause = 0x0010, | ||
| 193 | + SrsRtspMethodPlay = 0x0020, | ||
| 194 | + SrsRtspMethodRecord = 0x0040, | ||
| 195 | + SrsRtspMethodRedirect = 0x0080, | ||
| 196 | + SrsRtspMethodSetup = 0x0100, | ||
| 197 | + SrsRtspMethodSetParameter = 0x0200, | ||
| 198 | + SrsRtspMethodTeardown = 0x0400, | ||
| 199 | +}; | ||
| 200 | + | ||
| 201 | +/** | ||
| 202 | +* 10.1 OPTIONS | ||
| 203 | +* The behavior is equivalent to that described in [H9.2]. An OPTIONS | ||
| 204 | +* request may be issued at any time, e.g., if the client is about to | ||
| 205 | +* try a nonstandard request. It does not influence server state. | ||
| 206 | +*/ | ||
| 207 | +class SrsRtspOptionsResponse : public SrsRtspResponse | ||
| 208 | +{ | ||
| 209 | +public: | ||
| 210 | + /** | ||
| 211 | + * join of SrsRtspMethod | ||
| 212 | + */ | ||
| 213 | + SrsRtspMethod methods; | ||
| 214 | +public: | ||
| 215 | + SrsRtspOptionsResponse(int cseq); | ||
| 216 | + virtual ~SrsRtspOptionsResponse(); | ||
| 217 | +public: | ||
| 218 | + virtual std::stringstream& encode(std::stringstream& ss); | ||
| 219 | +}; | ||
| 220 | + | ||
| 221 | +/** | ||
| 222 | +* the state of rtsp token. | ||
| 223 | +*/ | ||
| 224 | +enum SrsRtspTokenState | ||
| 225 | +{ | ||
| 226 | + /** | ||
| 227 | + * parse token failed, default state. | ||
| 228 | + */ | ||
| 229 | + SrsRtspTokenStateError = 100, | ||
| 230 | + /** | ||
| 231 | + * when SP follow the token. | ||
| 232 | + */ | ||
| 233 | + SrsRtspTokenStateNormal = 101, | ||
| 234 | + /** | ||
| 235 | + * when CRLF follow the token. | ||
| 236 | + */ | ||
| 237 | + SrsRtspTokenStateEOF = 102, | ||
| 238 | +}; | ||
| 239 | + | ||
| 37 | /** | 240 | /** |
| 38 | * the rtsp protocol stack to parse the rtsp packets. | 241 | * the rtsp protocol stack to parse the rtsp packets. |
| 39 | */ | 242 | */ |
| @@ -41,12 +244,57 @@ class SrsRtspStack | @@ -41,12 +244,57 @@ class SrsRtspStack | ||
| 41 | { | 244 | { |
| 42 | private: | 245 | private: |
| 43 | /** | 246 | /** |
| 247 | + * cached bytes buffer. | ||
| 248 | + */ | ||
| 249 | + SrsSimpleBuffer* buf; | ||
| 250 | + /** | ||
| 44 | * underlayer socket object, send/recv bytes. | 251 | * underlayer socket object, send/recv bytes. |
| 45 | */ | 252 | */ |
| 46 | ISrsProtocolReaderWriter* skt; | 253 | ISrsProtocolReaderWriter* skt; |
| 47 | public: | 254 | public: |
| 48 | SrsRtspStack(ISrsProtocolReaderWriter* s); | 255 | SrsRtspStack(ISrsProtocolReaderWriter* s); |
| 49 | virtual ~SrsRtspStack(); | 256 | virtual ~SrsRtspStack(); |
| 257 | +public: | ||
| 258 | + /** | ||
| 259 | + * recv rtsp message from underlayer io. | ||
| 260 | + * @param preq the output rtsp request message, which user must free it. | ||
| 261 | + * @return an int error code. | ||
| 262 | + * ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF. | ||
| 263 | + */ | ||
| 264 | + virtual int recv_message(SrsRtspRequest** preq); | ||
| 265 | + /** | ||
| 266 | + * send rtsp message over underlayer io. | ||
| 267 | + * @param res the rtsp response message, which user should never free it. | ||
| 268 | + * @return an int error code. | ||
| 269 | + */ | ||
| 270 | + virtual int send_message(SrsRtspResponse* res); | ||
| 271 | +private: | ||
| 272 | + /** | ||
| 273 | + * recv the rtsp message. | ||
| 274 | + */ | ||
| 275 | + virtual int do_recv_message(SrsRtspRequest* req); | ||
| 276 | + /** | ||
| 277 | + * read a normal token from io, error when token state is not normal. | ||
| 278 | + */ | ||
| 279 | + virtual int recv_token_normal(std::string& token); | ||
| 280 | + /** | ||
| 281 | + * read a normal token from io, error when token state is not eof. | ||
| 282 | + */ | ||
| 283 | + virtual int recv_token_eof(std::string& token); | ||
| 284 | + /** | ||
| 285 | + * read the token util got eof, for example, to read the response status Reason-Phrase | ||
| 286 | + */ | ||
| 287 | + virtual int recv_token_util_eof(std::string& token); | ||
| 288 | + /** | ||
| 289 | + * read a token from io, split by SP, endswith CRLF: | ||
| 290 | + * token1 SP token2 SP ... tokenN CRLF | ||
| 291 | + * @param normal_ch, the char to indicates the normal token. | ||
| 292 | + * the SP use to indicates the normal token, @see __SRS_RTSP_SP | ||
| 293 | + * the 0x00 use to ignore normal token flag. @see recv_token_util_eof | ||
| 294 | + * @param token, output the read token. | ||
| 295 | + * @param state, output the token parse state. | ||
| 296 | + */ | ||
| 297 | + virtual int recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch = __SRS_RTSP_SP); | ||
| 50 | }; | 298 | }; |
| 51 | 299 | ||
| 52 | #endif | 300 | #endif |
-
请 注册 或 登录 后发表评论