Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2015-02-16 22:15:59 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
604f4cc57bc881f69a60ea484dca312a99657995
604f4cc5
1 parent
c0e50265
for #133, support the rtsp options request and response.
显示空白字符变更
内嵌
并排对比
正在显示
8 个修改的文件
包含
849 行增加
和
33 行删除
trunk/src/app/srs_app_http.cpp
trunk/src/app/srs_app_http.hpp
trunk/src/app/srs_app_http_client.cpp
trunk/src/app/srs_app_rtsp.cpp
trunk/src/kernel/srs_kernel_consts.hpp
trunk/src/kernel/srs_kernel_error.hpp
trunk/src/protocol/srs_rtsp_stack.cpp
trunk/src/protocol/srs_rtsp_stack.hpp
trunk/src/app/srs_app_http.cpp
查看文件 @
604f4cc
...
...
@@ -62,7 +62,7 @@ int srs_go_http_response_json(ISrsGoHttpResponseWriter* w, string data)
}
// get the status text of code.
string
srs_generate_status_text
(
int
status
)
string
srs_generate_
http_
status_text
(
int
status
)
{
static
std
::
map
<
int
,
std
::
string
>
_status_map
;
if
(
_status_map
.
empty
())
{
...
...
@@ -212,7 +212,7 @@ void SrsGoHttpHeader::write(stringstream& ss)
{
std
::
map
<
std
::
string
,
std
::
string
>::
iterator
it
;
for
(
it
=
headers
.
begin
();
it
!=
headers
.
end
();
++
it
)
{
ss
<<
it
->
first
<<
": "
<<
it
->
second
<<
__SRS_CRLF
;
ss
<<
it
->
first
<<
": "
<<
it
->
second
<<
__SRS_
HTTP_
CRLF
;
}
}
...
...
@@ -711,7 +711,7 @@ int SrsGoHttpResponseWriter::final_request()
// complete the chunked encoding.
if
(
content_length
==
-
1
)
{
std
::
stringstream
ss
;
ss
<<
0
<<
__SRS_
CRLF
<<
__SRS
_CRLF
;
ss
<<
0
<<
__SRS_
HTTP_CRLF
<<
__SRS_HTTP
_CRLF
;
std
::
string
ch
=
ss
.
str
();
return
skt
->
write
((
void
*
)
ch
.
data
(),
(
int
)
ch
.
length
(),
NULL
);
}
...
...
@@ -752,7 +752,7 @@ int SrsGoHttpResponseWriter::write(char* data, int size)
// send in chunked encoding.
std
::
stringstream
ss
;
ss
<<
hex
<<
size
<<
__SRS_CRLF
;
ss
<<
hex
<<
size
<<
__SRS_
HTTP_
CRLF
;
std
::
string
ch
=
ss
.
str
();
if
((
ret
=
skt
->
write
((
void
*
)
ch
.
data
(),
(
int
)
ch
.
length
(),
NULL
))
!=
ERROR_SUCCESS
)
{
return
ret
;
...
...
@@ -760,7 +760,7 @@ int SrsGoHttpResponseWriter::write(char* data, int size)
if
((
ret
=
skt
->
write
((
void
*
)
data
,
size
,
NULL
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
skt
->
write
((
void
*
)
__SRS_CRLF
,
2
,
NULL
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
skt
->
write
((
void
*
)
__SRS_
HTTP_
CRLF
,
2
,
NULL
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
...
...
@@ -794,7 +794,7 @@ int SrsGoHttpResponseWriter::send_header(char* data, int size)
// status_line
ss
<<
"HTTP/1.1 "
<<
status
<<
" "
<<
srs_generate_
status_text
(
status
)
<<
__SRS
_CRLF
;
<<
srs_generate_
http_status_text
(
status
)
<<
__SRS_HTTP
_CRLF
;
// detect content type
if
(
srs_go_http_body_allowd
(
status
))
{
...
...
@@ -820,7 +820,7 @@ int SrsGoHttpResponseWriter::send_header(char* data, int size)
hdr
->
write
(
ss
);
// header_eof
ss
<<
__SRS_CRLF
;
ss
<<
__SRS_
HTTP_
CRLF
;
std
::
string
buf
=
ss
.
str
();
return
skt
->
write
((
void
*
)
buf
.
c_str
(),
buf
.
length
(),
NULL
);
...
...
trunk/src/app/srs_app_http.hpp
查看文件 @
604f4cc
...
...
@@ -39,6 +39,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <http_parser.h>
#include <srs_app_st.hpp>
#include <srs_kernel_consts.hpp>
class
SrsRequest
;
class
SrsStSocket
;
...
...
@@ -51,19 +52,19 @@ class ISrsGoHttpResponseWriter;
// http specification
// CR = <US-ASCII CR, carriage return (13)>
#define __SRS_CR SRS_CONSTS_CR // 0x0D
#define __SRS_
HTTP_
CR SRS_CONSTS_CR // 0x0D
// LF = <US-ASCII LF, linefeed (10)>
#define __SRS_LF SRS_CONSTS_LF // 0x0A
#define __SRS_
HTTP_
LF SRS_CONSTS_LF // 0x0A
// SP = <US-ASCII SP, space (32)>
#define __SRS_SP ' ' // 0x20
#define __SRS_
HTTP_
SP ' ' // 0x20
// HT = <US-ASCII HT, horizontal-tab (9)>
#define __SRS_HT '\x09' // 0x09
#define __SRS_HT
TP_HT
'\x09' // 0x09
// HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all
// protocol elements except the entity-body (see appendix 19.3 for
// tolerant applications).
#define __SRS_CRLF "\r\n" // 0x0D0A
#define __SRS_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A
#define __SRS_HTTP_CRLF "\r\n" // 0x0D0A
#define __SRS_HTTP_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A
// @see SrsHttpMessage._http_ts_send_buffer
#define __SRS_HTTP_TS_SEND_BUFFER_SIZE 4096
...
...
trunk/src/app/srs_app_http_client.cpp
查看文件 @
604f4cc
...
...
@@ -76,13 +76,13 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r
// POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s
std
::
stringstream
ss
;
ss
<<
"POST "
<<
uri
->
get_path
()
<<
" "
<<
"HTTP/1.1"
<<
__SRS_CRLF
<<
"Host: "
<<
uri
->
get_host
()
<<
__SRS_CRLF
<<
"Connection: Keep-Alive"
<<
__SRS_CRLF
<<
"Content-Length: "
<<
std
::
dec
<<
req
.
length
()
<<
__SRS_CRLF
<<
"User-Agent: "
<<
RTMP_SIG_SRS_NAME
<<
RTMP_SIG_SRS_VERSION
<<
__SRS_CRLF
<<
"Content-Type: application/json"
<<
__SRS_CRLF
<<
__SRS_CRLF
<<
"HTTP/1.1"
<<
__SRS_HTTP_CRLF
<<
"Host: "
<<
uri
->
get_host
()
<<
__SRS_HTTP_CRLF
<<
"Connection: Keep-Alive"
<<
__SRS_HTTP_CRLF
<<
"Content-Length: "
<<
std
::
dec
<<
req
.
length
()
<<
__SRS_HTTP_CRLF
<<
"User-Agent: "
<<
RTMP_SIG_SRS_NAME
<<
RTMP_SIG_SRS_VERSION
<<
__SRS_HTTP_CRLF
<<
"Content-Type: application/json"
<<
__SRS_HTTP_CRLF
<<
__SRS_HTTP_CRLF
<<
req
;
SrsStSocket
skt
(
stfd
);
...
...
trunk/src/app/srs_app_rtsp.cpp
查看文件 @
604f4cc
...
...
@@ -32,6 +32,7 @@ using namespace std;
#include <srs_app_st_socket.hpp>
#include <srs_kernel_log.hpp>
#include <srs_app_utility.hpp>
#include <srs_core_autofree.hpp>
#ifdef SRS_AUTO_STREAM_CASTER
...
...
@@ -76,6 +77,28 @@ int SrsRtspConn::do_cycle()
std
::
string
ip
=
srs_get_peer_ip
(
st_netfd_fileno
(
stfd
));
srs_trace
(
"rtsp: serve %s"
,
ip
.
c_str
());
// consume all rtsp messages.
for
(;;)
{
SrsRtspRequest
*
req
=
NULL
;
if
((
ret
=
rtsp
->
recv_message
(
&
req
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: recv request failed. ret=%d"
,
ret
);
}
return
ret
;
}
SrsAutoFree
(
SrsRtspRequest
,
req
);
srs_info
(
"rtsp: got rtsp request"
);
if
(
req
->
is_options
())
{
if
((
ret
=
rtsp
->
send_message
(
new
SrsRtspOptionsResponse
(
req
->
seq
)))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: send response failed. ret=%d"
,
ret
);
}
return
ret
;
}
}
}
return
ret
;
}
...
...
trunk/src/kernel/srs_kernel_consts.hpp
查看文件 @
604f4cc
...
...
@@ -265,43 +265,137 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SRS_CONSTS_HTTP_Continue_str "Continue"
#define SRS_CONSTS_HTTP_SwitchingProtocols_str "Switching Protocols"
#define SRS_CONSTS_HTTP_OK_str "OK"
#define SRS_CONSTS_HTTP_Created_str "Created
"
#define SRS_CONSTS_HTTP_Created_str "Created"
#define SRS_CONSTS_HTTP_Accepted_str "Accepted"
#define SRS_CONSTS_HTTP_NonAuthoritativeInformation_str "Non Authoritative Information "
#define SRS_CONSTS_HTTP_NoContent_str "No Content "
#define SRS_CONSTS_HTTP_NonAuthoritativeInformation_str "Non Authoritative Information"
#define SRS_CONSTS_HTTP_NoContent_str "No Content"
#define SRS_CONSTS_HTTP_ResetContent_str "Reset Content"
#define SRS_CONSTS_HTTP_PartialContent_str "Partial Content"
#define SRS_CONSTS_HTTP_MultipleChoices_str "Multiple Choices
"
#define SRS_CONSTS_HTTP_MultipleChoices_str "Multiple Choices"
#define SRS_CONSTS_HTTP_MovedPermanently_str "Moved Permanently"
#define SRS_CONSTS_HTTP_Found_str "Found"
#define SRS_CONSTS_HTTP_SeeOther_str "See Other"
#define SRS_CONSTS_HTTP_NotModified_str "Not Modified
"
#define SRS_CONSTS_HTTP_NotModified_str "Not Modified"
#define SRS_CONSTS_HTTP_UseProxy_str "Use Proxy"
#define SRS_CONSTS_HTTP_TemporaryRedirect_str "Temporary Redirect
"
#define SRS_CONSTS_HTTP_TemporaryRedirect_str "Temporary Redirect"
#define SRS_CONSTS_HTTP_BadRequest_str "Bad Request"
#define SRS_CONSTS_HTTP_Unauthorized_str "Unauthorized"
#define SRS_CONSTS_HTTP_PaymentRequired_str "Payment Required "
#define SRS_CONSTS_HTTP_Forbidden_str "Forbidden "
#define SRS_CONSTS_HTTP_PaymentRequired_str "Payment Required"
#define SRS_CONSTS_HTTP_Forbidden_str "Forbidden"
#define SRS_CONSTS_HTTP_NotFound_str "Not Found"
#define SRS_CONSTS_HTTP_MethodNotAllowed_str "Method Not Allowed"
#define SRS_CONSTS_HTTP_NotAcceptable_str "Not Acceptable "
#define SRS_CONSTS_HTTP_ProxyAuthenticationRequired_str "Proxy Authentication Required "
#define SRS_CONSTS_HTTP_NotAcceptable_str "Not Acceptable"
#define SRS_CONSTS_HTTP_ProxyAuthenticationRequired_str "Proxy Authentication Required"
#define SRS_CONSTS_HTTP_RequestTimeout_str "Request Timeout"
#define SRS_CONSTS_HTTP_Conflict_str "Conflict"
#define SRS_CONSTS_HTTP_Gone_str "Gone"
#define SRS_CONSTS_HTTP_LengthRequired_str "Length Required"
#define SRS_CONSTS_HTTP_PreconditionFailed_str "Precondition Failed"
#define SRS_CONSTS_HTTP_RequestEntityTooLarge_str "Request Entity Too Large
"
#define SRS_CONSTS_HTTP_RequestEntityTooLarge_str "Request Entity Too Large"
#define SRS_CONSTS_HTTP_RequestURITooLarge_str "Request URI Too Large"
#define SRS_CONSTS_HTTP_UnsupportedMediaType_str "Unsupported Media Type"
#define SRS_CONSTS_HTTP_RequestedRangeNotSatisfiable_str "Requested Range Not Satisfiable"
#define SRS_CONSTS_HTTP_ExpectationFailed_str "Expectation Failed "
#define SRS_CONSTS_HTTP_InternalServerError_str "Internal Server Error "
#define SRS_CONSTS_HTTP_ExpectationFailed_str "Expectation Failed"
#define SRS_CONSTS_HTTP_InternalServerError_str "Internal Server Error"
#define SRS_CONSTS_HTTP_NotImplemented_str "Not Implemented"
#define SRS_CONSTS_HTTP_BadGateway_str "Bad Gateway"
#define SRS_CONSTS_HTTP_ServiceUnavailable_str "Service Unavailable"
#define SRS_CONSTS_HTTP_GatewayTimeout_str "Gateway Timeout"
#define SRS_CONSTS_HTTP_HTTPVersionNotSupported_str "HTTP Version Not Supported"
///////////////////////////////////////////////////////////
// RTSP consts values
///////////////////////////////////////////////////////////
// 7.1.1 Status Code and Reason Phrase
#define SRS_CONSTS_RTSP_Continue 100
#define SRS_CONSTS_RTSP_OK 200
#define SRS_CONSTS_RTSP_Created 201
#define SRS_CONSTS_RTSP_LowOnStorageSpace 250
#define SRS_CONSTS_RTSP_MultipleChoices 300
#define SRS_CONSTS_RTSP_MovedPermanently 301
#define SRS_CONSTS_RTSP_MovedTemporarily 302
#define SRS_CONSTS_RTSP_SeeOther 303
#define SRS_CONSTS_RTSP_NotModified 304
#define SRS_CONSTS_RTSP_UseProxy 305
#define SRS_CONSTS_RTSP_BadRequest 400
#define SRS_CONSTS_RTSP_Unauthorized 401
#define SRS_CONSTS_RTSP_PaymentRequired 402
#define SRS_CONSTS_RTSP_Forbidden 403
#define SRS_CONSTS_RTSP_NotFound 404
#define SRS_CONSTS_RTSP_MethodNotAllowed 405
#define SRS_CONSTS_RTSP_NotAcceptable 406
#define SRS_CONSTS_RTSP_ProxyAuthenticationRequired 407
#define SRS_CONSTS_RTSP_RequestTimeout 408
#define SRS_CONSTS_RTSP_Gone 410
#define SRS_CONSTS_RTSP_LengthRequired 411
#define SRS_CONSTS_RTSP_PreconditionFailed 412
#define SRS_CONSTS_RTSP_RequestEntityTooLarge 413
#define SRS_CONSTS_RTSP_RequestURITooLarge 414
#define SRS_CONSTS_RTSP_UnsupportedMediaType 415
#define SRS_CONSTS_RTSP_ParameterNotUnderstood 451
#define SRS_CONSTS_RTSP_ConferenceNotFound 452
#define SRS_CONSTS_RTSP_NotEnoughBandwidth 453
#define SRS_CONSTS_RTSP_SessionNotFound 454
#define SRS_CONSTS_RTSP_MethodNotValidInThisState 455
#define SRS_CONSTS_RTSP_HeaderFieldNotValidForResource 456
#define SRS_CONSTS_RTSP_InvalidRange 457
#define SRS_CONSTS_RTSP_ParameterIsReadOnly 458
#define SRS_CONSTS_RTSP_AggregateOperationNotAllowed 459
#define SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed 460
#define SRS_CONSTS_RTSP_UnsupportedTransport 461
#define SRS_CONSTS_RTSP_DestinationUnreachable 462
#define SRS_CONSTS_RTSP_InternalServerError 500
#define SRS_CONSTS_RTSP_NotImplemented 501
#define SRS_CONSTS_RTSP_BadGateway 502
#define SRS_CONSTS_RTSP_ServiceUnavailable 503
#define SRS_CONSTS_RTSP_GatewayTimeout 504
#define SRS_CONSTS_RTSP_RTSPVersionNotSupported 505
#define SRS_CONSTS_RTSP_OptionNotSupported 551
#define SRS_CONSTS_RTSP_Continue_str "Continue"
#define SRS_CONSTS_RTSP_OK_str "OK"
#define SRS_CONSTS_RTSP_Created_str "Created"
#define SRS_CONSTS_RTSP_LowOnStorageSpace_str "Low on Storage Space"
#define SRS_CONSTS_RTSP_MultipleChoices_str "Multiple Choices"
#define SRS_CONSTS_RTSP_MovedPermanently_str "Moved Permanently"
#define SRS_CONSTS_RTSP_MovedTemporarily_str "Moved Temporarily"
#define SRS_CONSTS_RTSP_SeeOther_str "See Other"
#define SRS_CONSTS_RTSP_NotModified_str "Not Modified"
#define SRS_CONSTS_RTSP_UseProxy_str "Use Proxy"
#define SRS_CONSTS_RTSP_BadRequest_str "Bad Request"
#define SRS_CONSTS_RTSP_Unauthorized_str "Unauthorized"
#define SRS_CONSTS_RTSP_PaymentRequired_str "Payment Required"
#define SRS_CONSTS_RTSP_Forbidden_str "Forbidden"
#define SRS_CONSTS_RTSP_NotFound_str "Not Found"
#define SRS_CONSTS_RTSP_MethodNotAllowed_str "Method Not Allowed"
#define SRS_CONSTS_RTSP_NotAcceptable_str "Not Acceptable"
#define SRS_CONSTS_RTSP_ProxyAuthenticationRequired_str "Proxy Authentication Required"
#define SRS_CONSTS_RTSP_RequestTimeout_str "Request Timeout"
#define SRS_CONSTS_RTSP_Gone_str "Gone"
#define SRS_CONSTS_RTSP_LengthRequired_str "Length Required"
#define SRS_CONSTS_RTSP_PreconditionFailed_str "Precondition Failed"
#define SRS_CONSTS_RTSP_RequestEntityTooLarge_str "Request Entity Too Large"
#define SRS_CONSTS_RTSP_RequestURITooLarge_str "Request URI Too Large"
#define SRS_CONSTS_RTSP_UnsupportedMediaType_str "Unsupported Media Type"
#define SRS_CONSTS_RTSP_ParameterNotUnderstood_str "Invalid parameter"
#define SRS_CONSTS_RTSP_ConferenceNotFound_str "Illegal Conference Identifier"
#define SRS_CONSTS_RTSP_NotEnoughBandwidth_str "Not Enough Bandwidth"
#define SRS_CONSTS_RTSP_SessionNotFound_str "Session Not Found"
#define SRS_CONSTS_RTSP_MethodNotValidInThisState_str "Method Not Valid In This State"
#define SRS_CONSTS_RTSP_HeaderFieldNotValidForResource_str "Header Field Not Valid"
#define SRS_CONSTS_RTSP_InvalidRange_str "Invalid Range"
#define SRS_CONSTS_RTSP_ParameterIsReadOnly_str "Parameter Is Read-Only"
#define SRS_CONSTS_RTSP_AggregateOperationNotAllowed_str "Aggregate Operation Not Allowed"
#define SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed_str "Only Aggregate Operation Allowed"
#define SRS_CONSTS_RTSP_UnsupportedTransport_str "Unsupported Transport"
#define SRS_CONSTS_RTSP_DestinationUnreachable_str "Destination Unreachable"
#define SRS_CONSTS_RTSP_InternalServerError_str "Internal Server Error"
#define SRS_CONSTS_RTSP_NotImplemented_str "Not Implemented"
#define SRS_CONSTS_RTSP_BadGateway_str "Bad Gateway"
#define SRS_CONSTS_RTSP_ServiceUnavailable_str "Service Unavailable"
#define SRS_CONSTS_RTSP_GatewayTimeout_str "Gateway Timeout"
#define SRS_CONSTS_RTSP_RTSPVersionNotSupported_str "RTSP Version Not Supported"
#define SRS_CONSTS_RTSP_OptionNotSupported_str "Option not support"
#endif
...
...
trunk/src/kernel/srs_kernel_error.hpp
查看文件 @
604f4cc
...
...
@@ -142,6 +142,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_OpenSslComputeSharedKey 2039
#define ERROR_RTMP_MIC_CHUNKSIZE_CHANGED 2040
#define ERROR_RTMP_MIC_CACHE_OVERFLOW 2041
#define ERROR_RTSP_TOKEN_NOT_NORMAL 2042
#define ERROR_RTSP_REQUEST_HEADER_EOF 2043
//
// system control message,
// not an error, but special control logic.
...
...
trunk/src/protocol/srs_rtsp_stack.cpp
查看文件 @
604f4cc
...
...
@@ -23,17 +23,465 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_rtsp_stack.hpp>
#include <stdlib.h>
#include <map>
using
namespace
std
;
#include <srs_rtmp_io.hpp>
#include <srs_kernel_buffer.hpp>
#include <srs_kernel_error.hpp>
#include <srs_kernel_log.hpp>
#include <srs_kernel_consts.hpp>
#ifdef SRS_AUTO_STREAM_CASTER
#define __SRS_RTSP_BUFFER 4096
// get the status text of code.
string
srs_generate_rtsp_status_text
(
int
status
)
{
static
std
::
map
<
int
,
std
::
string
>
_status_map
;
if
(
_status_map
.
empty
())
{
_status_map
[
SRS_CONSTS_RTSP_Continue
]
=
SRS_CONSTS_RTSP_Continue_str
;
_status_map
[
SRS_CONSTS_RTSP_OK
]
=
SRS_CONSTS_RTSP_OK_str
;
_status_map
[
SRS_CONSTS_RTSP_Created
]
=
SRS_CONSTS_RTSP_Created_str
;
_status_map
[
SRS_CONSTS_RTSP_LowOnStorageSpace
]
=
SRS_CONSTS_RTSP_LowOnStorageSpace_str
;
_status_map
[
SRS_CONSTS_RTSP_MultipleChoices
]
=
SRS_CONSTS_RTSP_MultipleChoices_str
;
_status_map
[
SRS_CONSTS_RTSP_MovedPermanently
]
=
SRS_CONSTS_RTSP_MovedPermanently_str
;
_status_map
[
SRS_CONSTS_RTSP_MovedTemporarily
]
=
SRS_CONSTS_RTSP_MovedTemporarily_str
;
_status_map
[
SRS_CONSTS_RTSP_SeeOther
]
=
SRS_CONSTS_RTSP_SeeOther_str
;
_status_map
[
SRS_CONSTS_RTSP_NotModified
]
=
SRS_CONSTS_RTSP_NotModified_str
;
_status_map
[
SRS_CONSTS_RTSP_UseProxy
]
=
SRS_CONSTS_RTSP_UseProxy_str
;
_status_map
[
SRS_CONSTS_RTSP_BadRequest
]
=
SRS_CONSTS_RTSP_BadRequest_str
;
_status_map
[
SRS_CONSTS_RTSP_Unauthorized
]
=
SRS_CONSTS_RTSP_Unauthorized_str
;
_status_map
[
SRS_CONSTS_RTSP_PaymentRequired
]
=
SRS_CONSTS_RTSP_PaymentRequired_str
;
_status_map
[
SRS_CONSTS_RTSP_Forbidden
]
=
SRS_CONSTS_RTSP_Forbidden_str
;
_status_map
[
SRS_CONSTS_RTSP_NotFound
]
=
SRS_CONSTS_RTSP_NotFound_str
;
_status_map
[
SRS_CONSTS_RTSP_MethodNotAllowed
]
=
SRS_CONSTS_RTSP_MethodNotAllowed_str
;
_status_map
[
SRS_CONSTS_RTSP_NotAcceptable
]
=
SRS_CONSTS_RTSP_NotAcceptable_str
;
_status_map
[
SRS_CONSTS_RTSP_ProxyAuthenticationRequired
]
=
SRS_CONSTS_RTSP_ProxyAuthenticationRequired_str
;
_status_map
[
SRS_CONSTS_RTSP_RequestTimeout
]
=
SRS_CONSTS_RTSP_RequestTimeout_str
;
_status_map
[
SRS_CONSTS_RTSP_Gone
]
=
SRS_CONSTS_RTSP_Gone_str
;
_status_map
[
SRS_CONSTS_RTSP_LengthRequired
]
=
SRS_CONSTS_RTSP_LengthRequired_str
;
_status_map
[
SRS_CONSTS_RTSP_PreconditionFailed
]
=
SRS_CONSTS_RTSP_PreconditionFailed_str
;
_status_map
[
SRS_CONSTS_RTSP_RequestEntityTooLarge
]
=
SRS_CONSTS_RTSP_RequestEntityTooLarge_str
;
_status_map
[
SRS_CONSTS_RTSP_RequestURITooLarge
]
=
SRS_CONSTS_RTSP_RequestURITooLarge_str
;
_status_map
[
SRS_CONSTS_RTSP_UnsupportedMediaType
]
=
SRS_CONSTS_RTSP_UnsupportedMediaType_str
;
_status_map
[
SRS_CONSTS_RTSP_ParameterNotUnderstood
]
=
SRS_CONSTS_RTSP_ParameterNotUnderstood_str
;
_status_map
[
SRS_CONSTS_RTSP_ConferenceNotFound
]
=
SRS_CONSTS_RTSP_ConferenceNotFound_str
;
_status_map
[
SRS_CONSTS_RTSP_NotEnoughBandwidth
]
=
SRS_CONSTS_RTSP_NotEnoughBandwidth_str
;
_status_map
[
SRS_CONSTS_RTSP_SessionNotFound
]
=
SRS_CONSTS_RTSP_SessionNotFound_str
;
_status_map
[
SRS_CONSTS_RTSP_MethodNotValidInThisState
]
=
SRS_CONSTS_RTSP_MethodNotValidInThisState_str
;
_status_map
[
SRS_CONSTS_RTSP_HeaderFieldNotValidForResource
]
=
SRS_CONSTS_RTSP_HeaderFieldNotValidForResource_str
;
_status_map
[
SRS_CONSTS_RTSP_InvalidRange
]
=
SRS_CONSTS_RTSP_InvalidRange_str
;
_status_map
[
SRS_CONSTS_RTSP_ParameterIsReadOnly
]
=
SRS_CONSTS_RTSP_ParameterIsReadOnly_str
;
_status_map
[
SRS_CONSTS_RTSP_AggregateOperationNotAllowed
]
=
SRS_CONSTS_RTSP_AggregateOperationNotAllowed_str
;
_status_map
[
SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed
]
=
SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed_str
;
_status_map
[
SRS_CONSTS_RTSP_UnsupportedTransport
]
=
SRS_CONSTS_RTSP_UnsupportedTransport_str
;
_status_map
[
SRS_CONSTS_RTSP_DestinationUnreachable
]
=
SRS_CONSTS_RTSP_DestinationUnreachable_str
;
_status_map
[
SRS_CONSTS_RTSP_InternalServerError
]
=
SRS_CONSTS_RTSP_InternalServerError_str
;
_status_map
[
SRS_CONSTS_RTSP_NotImplemented
]
=
SRS_CONSTS_RTSP_NotImplemented_str
;
_status_map
[
SRS_CONSTS_RTSP_BadGateway
]
=
SRS_CONSTS_RTSP_BadGateway_str
;
_status_map
[
SRS_CONSTS_RTSP_ServiceUnavailable
]
=
SRS_CONSTS_RTSP_ServiceUnavailable_str
;
_status_map
[
SRS_CONSTS_RTSP_GatewayTimeout
]
=
SRS_CONSTS_RTSP_GatewayTimeout_str
;
_status_map
[
SRS_CONSTS_RTSP_RTSPVersionNotSupported
]
=
SRS_CONSTS_RTSP_RTSPVersionNotSupported_str
;
_status_map
[
SRS_CONSTS_RTSP_OptionNotSupported
]
=
SRS_CONSTS_RTSP_OptionNotSupported_str
;
}
std
::
string
status_text
;
if
(
_status_map
.
find
(
status
)
==
_status_map
.
end
())
{
status_text
=
"Status Unknown"
;
}
else
{
status_text
=
_status_map
[
status
];
}
return
status_text
;
}
std
::
string
srs_generate_rtsp_method_str
(
SrsRtspMethod
method
)
{
switch
(
method
)
{
case
SrsRtspMethodDescribe
:
return
__SRS_METHOD_DESCRIBE
;
case
SrsRtspMethodAnnounce
:
return
__SRS_METHOD_ANNOUNCE
;
case
SrsRtspMethodGetParameter
:
return
__SRS_METHOD_GET_PARAMETER
;
case
SrsRtspMethodOptions
:
return
__SRS_METHOD_OPTIONS
;
case
SrsRtspMethodPause
:
return
__SRS_METHOD_PAUSE
;
case
SrsRtspMethodPlay
:
return
__SRS_METHOD_PLAY
;
case
SrsRtspMethodRecord
:
return
__SRS_METHOD_RECORD
;
case
SrsRtspMethodRedirect
:
return
__SRS_METHOD_REDIRECT
;
case
SrsRtspMethodSetup
:
return
__SRS_METHOD_SETUP
;
case
SrsRtspMethodSetParameter
:
return
__SRS_METHOD_SET_PARAMETER
;
case
SrsRtspMethodTeardown
:
return
__SRS_METHOD_TEARDOWN
;
default
:
return
"Unknown"
;
}
}
SrsRtspRequest
::
SrsRtspRequest
()
{
seq
=
0
;
}
SrsRtspRequest
::~
SrsRtspRequest
()
{
}
bool
SrsRtspRequest
::
is_options
()
{
return
method
==
__SRS_METHOD_OPTIONS
;
}
SrsRtspResponse
::
SrsRtspResponse
(
int
cseq
)
{
seq
=
cseq
;
status
=
SRS_CONSTS_RTSP_OK
;
}
SrsRtspResponse
::~
SrsRtspResponse
()
{
}
stringstream
&
SrsRtspResponse
::
encode
(
stringstream
&
ss
)
{
// status line
ss
<<
__SRS_VERSION
<<
__SRS_RTSP_SP
<<
status
<<
__SRS_RTSP_SP
<<
srs_generate_rtsp_status_text
(
status
)
<<
__SRS_RTSP_CRLF
;
// cseq
ss
<<
__SRS_TOKEN_CSEQ
<<
":"
<<
__SRS_RTSP_SP
<<
seq
<<
__SRS_RTSP_CRLF
;
// others.
ss
<<
"Cache-Control: no-store"
<<
__SRS_RTSP_CRLF
<<
"Pragma: no-cache"
<<
__SRS_RTSP_CRLF
<<
"Server: "
<<
RTMP_SIG_SRS_SERVER
<<
__SRS_RTSP_CRLF
;
return
ss
;
}
SrsRtspOptionsResponse
::
SrsRtspOptionsResponse
(
int
cseq
)
:
SrsRtspResponse
(
cseq
)
{
methods
=
(
SrsRtspMethod
)(
SrsRtspMethodDescribe
|
SrsRtspMethodOptions
|
SrsRtspMethodPause
|
SrsRtspMethodPlay
|
SrsRtspMethodSetup
|
SrsRtspMethodTeardown
|
SrsRtspMethodAnnounce
|
SrsRtspMethodRecord
);
}
SrsRtspOptionsResponse
::~
SrsRtspOptionsResponse
()
{
}
stringstream
&
SrsRtspOptionsResponse
::
encode
(
stringstream
&
ss
)
{
SrsRtspResponse
::
encode
(
ss
);
SrsRtspMethod
__methods
[]
=
{
SrsRtspMethodDescribe
,
SrsRtspMethodAnnounce
,
SrsRtspMethodGetParameter
,
SrsRtspMethodOptions
,
SrsRtspMethodPause
,
SrsRtspMethodPlay
,
SrsRtspMethodRecord
,
SrsRtspMethodRedirect
,
SrsRtspMethodSetup
,
SrsRtspMethodSetParameter
,
SrsRtspMethodTeardown
,
};
ss
<<
__SRS_TOKEN_PUBLIC
<<
":"
<<
__SRS_RTSP_SP
;
bool
appended
=
false
;
int
nb_methods
=
(
int
)(
sizeof
(
__methods
)
/
sizeof
(
SrsRtspMethod
));
for
(
int
i
=
0
;
i
<
nb_methods
;
i
++
)
{
SrsRtspMethod
method
=
__methods
[
i
];
if
(((
int
)
methods
&
(
int
)
method
)
!=
(
int
)
method
)
{
continue
;
}
if
(
appended
)
{
ss
<<
", "
;
}
ss
<<
srs_generate_rtsp_method_str
(
method
);
appended
=
true
;
}
ss
<<
__SRS_RTSP_CRLF
;
// eof header.
ss
<<
__SRS_RTSP_CRLF
;
return
ss
;
}
SrsRtspStack
::
SrsRtspStack
(
ISrsProtocolReaderWriter
*
s
)
{
buf
=
new
SrsSimpleBuffer
();
skt
=
s
;
}
SrsRtspStack
::~
SrsRtspStack
()
{
srs_freep
(
buf
);
}
int
SrsRtspStack
::
recv_message
(
SrsRtspRequest
**
preq
)
{
int
ret
=
ERROR_SUCCESS
;
SrsRtspRequest
*
req
=
new
SrsRtspRequest
();
if
((
ret
=
do_recv_message
(
req
))
!=
ERROR_SUCCESS
)
{
srs_freep
(
req
);
return
ret
;
}
*
preq
=
req
;
return
ret
;
}
int
SrsRtspStack
::
send_message
(
SrsRtspResponse
*
res
)
{
int
ret
=
ERROR_SUCCESS
;
std
::
stringstream
ss
;
// encode the message to string.
res
->
encode
(
ss
);
std
::
string
str
=
ss
.
str
();
srs_assert
(
!
str
.
empty
());
if
((
ret
=
skt
->
write
((
char
*
)
str
.
c_str
(),
(
int
)
str
.
length
(),
NULL
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: send response failed. ret=%d"
,
ret
);
}
return
ret
;
}
srs_info
(
"rtsp: send response ok"
);
return
ret
;
}
int
SrsRtspStack
::
do_recv_message
(
SrsRtspRequest
*
req
)
{
int
ret
=
ERROR_SUCCESS
;
// parse request line.
if
((
ret
=
recv_token_normal
(
req
->
method
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: parse method failed. ret=%d"
,
ret
);
}
return
ret
;
}
if
((
ret
=
recv_token_normal
(
req
->
uri
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: parse uri failed. ret=%d"
,
ret
);
}
return
ret
;
}
if
((
ret
=
recv_token_eof
(
req
->
version
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: parse version failed. ret=%d"
,
ret
);
}
return
ret
;
}
// parse headers.
for
(;;)
{
// parse the header name
std
::
string
token
;
if
((
ret
=
recv_token_normal
(
token
))
!=
ERROR_SUCCESS
)
{
if
(
ret
==
ERROR_RTSP_REQUEST_HEADER_EOF
)
{
ret
=
ERROR_SUCCESS
;
srs_info
(
"rtsp: message header parsed"
);
break
;
}
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: parse token failed. ret=%d"
,
ret
);
}
return
ret
;
}
// parse the header value according by header name
if
(
token
==
__SRS_TOKEN_CSEQ
)
{
std
::
string
seq
;
if
((
ret
=
recv_token_eof
(
seq
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: parse seq failed. ret=%d"
,
ret
);
}
return
ret
;
}
req
->
seq
=
::
atoi
(
seq
.
c_str
());
}
else
{
// unknown header name, parse util EOF.
SrsRtspTokenState
state
=
SrsRtspTokenStateNormal
;
while
(
state
==
SrsRtspTokenStateNormal
)
{
std
::
string
value
;
if
((
ret
=
recv_token
(
value
,
state
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: parse token failed. ret=%d"
,
ret
);
}
return
ret
;
}
srs_trace
(
"rtsp: ignore header %s=%s"
,
token
.
c_str
(),
value
.
c_str
());
}
}
}
// parse body.
return
ret
;
}
int
SrsRtspStack
::
recv_token_normal
(
std
::
string
&
token
)
{
int
ret
=
ERROR_SUCCESS
;
SrsRtspTokenState
state
;
if
((
ret
=
recv_token
(
token
,
state
))
!=
ERROR_SUCCESS
)
{
if
(
ret
==
ERROR_RTSP_REQUEST_HEADER_EOF
)
{
return
ret
;
}
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: parse token failed. ret=%d"
,
ret
);
}
return
ret
;
}
if
(
state
!=
SrsRtspTokenStateNormal
)
{
ret
=
ERROR_RTSP_TOKEN_NOT_NORMAL
;
srs_error
(
"rtsp: parse normal token failed, state=%d. ret=%d"
,
state
,
ret
);
return
ret
;
}
return
ret
;
}
int
SrsRtspStack
::
recv_token_eof
(
std
::
string
&
token
)
{
int
ret
=
ERROR_SUCCESS
;
SrsRtspTokenState
state
;
if
((
ret
=
recv_token
(
token
,
state
))
!=
ERROR_SUCCESS
)
{
if
(
ret
==
ERROR_RTSP_REQUEST_HEADER_EOF
)
{
return
ret
;
}
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: parse token failed. ret=%d"
,
ret
);
}
return
ret
;
}
if
(
state
!=
SrsRtspTokenStateEOF
)
{
ret
=
ERROR_RTSP_TOKEN_NOT_NORMAL
;
srs_error
(
"rtsp: parse eof token failed, state=%d. ret=%d"
,
state
,
ret
);
return
ret
;
}
return
ret
;
}
int
SrsRtspStack
::
recv_token_util_eof
(
std
::
string
&
token
)
{
int
ret
=
ERROR_SUCCESS
;
SrsRtspTokenState
state
;
// use 0x00 as ignore the normal token flag.
if
((
ret
=
recv_token
(
token
,
state
,
0x00
))
!=
ERROR_SUCCESS
)
{
if
(
ret
==
ERROR_RTSP_REQUEST_HEADER_EOF
)
{
return
ret
;
}
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: parse token failed. ret=%d"
,
ret
);
}
return
ret
;
}
if
(
state
!=
SrsRtspTokenStateEOF
)
{
ret
=
ERROR_RTSP_TOKEN_NOT_NORMAL
;
srs_error
(
"rtsp: parse eof token failed, state=%d. ret=%d"
,
state
,
ret
);
return
ret
;
}
return
ret
;
}
int
SrsRtspStack
::
recv_token
(
std
::
string
&
token
,
SrsRtspTokenState
&
state
,
char
normal_ch
)
{
int
ret
=
ERROR_SUCCESS
;
// whatever, default to error state.
state
=
SrsRtspTokenStateError
;
// when buffer is empty, append bytes first.
bool
append_bytes
=
buf
->
length
()
==
0
;
// parse util token.
for
(;;)
{
// append bytes if required.
if
(
append_bytes
)
{
append_bytes
=
false
;
char
buffer
[
__SRS_RTSP_BUFFER
];
ssize_t
nb_read
=
0
;
if
((
ret
=
skt
->
read
(
buffer
,
__SRS_RTSP_BUFFER
,
&
nb_read
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"rtsp: io read failed. ret=%d"
,
ret
);
}
return
ret
;
}
srs_info
(
"rtsp: io read %d bytes"
,
nb_read
);
buf
->
append
(
buffer
,
nb_read
);
}
// parse one by one.
char
*
start
=
buf
->
bytes
();
char
*
end
=
start
+
buf
->
length
();
char
*
p
=
start
;
// find util SP/CR/LF, max 2 EOF, to finger out the EOF of message.
for
(;
p
<
end
&&
p
[
0
]
!=
normal_ch
&&
p
[
0
]
!=
__SRS_RTSP_CR
&&
p
[
0
]
!=
__SRS_RTSP_LF
;
p
++
)
{
}
// matched.
if
(
p
<
end
)
{
// finger out the state.
if
(
p
[
0
]
==
normal_ch
)
{
state
=
SrsRtspTokenStateNormal
;
}
else
{
state
=
SrsRtspTokenStateEOF
;
}
// got the token.
int
nb_token
=
p
-
start
;
// trim last ':' character.
if
(
nb_token
&&
p
[
-
1
]
==
':'
)
{
nb_token
--
;
}
if
(
nb_token
)
{
token
.
append
(
start
,
nb_token
);
}
else
{
ret
=
ERROR_RTSP_REQUEST_HEADER_EOF
;
}
// ignore SP/CR/LF
for
(
int
i
=
0
;
i
<
2
&&
p
<
end
&&
(
p
[
0
]
==
normal_ch
||
p
[
0
]
==
__SRS_RTSP_CR
||
p
[
0
]
==
__SRS_RTSP_LF
);
p
++
,
i
++
)
{
}
// consume the token bytes.
srs_assert
(
p
-
start
);
buf
->
erase
(
p
-
start
);
break
;
}
// append more and parse again.
append_bytes
=
true
;
}
return
ret
;
}
#endif
...
...
trunk/src/protocol/srs_rtsp_stack.hpp
查看文件 @
604f4cc
...
...
@@ -30,10 +30,213 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core.hpp>
#include <string>
#include <sstream>
#include <srs_kernel_consts.hpp>
#ifdef SRS_AUTO_STREAM_CASTER
class
SrsSimpleBuffer
;
class
ISrsProtocolReaderWriter
;
// rtsp specification
// CR = <US-ASCII CR, carriage return (13)>
#define __SRS_RTSP_CR SRS_CONSTS_CR // 0x0D
// LF = <US-ASCII LF, linefeed (10)>
#define __SRS_RTSP_LF SRS_CONSTS_LF // 0x0A
// SP = <US-ASCII SP, space (32)>
#define __SRS_RTSP_SP ' ' // 0x20
// 4 RTSP Message
// Lines are terminated by CRLF, but
// receivers should be prepared to also interpret CR and LF by
// themselves as line terminators.
#define __SRS_RTSP_CRLF "\r\n" // 0x0D0A
#define __SRS_RTSP_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A
// RTSP token
#define __SRS_TOKEN_CSEQ "CSeq"
#define __SRS_TOKEN_PUBLIC "Public"
// RTSP methods
#define __SRS_METHOD_OPTIONS "OPTIONS"
#define __SRS_METHOD_DESCRIBE "DESCRIBE"
#define __SRS_METHOD_ANNOUNCE "ANNOUNCE"
#define __SRS_METHOD_SETUP "SETUP"
#define __SRS_METHOD_PLAY "PLAY"
#define __SRS_METHOD_PAUSE "PAUSE"
#define __SRS_METHOD_TEARDOWN "TEARDOWN"
#define __SRS_METHOD_GET_PARAMETER "GET_PARAMETER"
#define __SRS_METHOD_SET_PARAMETER "SET_PARAMETER"
#define __SRS_METHOD_REDIRECT "REDIRECT"
#define __SRS_METHOD_RECORD "RECORD"
// Embedded (Interleaved) Binary Data
// RTSP-Version
#define __SRS_VERSION "RTSP/1.0"
/**
* the rtsp request message.
* 6 Request
* A request message from a client to a server or vice versa includes,
* within the first line of that message, the method to be applied to
* the resource, the identifier of the resource, and the protocol
* version in use.
* Request = Request-Line ; Section 6.1
* *( general-header ; Section 5
* | request-header ; Section 6.2
* | entity-header ) ; Section 8.1
* CRLF
* [ message-body ] ; Section 4.3
*/
class
SrsRtspRequest
{
public
:
/**
* 6.1 Request Line
* Request-Line = Method SP Request-URI SP RTSP-Version CRLF
*/
std
::
string
method
;
std
::
string
uri
;
std
::
string
version
;
/**
* 12.17 CSeq
* The CSeq field specifies the sequence number for an RTSP requestresponse
* pair. This field MUST be present in all requests and
* responses. For every RTSP request containing the given sequence
* number, there will be a corresponding response having the same
* number. Any retransmitted request must contain the same sequence
* number as the original (i.e. the sequence number is not incremented
* for retransmissions of the same request).
*/
int
seq
;
public
:
SrsRtspRequest
();
virtual
~
SrsRtspRequest
();
public
:
virtual
bool
is_options
();
};
/**
* the rtsp response message.
* 7 Response
* [H6] applies except that HTTP-Version is replaced by RTSP-Version.
* Also, RTSP defines additional status codes and does not define some
* HTTP codes. The valid response codes and the methods they can be used
* with are defined in Table 1.
* After receiving and interpreting a request message, the recipient
* responds with an RTSP response message.
* Response = Status-Line ; Section 7.1
* *( general-header ; Section 5
* | response-header ; Section 7.1.2
* | entity-header ) ; Section 8.1
* CRLF
* [ message-body ] ; Section 4.3
*/
class
SrsRtspResponse
{
public
:
/**
* 7.1 Status-Line
* The first line of a Response message is the Status-Line, consisting
* of the protocol version followed by a numeric status code, and the
* textual phrase associated with the status code, with each element
* separated by SP characters. No CR or LF is allowed except in the
* final CRLF sequence.
* Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
*/
// @see about the version of rtsp, see __SRS_VERSION
// @see about the status of rtsp, see SRS_CONSTS_RTSP_OK
int
status
;
/**
* 12.17 CSeq
* The CSeq field specifies the sequence number for an RTSP requestresponse
* pair. This field MUST be present in all requests and
* responses. For every RTSP request containing the given sequence
* number, there will be a corresponding response having the same
* number. Any retransmitted request must contain the same sequence
* number as the original (i.e. the sequence number is not incremented
* for retransmissions of the same request).
*/
int
seq
;
public
:
SrsRtspResponse
(
int
cseq
);
virtual
~
SrsRtspResponse
();
public
:
/**
* encode message to string.
*/
virtual
std
::
stringstream
&
encode
(
std
::
stringstream
&
ss
);
};
/**
* 10 Method Definitions
* The method token indicates the method to be performed on the resource
* identified by the Request-URI. The method is case-sensitive. New
* methods may be defined in the future. Method names may not start with
* a $ character (decimal 24) and must be a token. Methods are
* summarized in Table 2.
* Notes on Table 2: PAUSE is recommended, but not required in that a
* fully functional server can be built that does not support this
* method, for example, for live feeds. If a server does not support a
* particular method, it MUST return "501 Not Implemented" and a client
* SHOULD not try this method again for this server.
*/
enum
SrsRtspMethod
{
SrsRtspMethodDescribe
=
0x0001
,
SrsRtspMethodAnnounce
=
0x0002
,
SrsRtspMethodGetParameter
=
0x0004
,
SrsRtspMethodOptions
=
0x0008
,
SrsRtspMethodPause
=
0x0010
,
SrsRtspMethodPlay
=
0x0020
,
SrsRtspMethodRecord
=
0x0040
,
SrsRtspMethodRedirect
=
0x0080
,
SrsRtspMethodSetup
=
0x0100
,
SrsRtspMethodSetParameter
=
0x0200
,
SrsRtspMethodTeardown
=
0x0400
,
};
/**
* 10.1 OPTIONS
* The behavior is equivalent to that described in [H9.2]. An OPTIONS
* request may be issued at any time, e.g., if the client is about to
* try a nonstandard request. It does not influence server state.
*/
class
SrsRtspOptionsResponse
:
public
SrsRtspResponse
{
public
:
/**
* join of SrsRtspMethod
*/
SrsRtspMethod
methods
;
public
:
SrsRtspOptionsResponse
(
int
cseq
);
virtual
~
SrsRtspOptionsResponse
();
public
:
virtual
std
::
stringstream
&
encode
(
std
::
stringstream
&
ss
);
};
/**
* the state of rtsp token.
*/
enum
SrsRtspTokenState
{
/**
* parse token failed, default state.
*/
SrsRtspTokenStateError
=
100
,
/**
* when SP follow the token.
*/
SrsRtspTokenStateNormal
=
101
,
/**
* when CRLF follow the token.
*/
SrsRtspTokenStateEOF
=
102
,
};
/**
* the rtsp protocol stack to parse the rtsp packets.
*/
...
...
@@ -41,12 +244,57 @@ class SrsRtspStack
{
private
:
/**
* cached bytes buffer.
*/
SrsSimpleBuffer
*
buf
;
/**
* underlayer socket object, send/recv bytes.
*/
ISrsProtocolReaderWriter
*
skt
;
public
:
SrsRtspStack
(
ISrsProtocolReaderWriter
*
s
);
virtual
~
SrsRtspStack
();
public
:
/**
* recv rtsp message from underlayer io.
* @param preq the output rtsp request message, which user must free it.
* @return an int error code.
* ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
*/
virtual
int
recv_message
(
SrsRtspRequest
**
preq
);
/**
* send rtsp message over underlayer io.
* @param res the rtsp response message, which user should never free it.
* @return an int error code.
*/
virtual
int
send_message
(
SrsRtspResponse
*
res
);
private
:
/**
* recv the rtsp message.
*/
virtual
int
do_recv_message
(
SrsRtspRequest
*
req
);
/**
* read a normal token from io, error when token state is not normal.
*/
virtual
int
recv_token_normal
(
std
::
string
&
token
);
/**
* read a normal token from io, error when token state is not eof.
*/
virtual
int
recv_token_eof
(
std
::
string
&
token
);
/**
* read the token util got eof, for example, to read the response status Reason-Phrase
*/
virtual
int
recv_token_util_eof
(
std
::
string
&
token
);
/**
* read a token from io, split by SP, endswith CRLF:
* token1 SP token2 SP ... tokenN CRLF
* @param normal_ch, the char to indicates the normal token.
* the SP use to indicates the normal token, @see __SRS_RTSP_SP
* the 0x00 use to ignore normal token flag. @see recv_token_util_eof
* @param token, output the read token.
* @param state, output the token parse state.
*/
virtual
int
recv_token
(
std
::
string
&
token
,
SrsRtspTokenState
&
state
,
char
normal_ch
=
__SRS_RTSP_SP
);
};
#endif
...
...
请
注册
或
登录
后发表评论