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-01-17 21:58:23 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
9bbbaad2880135f9a97fbea56b8b63555005a7e0
9bbbaad2
1 parent
33efeeb3
for bug #277, refine http api refer to go http-framework. 2.0.97
隐藏空白字符变更
内嵌
并排对比
正在显示
10 个修改的文件
包含
1004 行增加
和
395 行删除
README.md
trunk/src/app/srs_app_http.cpp
trunk/src/app/srs_app_http.hpp
trunk/src/app/srs_app_http_api.cpp
trunk/src/app/srs_app_http_api.hpp
trunk/src/app/srs_app_http_conn.cpp
trunk/src/app/srs_app_server.cpp
trunk/src/app/srs_app_server.hpp
trunk/src/core/srs_core.hpp
trunk/src/kernel/srs_kernel_error.hpp
README.md
查看文件 @
9bbbaad
...
...
@@ -510,6 +510,7 @@ Supported operating systems and hardware:
## History
*
v2.0, 2015-01-17, for
[
#277
](
https://github.com/winlinvip/simple-rtmp-server/issues/277
)
, refine http api refer to go http-framework. 2.0.97
*
v2.0, 2015-01-17, hotfix
[
#290
](
https://github.com/winlinvip/simple-rtmp-server/issues/290
)
, use iformat only for rtmp input. 2.0.95
*
v2.0, 2015-01-08, hotfix
[
#281
](
https://github.com/winlinvip/simple-rtmp-server/issues/281
)
, fix hls bug ignore type-9 send aud. 2.0.93
*
v2.0, 2015-01-03, fix
[
#274
](
https://github.com/winlinvip/simple-rtmp-server/issues/274
)
, http-callback support on_dvr when reap a dvr file. 2.0.89
...
...
trunk/src/app/srs_app_http.cpp
查看文件 @
9bbbaad
...
...
@@ -68,6 +68,503 @@ bool srs_path_like(const char* expect, const char* path, int nb_path)
return
equals
;
}
int
srs_go_http_response_json
(
ISrsGoHttpResponseWriter
*
w
,
string
data
)
{
w
->
header
()
->
set_content_length
(
data
.
length
());
w
->
header
()
->
set_content_type
(
"application/json;charset=utf-8"
);
return
w
->
write
((
char
*
)
data
.
data
(),
data
.
length
());
}
// get the status text of code.
string
srs_generate_status_text
(
int
status
)
{
static
std
::
map
<
int
,
std
::
string
>
_status_map
;
if
(
_status_map
.
empty
())
{
_status_map
[
SRS_CONSTS_HTTP_Continue
]
=
SRS_CONSTS_HTTP_Continue_str
;
_status_map
[
SRS_CONSTS_HTTP_SwitchingProtocols
]
=
SRS_CONSTS_HTTP_SwitchingProtocols_str
;
_status_map
[
SRS_CONSTS_HTTP_OK
]
=
SRS_CONSTS_HTTP_OK_str
;
_status_map
[
SRS_CONSTS_HTTP_Created
]
=
SRS_CONSTS_HTTP_Created_str
;
_status_map
[
SRS_CONSTS_HTTP_Accepted
]
=
SRS_CONSTS_HTTP_Accepted_str
;
_status_map
[
SRS_CONSTS_HTTP_NonAuthoritativeInformation
]
=
SRS_CONSTS_HTTP_NonAuthoritativeInformation_str
;
_status_map
[
SRS_CONSTS_HTTP_NoContent
]
=
SRS_CONSTS_HTTP_NoContent_str
;
_status_map
[
SRS_CONSTS_HTTP_ResetContent
]
=
SRS_CONSTS_HTTP_ResetContent_str
;
_status_map
[
SRS_CONSTS_HTTP_PartialContent
]
=
SRS_CONSTS_HTTP_PartialContent_str
;
_status_map
[
SRS_CONSTS_HTTP_MultipleChoices
]
=
SRS_CONSTS_HTTP_MultipleChoices_str
;
_status_map
[
SRS_CONSTS_HTTP_MovedPermanently
]
=
SRS_CONSTS_HTTP_MovedPermanently_str
;
_status_map
[
SRS_CONSTS_HTTP_Found
]
=
SRS_CONSTS_HTTP_Found_str
;
_status_map
[
SRS_CONSTS_HTTP_SeeOther
]
=
SRS_CONSTS_HTTP_SeeOther_str
;
_status_map
[
SRS_CONSTS_HTTP_NotModified
]
=
SRS_CONSTS_HTTP_NotModified_str
;
_status_map
[
SRS_CONSTS_HTTP_UseProxy
]
=
SRS_CONSTS_HTTP_UseProxy_str
;
_status_map
[
SRS_CONSTS_HTTP_TemporaryRedirect
]
=
SRS_CONSTS_HTTP_TemporaryRedirect_str
;
_status_map
[
SRS_CONSTS_HTTP_BadRequest
]
=
SRS_CONSTS_HTTP_BadRequest_str
;
_status_map
[
SRS_CONSTS_HTTP_Unauthorized
]
=
SRS_CONSTS_HTTP_Unauthorized_str
;
_status_map
[
SRS_CONSTS_HTTP_PaymentRequired
]
=
SRS_CONSTS_HTTP_PaymentRequired_str
;
_status_map
[
SRS_CONSTS_HTTP_Forbidden
]
=
SRS_CONSTS_HTTP_Forbidden_str
;
_status_map
[
SRS_CONSTS_HTTP_NotFound
]
=
SRS_CONSTS_HTTP_NotFound_str
;
_status_map
[
SRS_CONSTS_HTTP_MethodNotAllowed
]
=
SRS_CONSTS_HTTP_MethodNotAllowed_str
;
_status_map
[
SRS_CONSTS_HTTP_NotAcceptable
]
=
SRS_CONSTS_HTTP_NotAcceptable_str
;
_status_map
[
SRS_CONSTS_HTTP_ProxyAuthenticationRequired
]
=
SRS_CONSTS_HTTP_ProxyAuthenticationRequired_str
;
_status_map
[
SRS_CONSTS_HTTP_RequestTimeout
]
=
SRS_CONSTS_HTTP_RequestTimeout_str
;
_status_map
[
SRS_CONSTS_HTTP_Conflict
]
=
SRS_CONSTS_HTTP_Conflict_str
;
_status_map
[
SRS_CONSTS_HTTP_Gone
]
=
SRS_CONSTS_HTTP_Gone_str
;
_status_map
[
SRS_CONSTS_HTTP_LengthRequired
]
=
SRS_CONSTS_HTTP_LengthRequired_str
;
_status_map
[
SRS_CONSTS_HTTP_PreconditionFailed
]
=
SRS_CONSTS_HTTP_PreconditionFailed_str
;
_status_map
[
SRS_CONSTS_HTTP_RequestEntityTooLarge
]
=
SRS_CONSTS_HTTP_RequestEntityTooLarge_str
;
_status_map
[
SRS_CONSTS_HTTP_RequestURITooLarge
]
=
SRS_CONSTS_HTTP_RequestURITooLarge_str
;
_status_map
[
SRS_CONSTS_HTTP_UnsupportedMediaType
]
=
SRS_CONSTS_HTTP_UnsupportedMediaType_str
;
_status_map
[
SRS_CONSTS_HTTP_RequestedRangeNotSatisfiable
]
=
SRS_CONSTS_HTTP_RequestedRangeNotSatisfiable_str
;
_status_map
[
SRS_CONSTS_HTTP_ExpectationFailed
]
=
SRS_CONSTS_HTTP_ExpectationFailed_str
;
_status_map
[
SRS_CONSTS_HTTP_InternalServerError
]
=
SRS_CONSTS_HTTP_InternalServerError_str
;
_status_map
[
SRS_CONSTS_HTTP_NotImplemented
]
=
SRS_CONSTS_HTTP_NotImplemented_str
;
_status_map
[
SRS_CONSTS_HTTP_BadGateway
]
=
SRS_CONSTS_HTTP_BadGateway_str
;
_status_map
[
SRS_CONSTS_HTTP_ServiceUnavailable
]
=
SRS_CONSTS_HTTP_ServiceUnavailable_str
;
_status_map
[
SRS_CONSTS_HTTP_GatewayTimeout
]
=
SRS_CONSTS_HTTP_GatewayTimeout_str
;
_status_map
[
SRS_CONSTS_HTTP_HTTPVersionNotSupported
]
=
SRS_CONSTS_HTTP_HTTPVersionNotSupported_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
;
}
// bodyAllowedForStatus reports whether a given response status code
// permits a body. See RFC2616, section 4.4.
bool
srs_go_http_body_allowd
(
int
status
)
{
if
(
status
>=
100
&&
status
<=
199
)
{
return
false
;
}
else
if
(
status
==
204
||
status
==
304
)
{
return
false
;
}
return
true
;
}
// DetectContentType implements the algorithm described
// at http://mimesniff.spec.whatwg.org/ to determine the
// Content-Type of the given data. It considers at most the
// first 512 bytes of data. DetectContentType always returns
// a valid MIME type: if it cannot determine a more specific one, it
// returns "application/octet-stream".
string
srs_go_http_detect
(
char
*
data
,
int
size
)
{
return
"application/octet-stream"
;
// fallback
}
// Error replies to the request with the specified error message and HTTP code.
// The error message should be plain text.
int
srs_go_http_error
(
ISrsGoHttpResponseWriter
*
w
,
int
code
,
string
error
)
{
int
ret
=
ERROR_SUCCESS
;
w
->
header
()
->
set_content_type
(
"text/plain; charset=utf-8"
);
w
->
header
()
->
set_content_length
(
error
.
length
());
w
->
write_header
(
code
);
w
->
write
((
char
*
)
error
.
data
(),
(
int
)
error
.
length
());
return
ret
;
}
SrsGoHttpHeader
::
SrsGoHttpHeader
()
{
}
SrsGoHttpHeader
::~
SrsGoHttpHeader
()
{
}
void
SrsGoHttpHeader
::
set
(
string
key
,
string
value
)
{
headers
[
key
]
=
value
;
}
string
SrsGoHttpHeader
::
get
(
string
key
)
{
std
::
string
v
;
if
(
headers
.
find
(
key
)
!=
headers
.
end
())
{
v
=
headers
[
key
];
}
return
v
;
}
int64_t
SrsGoHttpHeader
::
content_length
()
{
std
::
string
cl
=
get
(
"Content-Length"
);
if
(
cl
.
empty
())
{
return
-
1
;
}
return
(
int64_t
)
::
atof
(
cl
.
c_str
());
}
void
SrsGoHttpHeader
::
set_content_length
(
int64_t
size
)
{
char
buf
[
64
];
snprintf
(
buf
,
sizeof
(
buf
),
"%"
PRId64
,
size
);
set
(
"Content-Length"
,
buf
);
}
string
SrsGoHttpHeader
::
content_type
()
{
return
get
(
"Content-Type"
);
}
void
SrsGoHttpHeader
::
set_content_type
(
string
ct
)
{
set
(
"Content-Type"
,
ct
);
}
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
;
}
}
ISrsGoHttpResponseWriter
::
ISrsGoHttpResponseWriter
()
{
}
ISrsGoHttpResponseWriter
::~
ISrsGoHttpResponseWriter
()
{
}
ISrsGoHttpHandler
::
ISrsGoHttpHandler
()
{
}
ISrsGoHttpHandler
::~
ISrsGoHttpHandler
()
{
}
SrsGoHttpRedirectHandler
::
SrsGoHttpRedirectHandler
(
string
u
,
int
c
)
{
url
=
u
;
code
=
c
;
}
SrsGoHttpRedirectHandler
::~
SrsGoHttpRedirectHandler
()
{
}
int
SrsGoHttpRedirectHandler
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
int
ret
=
ERROR_SUCCESS
;
// TODO: FIXME: implements it.
return
ret
;
}
SrsGoHttpNotFoundHandler
::
SrsGoHttpNotFoundHandler
()
{
}
SrsGoHttpNotFoundHandler
::~
SrsGoHttpNotFoundHandler
()
{
}
int
SrsGoHttpNotFoundHandler
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
return
srs_go_http_error
(
w
,
SRS_CONSTS_HTTP_NotFound
,
SRS_CONSTS_HTTP_NotFound_str
);
}
SrsGoHttpMuxEntry
::
SrsGoHttpMuxEntry
()
{
explicit_match
=
false
;
handler
=
NULL
;
}
SrsGoHttpMuxEntry
::~
SrsGoHttpMuxEntry
()
{
srs_freep
(
handler
);
}
SrsGoHttpServeMux
::
SrsGoHttpServeMux
()
{
}
SrsGoHttpServeMux
::~
SrsGoHttpServeMux
()
{
std
::
map
<
std
::
string
,
SrsGoHttpMuxEntry
*>::
iterator
it
;
for
(
it
=
entries
.
begin
();
it
!=
entries
.
end
();
++
it
)
{
SrsGoHttpMuxEntry
*
entry
=
it
->
second
;
srs_freep
(
entry
);
}
entries
.
clear
();
}
int
SrsGoHttpServeMux
::
initialize
()
{
int
ret
=
ERROR_SUCCESS
;
// TODO: FIXME: implements it.
return
ret
;
}
int
SrsGoHttpServeMux
::
handle
(
std
::
string
pattern
,
ISrsGoHttpHandler
*
handler
)
{
int
ret
=
ERROR_SUCCESS
;
srs_assert
(
handler
);
if
(
pattern
.
empty
())
{
ret
=
ERROR_HTTP_PATTERN_EMPTY
;
srs_error
(
"http: empty pattern. ret=%d"
,
ret
);
return
ret
;
}
if
(
entries
.
find
(
pattern
)
!=
entries
.
end
())
{
SrsGoHttpMuxEntry
*
exists
=
entries
[
pattern
];
if
(
exists
->
explicit_match
)
{
ret
=
ERROR_HTTP_PATTERN_DUPLICATED
;
srs_error
(
"http: multiple registrations for %s. ret=%d"
,
pattern
.
c_str
(),
ret
);
return
ret
;
}
}
if
(
true
)
{
SrsGoHttpMuxEntry
*
entry
=
new
SrsGoHttpMuxEntry
();
entry
->
explicit_match
=
true
;
entry
->
handler
=
handler
;
entry
->
pattern
=
pattern
;
if
(
entries
.
find
(
pattern
)
!=
entries
.
end
())
{
SrsGoHttpMuxEntry
*
exists
=
entries
[
pattern
];
srs_freep
(
exists
);
}
entries
[
pattern
]
=
entry
;
}
// Helpful behavior:
// If pattern is /tree/, insert an implicit permanent redirect for /tree.
// It can be overridden by an explicit registration.
if
(
!
pattern
.
empty
()
&&
pattern
.
at
(
pattern
.
length
()
-
1
)
==
'/'
)
{
std
::
string
rpattern
=
pattern
.
substr
(
0
,
pattern
.
length
()
-
1
);
SrsGoHttpMuxEntry
*
entry
=
NULL
;
// free the exists not explicit entry
if
(
entries
.
find
(
rpattern
)
!=
entries
.
end
())
{
SrsGoHttpMuxEntry
*
exists
=
entries
[
rpattern
];
if
(
!
exists
->
explicit_match
)
{
entry
=
exists
;
}
}
// create implicit redirect.
if
(
!
entry
||
entry
->
explicit_match
)
{
srs_freep
(
entry
);
entry
=
new
SrsGoHttpMuxEntry
();
entry
->
explicit_match
=
false
;
entry
->
handler
=
new
SrsGoHttpRedirectHandler
(
pattern
,
SRS_CONSTS_HTTP_MovedPermanently
);
entry
->
pattern
=
pattern
;
entries
[
rpattern
]
=
entry
;
}
}
return
ret
;
}
int
SrsGoHttpServeMux
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
int
ret
=
ERROR_SUCCESS
;
ISrsGoHttpHandler
*
h
=
NULL
;
if
((
ret
=
find_handler
(
r
,
&
h
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"find handler failed. ret=%d"
,
ret
);
return
ret
;
}
srs_assert
(
h
);
if
((
ret
=
h
->
serve_http
(
w
,
r
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"handler serve http failed. ret=%d"
,
ret
);
return
ret
;
}
return
ret
;
}
int
SrsGoHttpServeMux
::
find_handler
(
SrsHttpMessage
*
r
,
ISrsGoHttpHandler
**
ph
)
{
int
ret
=
ERROR_SUCCESS
;
// TODO: FIXME: support the path . and ..
if
(
r
->
url
().
find
(
".."
)
!=
std
::
string
::
npos
)
{
ret
=
ERROR_HTTP_URL_NOT_CLEAN
;
srs_error
(
"htt url not canonical, url=%s. ret=%d"
,
r
->
url
().
c_str
(),
ret
);
return
ret
;
}
if
((
ret
=
match
(
r
,
ph
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"http match handler failed. ret=%d"
,
ret
);
return
ret
;
}
if
(
*
ph
==
NULL
)
{
*
ph
=
new
SrsGoHttpNotFoundHandler
();
}
return
ret
;
}
int
SrsGoHttpServeMux
::
match
(
SrsHttpMessage
*
r
,
ISrsGoHttpHandler
**
ph
)
{
int
ret
=
ERROR_SUCCESS
;
std
::
string
path
=
r
->
path
();
int
nb_matched
=
0
;
ISrsGoHttpHandler
*
h
=
NULL
;
std
::
map
<
std
::
string
,
SrsGoHttpMuxEntry
*>::
iterator
it
;
for
(
it
=
entries
.
begin
();
it
!=
entries
.
end
();
++
it
)
{
std
::
string
pattern
=
it
->
first
;
SrsGoHttpMuxEntry
*
entry
=
it
->
second
;
if
(
!
path_match
(
pattern
,
path
))
{
continue
;
}
if
(
!
h
||
(
int
)
pattern
.
length
()
>
nb_matched
)
{
nb_matched
=
(
int
)
pattern
.
length
();
h
=
entry
->
handler
;
}
}
*
ph
=
h
;
return
ret
;
}
bool
SrsGoHttpServeMux
::
path_match
(
string
pattern
,
string
path
)
{
if
(
pattern
.
empty
())
{
return
false
;
}
int
n
=
pattern
.
length
();
// not endswith '/', exactly match.
if
(
pattern
.
at
(
n
-
1
)
!=
'/'
)
{
return
pattern
==
path
;
}
// endswith '/', match any,
// for example, '/api/' match '/api/[N]'
if
((
int
)
path
.
length
()
>=
n
)
{
if
(
memcmp
(
pattern
.
data
(),
path
.
data
(),
n
)
==
0
)
{
return
true
;
}
}
return
false
;
}
SrsGoHttpResponseWriter
::
SrsGoHttpResponseWriter
(
SrsStSocket
*
io
)
{
skt
=
io
;
hdr
=
new
SrsGoHttpHeader
();
header_wrote
=
false
;
status
=
SRS_CONSTS_HTTP_OK
;
content_length
=
-
1
;
written
=
0
;
header_sent
=
false
;
}
SrsGoHttpResponseWriter
::~
SrsGoHttpResponseWriter
()
{
srs_freep
(
hdr
);
}
SrsGoHttpHeader
*
SrsGoHttpResponseWriter
::
header
()
{
return
hdr
;
}
int
SrsGoHttpResponseWriter
::
write
(
char
*
data
,
int
size
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
!
header_wrote
)
{
write_header
(
SRS_CONSTS_HTTP_OK
);
}
written
+=
size
;
if
(
content_length
!=
-
1
&&
written
>
content_length
)
{
ret
=
ERROR_HTTP_CONTENT_LENGTH
;
srs_error
(
"http: exceed content length. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
send_header
(
data
,
size
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"http: send header failed. ret=%d"
,
ret
);
return
ret
;
}
return
skt
->
write
((
void
*
)
data
,
size
,
NULL
);
}
void
SrsGoHttpResponseWriter
::
write_header
(
int
code
)
{
if
(
header_wrote
)
{
srs_warn
(
"http: multiple write_header calls, code=%d"
,
code
);
return
;
}
header_wrote
=
true
;
status
=
code
;
// parse the content length from header.
content_length
=
hdr
->
content_length
();
}
int
SrsGoHttpResponseWriter
::
send_header
(
char
*
data
,
int
size
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
header_sent
)
{
return
ret
;
}
header_sent
=
true
;
std
::
stringstream
ss
;
// status_line
ss
<<
"HTTP/1.1 "
<<
status
<<
" "
<<
srs_generate_status_text
(
status
)
<<
__SRS_CRLF
;
// detect content type
if
(
srs_go_http_body_allowd
(
status
))
{
if
(
hdr
->
content_type
().
empty
())
{
hdr
->
set_content_type
(
srs_go_http_detect
(
data
,
size
));
}
}
// set server if not set.
if
(
hdr
->
get
(
"Server"
).
empty
())
{
hdr
->
set
(
"Server"
,
RTMP_SIG_SRS_KEY
"/"
RTMP_SIG_SRS_VERSION
);
}
// write headers
hdr
->
write
(
ss
);
// header_eof
ss
<<
__SRS_CRLF
;
std
::
string
buf
=
ss
.
str
();
return
skt
->
write
((
void
*
)
buf
.
c_str
(),
buf
.
length
(),
NULL
);
}
SrsHttpHandlerMatch
::
SrsHttpHandlerMatch
()
{
handler
=
NULL
;
...
...
@@ -521,13 +1018,6 @@ int SrsHttpHandler::res_error(SrsStSocket* skt, SrsHttpMessage* req, int code, s
return
res_flush
(
skt
,
ss
);
}
#ifdef SRS_AUTO_HTTP_API
SrsHttpHandler
*
SrsHttpHandler
::
create_http_api
()
{
return
new
SrsApiRoot
();
}
#endif
#ifdef SRS_AUTO_HTTP_SERVER
SrsHttpHandler
*
SrsHttpHandler
::
create_http_stream
()
{
...
...
@@ -553,6 +1043,41 @@ SrsHttpMessage::~SrsHttpMessage()
srs_freep
(
_http_ts_send_buffer
);
}
int
SrsHttpMessage
::
initialize
()
{
int
ret
=
ERROR_SUCCESS
;
// parse uri to schema/server:port/path?query
if
((
ret
=
_uri
->
initialize
(
_url
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// must format as key=value&...&keyN=valueN
std
::
string
q
=
_uri
->
get_query
();
size_t
pos
=
string
::
npos
;
while
(
!
q
.
empty
())
{
std
::
string
k
=
q
;
if
((
pos
=
q
.
find
(
"="
))
!=
string
::
npos
)
{
k
=
q
.
substr
(
0
,
pos
);
q
=
q
.
substr
(
pos
+
1
);
}
else
{
q
=
""
;
}
std
::
string
v
=
q
;
if
((
pos
=
q
.
find
(
"&"
))
!=
string
::
npos
)
{
v
=
q
.
substr
(
0
,
pos
);
q
=
q
.
substr
(
pos
+
1
);
}
else
{
q
=
""
;
}
_query
[
k
]
=
v
;
}
return
ret
;
}
char
*
SrsHttpMessage
::
http_ts_send_buffer
()
{
return
_http_ts_send_buffer
;
...
...
@@ -565,24 +1090,6 @@ void SrsHttpMessage::reset()
_url
=
""
;
}
int
SrsHttpMessage
::
parse_uri
()
{
// filter url according to HTTP specification.
// remove the duplicated slash.
std
::
string
filtered_url
=
srs_string_replace
(
_url
,
"//"
,
"/"
);
// remove the last / to match resource.
filtered_url
=
srs_string_trim_end
(
filtered_url
,
"/"
);
// if empty, use root.
if
(
filtered_url
.
empty
())
{
filtered_url
=
"/"
;
}
return
_uri
->
initialize
(
filtered_url
);
}
bool
SrsHttpMessage
::
is_complete
()
{
return
_state
==
SrsHttpParseStateComplete
;
...
...
@@ -671,11 +1178,6 @@ string SrsHttpMessage::path()
return
_uri
->
get_path
();
}
string
SrsHttpMessage
::
query
()
{
return
_uri
->
get_query
();
}
string
SrsHttpMessage
::
body
()
{
std
::
string
b
;
...
...
@@ -745,21 +1247,10 @@ void SrsHttpMessage::append_body(const char* body, int length)
string
SrsHttpMessage
::
query_get
(
string
key
)
{
std
::
string
q
=
query
();
size_t
pos
=
std
::
string
::
npos
;
std
::
string
v
;
// must format as key=value&...&keyN=valueN
if
((
pos
=
key
.
find
(
"="
))
!=
key
.
length
()
-
1
)
{
key
=
key
+
"="
;
}
if
((
pos
=
q
.
find
(
key
))
==
std
::
string
::
npos
)
{
return
""
;
}
std
::
string
v
=
q
.
substr
(
pos
+
key
.
length
());
if
((
pos
=
v
.
find
(
"&"
))
!=
std
::
string
::
npos
)
{
v
=
v
.
substr
(
0
,
pos
);
if
(
_query
.
find
(
key
)
!=
_query
.
end
())
{
v
=
_query
[
key
];
}
return
v
;
...
...
@@ -859,6 +1350,13 @@ int SrsHttpParser::parse_message(SrsStSocket* skt, SrsHttpMessage** ppmsg)
srs_freep
(
msg
);
return
ret
;
}
// initalize http msg, parse url.
if
((
ret
=
msg
->
initialize
())
!=
ERROR_SUCCESS
)
{
srs_error
(
"initialize http msg failed. ret=%d"
,
ret
);
srs_freep
(
msg
);
return
ret
;
}
// parse ok, return the msg.
*
ppmsg
=
msg
;
...
...
trunk/src/app/srs_app_http.hpp
查看文件 @
9bbbaad
...
...
@@ -31,6 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef SRS_AUTO_HTTP_PARSER
#include <map>
#include <string>
#include <vector>
#include <sstream>
...
...
@@ -45,6 +46,7 @@ class SrsStSocket;
class
SrsHttpUri
;
class
SrsHttpMessage
;
class
SrsHttpHandler
;
class
ISrsGoHttpResponseWriter
;
// http specification
// CR = <US-ASCII CR, carriage return (13)>
...
...
@@ -65,6 +67,9 @@ class SrsHttpHandler;
// @see SrsHttpMessage._http_ts_send_buffer
#define __SRS_HTTP_TS_SEND_BUFFER_SIZE 4096
// helper function: response in json format.
extern
int
srs_go_http_response_json
(
ISrsGoHttpResponseWriter
*
w
,
std
::
string
data
);
// compare the path.
// full compare, extractly match.
// used for api match.
...
...
@@ -81,6 +86,214 @@ enum SrsHttpParseState {
SrsHttpParseStateComplete
};
// A Header represents the key-value pairs in an HTTP header.
class
SrsGoHttpHeader
{
private
:
std
::
map
<
std
::
string
,
std
::
string
>
headers
;
public
:
SrsGoHttpHeader
();
virtual
~
SrsGoHttpHeader
();
public
:
// Add adds the key, value pair to the header.
// It appends to any existing values associated with key.
virtual
void
set
(
std
::
string
key
,
std
::
string
value
);
// Get gets the first value associated with the given key.
// If there are no values associated with the key, Get returns "".
// To access multiple values of a key, access the map directly
// with CanonicalHeaderKey.
virtual
std
::
string
get
(
std
::
string
key
);
public
:
/**
* get the content length. -1 if not set.
*/
virtual
int64_t
content_length
();
/**
* set the content length by header "Content-Length"
*/
virtual
void
set_content_length
(
int64_t
size
);
public
:
/**
* get the content type. empty string if not set.
*/
virtual
std
::
string
content_type
();
/**
* set the content type by header "Content-Type"
*/
virtual
void
set_content_type
(
std
::
string
ct
);
public
:
/**
* write all headers to string stream.
*/
virtual
void
write
(
std
::
stringstream
&
ss
);
};
// A ResponseWriter interface is used by an HTTP handler to
// construct an HTTP response.
class
ISrsGoHttpResponseWriter
{
public
:
ISrsGoHttpResponseWriter
();
virtual
~
ISrsGoHttpResponseWriter
();
public
:
// Header returns the header map that will be sent by WriteHeader.
// Changing the header after a call to WriteHeader (or Write) has
// no effect.
virtual
SrsGoHttpHeader
*
header
()
=
0
;
// Write writes the data to the connection as part of an HTTP reply.
// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
// before writing the data. If the Header does not contain a
// Content-Type line, Write adds a Content-Type set to the result of passing
// the initial 512 bytes of written data to DetectContentType.
virtual
int
write
(
char
*
data
,
int
size
)
=
0
;
// WriteHeader sends an HTTP response header with status code.
// If WriteHeader is not called explicitly, the first call to Write
// will trigger an implicit WriteHeader(http.StatusOK).
// Thus explicit calls to WriteHeader are mainly used to
// send error codes.
virtual
void
write_header
(
int
code
)
=
0
;
};
// Objects implementing the Handler interface can be
// registered to serve a particular path or subtree
// in the HTTP server.
//
// ServeHTTP should write reply headers and data to the ResponseWriter
// and then return. Returning signals that the request is finished
// and that the HTTP server can move on to the next request on
// the connection.
class
ISrsGoHttpHandler
{
public
:
ISrsGoHttpHandler
();
virtual
~
ISrsGoHttpHandler
();
public
:
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
=
0
;
};
// Redirect to a fixed URL
class
SrsGoHttpRedirectHandler
:
public
ISrsGoHttpHandler
{
private
:
std
::
string
url
;
int
code
;
public
:
SrsGoHttpRedirectHandler
(
std
::
string
u
,
int
c
);
virtual
~
SrsGoHttpRedirectHandler
();
public
:
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
// NotFound replies to the request with an HTTP 404 not found error.
class
SrsGoHttpNotFoundHandler
:
public
ISrsGoHttpHandler
{
public
:
SrsGoHttpNotFoundHandler
();
virtual
~
SrsGoHttpNotFoundHandler
();
public
:
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
// the mux entry for server mux.
class
SrsGoHttpMuxEntry
{
public
:
bool
explicit_match
;
ISrsGoHttpHandler
*
handler
;
std
::
string
pattern
;
public
:
SrsGoHttpMuxEntry
();
virtual
~
SrsGoHttpMuxEntry
();
};
// ServeMux is an HTTP request multiplexer.
// It matches the URL of each incoming request against a list of registered
// patterns and calls the handler for the pattern that
// most closely matches the URL.
//
// Patterns name fixed, rooted paths, like "/favicon.ico",
// or rooted subtrees, like "/images/" (note the trailing slash).
// Longer patterns take precedence over shorter ones, so that
// if there are handlers registered for both "/images/"
// and "/images/thumbnails/", the latter handler will be
// called for paths beginning "/images/thumbnails/" and the
// former will receive requests for any other paths in the
// "/images/" subtree.
//
// Note that since a pattern ending in a slash names a rooted subtree,
// the pattern "/" matches all paths not matched by other registered
// patterns, not just the URL with Path == "/".
//
// Patterns may optionally begin with a host name, restricting matches to
// URLs on that host only. Host-specific patterns take precedence over
// general patterns, so that a handler might register for the two patterns
// "/codesearch" and "codesearch.google.com/" without also taking over
// requests for "http://www.google.com/".
//
// ServeMux also takes care of sanitizing the URL request path,
// redirecting any request containing . or .. elements to an
// equivalent .- and ..-free URL.
class
SrsGoHttpServeMux
{
private
:
std
::
map
<
std
::
string
,
SrsGoHttpMuxEntry
*>
entries
;
public
:
SrsGoHttpServeMux
();
virtual
~
SrsGoHttpServeMux
();
public
:
/**
* initialize the http serve mux.
*/
virtual
int
initialize
();
public
:
// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
virtual
int
handle
(
std
::
string
pattern
,
ISrsGoHttpHandler
*
handler
);
// interface ISrsGoHttpHandler
public:
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
private
:
virtual
int
find_handler
(
SrsHttpMessage
*
r
,
ISrsGoHttpHandler
**
ph
);
virtual
int
match
(
SrsHttpMessage
*
r
,
ISrsGoHttpHandler
**
ph
);
virtual
bool
path_match
(
std
::
string
pattern
,
std
::
string
path
);
};
/**
* response writer use st socket
*/
class
SrsGoHttpResponseWriter
:
public
ISrsGoHttpResponseWriter
{
private
:
SrsStSocket
*
skt
;
SrsGoHttpHeader
*
hdr
;
private
:
// reply header has been (logically) written
bool
header_wrote
;
// status code passed to WriteHeader
int
status
;
private
:
// explicitly-declared Content-Length; or -1
int64_t
content_length
;
// number of bytes written in body
int64_t
written
;
private
:
// wroteHeader tells whether the header's been written to "the
// wire" (or rather: w.conn.buf). this is unlike
// (*response).wroteHeader, which tells only whether it was
// logically written.
bool
header_sent
;
public
:
SrsGoHttpResponseWriter
(
SrsStSocket
*
io
);
virtual
~
SrsGoHttpResponseWriter
();
public
:
virtual
SrsGoHttpHeader
*
header
();
virtual
int
write
(
char
*
data
,
int
size
);
virtual
void
write_header
(
int
code
);
virtual
int
send_header
(
char
*
data
,
int
size
);
};
/**
* the matched handler info.
*/
...
...
@@ -183,12 +396,6 @@ public:
// object creator
public:
/**
* create http api resource handler.
*/
#ifdef SRS_AUTO_HTTP_API
static
SrsHttpHandler
*
create_http_api
();
#endif
/**
* create http stream resource handler.
*/
#ifdef SRS_AUTO_HTTP_SERVER
...
...
@@ -196,6 +403,12 @@ public:
#endif
};
// A Request represents an HTTP request received by a server
// or to be sent by a client.
//
// The field semantics differ slightly between client and server
// usage. In addition to the notes on the fields below, see the
// documentation for Request.Write and RoundTripper.
/**
* the http message, request or response.
*/
...
...
@@ -239,13 +452,16 @@ private:
// http headers
typedef
std
::
pair
<
std
::
string
,
std
::
string
>
SrsHttpHeaderField
;
std
::
vector
<
SrsHttpHeaderField
>
headers
;
// the query map
std
::
map
<
std
::
string
,
std
::
string
>
_query
;
public
:
SrsHttpMessage
();
virtual
~
SrsHttpMessage
();
public
:
virtual
int
initialize
();
public
:
virtual
char
*
http_ts_send_buffer
();
virtual
void
reset
();
virtual
int
parse_uri
();
public
:
virtual
bool
is_complete
();
virtual
u_int8_t
method
();
...
...
@@ -260,7 +476,7 @@ public:
virtual
std
::
string
url
();
virtual
std
::
string
host
();
virtual
std
::
string
path
();
virtual
std
::
string
query
();
public
:
virtual
std
::
string
body
();
virtual
char
*
body_raw
();
virtual
int64_t
body_size
();
...
...
@@ -273,14 +489,12 @@ public:
virtual
void
set_match
(
SrsHttpHandlerMatch
*
match
);
virtual
void
set_requires_crossdomain
(
bool
requires_crossdomain
);
virtual
void
append_body
(
const
char
*
body
,
int
length
);
public
:
/**
* get the param in query string,
* for instance, query is "start=100&end=200",
* then query_get("start") is "100", and query_get("end") is "200"
*/
virtual
std
::
string
query_get
(
std
::
string
key
);
public
:
virtual
int
request_header_count
();
virtual
std
::
string
request_header_key_at
(
int
index
);
virtual
std
::
string
request_header_value_at
(
int
index
);
...
...
trunk/src/app/srs_app_http_api.cpp
查看文件 @
9bbbaad
...
...
@@ -38,41 +38,15 @@ using namespace std;
#include <srs_app_statistic.hpp>
#include <srs_protocol_rtmp.hpp>
Srs
ApiRoot
::
Srs
ApiRoot
()
Srs
GoApiRoot
::
SrsGo
ApiRoot
()
{
handlers
.
push_back
(
new
SrsApiApi
());
}
Srs
ApiRoot
::~
Srs
ApiRoot
()
Srs
GoApiRoot
::~
SrsGo
ApiRoot
()
{
}
bool
SrsApiRoot
::
is_handler_valid
(
SrsHttpMessage
*
req
,
int
&
status_code
,
std
::
string
&
reason_phrase
)
{
if
(
!
SrsHttpHandler
::
is_handler_valid
(
req
,
status_code
,
reason_phrase
))
{
return
false
;
}
if
(
req
->
match
()
->
matched_url
.
length
()
!=
1
)
{
status_code
=
SRS_CONSTS_HTTP_NotFound
;
reason_phrase
=
SRS_CONSTS_HTTP_NotFound_str
;
return
false
;
}
return
true
;
}
bool
SrsApiRoot
::
can_handle
(
const
char
*
path
,
int
/*length*/
,
const
char
**
pchild
)
{
// reset the child path to path,
// for child to reparse the path.
*
pchild
=
path
;
// only compare the first char.
return
srs_path_equals
(
"/"
,
path
,
1
);
}
int
SrsApiRoot
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
SrsGoApiRoot
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
std
::
stringstream
ss
;
...
...
@@ -82,25 +56,19 @@ int SrsApiRoot::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
<<
__SRS_JFIELD_STR
(
"api"
,
"the api root"
)
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
}
SrsApiApi
::
SrsApiApi
()
{
handlers
.
push_back
(
new
SrsApiV1
());
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
Srs
ApiApi
::~
Srs
ApiApi
()
Srs
GoApiApi
::
SrsGo
ApiApi
()
{
}
bool
SrsApiApi
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
SrsGoApiApi
::~
SrsGoApiApi
(
)
{
return
srs_path_equals
(
"/api"
,
path
,
length
);
}
int
Srs
ApiApi
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
Srs
GoApiApi
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
std
::
stringstream
ss
;
...
...
@@ -110,34 +78,19 @@ int SrsApiApi::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
<<
__SRS_JFIELD_STR
(
"v1"
,
"the api version 1.0"
)
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
}
SrsApiV1
::
SrsApiV1
()
{
handlers
.
push_back
(
new
SrsApiVersion
());
handlers
.
push_back
(
new
SrsApiSummaries
());
handlers
.
push_back
(
new
SrsApiRusages
());
handlers
.
push_back
(
new
SrsApiSelfProcStats
());
handlers
.
push_back
(
new
SrsApiSystemProcStats
());
handlers
.
push_back
(
new
SrsApiMemInfos
());
handlers
.
push_back
(
new
SrsApiAuthors
());
handlers
.
push_back
(
new
SrsApiRequests
());
handlers
.
push_back
(
new
SrsApiVhosts
());
handlers
.
push_back
(
new
SrsApiStreams
());
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
Srs
ApiV1
::~
Srs
ApiV1
()
Srs
GoApiV1
::
SrsGo
ApiV1
()
{
}
bool
SrsApiV1
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
SrsGoApiV1
::~
SrsGoApiV1
(
)
{
return
srs_path_equals
(
"/v1"
,
path
,
length
);
}
int
Srs
ApiV1
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
Srs
GoApiV1
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
std
::
stringstream
ss
;
...
...
@@ -157,87 +110,18 @@ int SrsApiV1::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
Srs
ApiRequests
::
SrsApiRequests
()
Srs
GoApiVersion
::
SrsGoApiVersion
()
{
}
Srs
ApiRequests
::~
SrsApiRequests
()
Srs
GoApiVersion
::~
SrsGoApiVersion
()
{
}
bool
SrsApiRequests
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
{
return
srs_path_equals
(
"/requests"
,
path
,
length
);
}
int
SrsApiRequests
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
{
std
::
stringstream
ss
;
ss
<<
__SRS_JOBJECT_START
<<
__SRS_JFIELD_ERROR
(
ERROR_SUCCESS
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_ORG
(
"data"
,
__SRS_JOBJECT_START
)
<<
__SRS_JFIELD_STR
(
"uri"
,
req
->
uri
())
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_STR
(
"path"
,
req
->
path
())
<<
__SRS_JFIELD_CONT
;
// method
if
(
req
->
is_http_get
())
{
ss
<<
__SRS_JFIELD_STR
(
"METHOD"
,
"GET"
);
}
else
if
(
req
->
is_http_post
())
{
ss
<<
__SRS_JFIELD_STR
(
"METHOD"
,
"POST"
);
}
else
if
(
req
->
is_http_put
())
{
ss
<<
__SRS_JFIELD_STR
(
"METHOD"
,
"PUT"
);
}
else
if
(
req
->
is_http_delete
())
{
ss
<<
__SRS_JFIELD_STR
(
"METHOD"
,
"DELETE"
);
}
else
{
ss
<<
__SRS_JFIELD_ORG
(
"METHOD"
,
req
->
method
());
}
ss
<<
__SRS_JFIELD_CONT
;
// request headers
ss
<<
__SRS_JFIELD_NAME
(
"headers"
)
<<
__SRS_JOBJECT_START
;
for
(
int
i
=
0
;
i
<
req
->
request_header_count
();
i
++
)
{
std
::
string
key
=
req
->
request_header_key_at
(
i
);
std
::
string
value
=
req
->
request_header_value_at
(
i
);
if
(
i
<
req
->
request_header_count
()
-
1
)
{
ss
<<
__SRS_JFIELD_STR
(
key
,
value
)
<<
__SRS_JFIELD_CONT
;
}
else
{
ss
<<
__SRS_JFIELD_STR
(
key
,
value
);
}
}
ss
<<
__SRS_JOBJECT_END
<<
__SRS_JFIELD_CONT
;
// server informations
ss
<<
__SRS_JFIELD_NAME
(
"server"
)
<<
__SRS_JOBJECT_START
<<
__SRS_JFIELD_STR
(
"sigature"
,
RTMP_SIG_SRS_KEY
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_STR
(
"name"
,
RTMP_SIG_SRS_NAME
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_STR
(
"version"
,
RTMP_SIG_SRS_VERSION
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_STR
(
"link"
,
RTMP_SIG_SRS_URL
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_ORG
(
"time"
,
srs_get_system_time_ms
())
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
}
SrsApiVersion
::
SrsApiVersion
()
{
}
SrsApiVersion
::~
SrsApiVersion
()
{
}
bool
SrsApiVersion
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
{
return
srs_path_equals
(
"/versions"
,
path
,
length
);
}
int
SrsApiVersion
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
SrsGoApiVersion
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
std
::
stringstream
ss
;
...
...
@@ -251,43 +135,33 @@ int SrsApiVersion::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
}
SrsApiSummaries
::
SrsApiSummaries
()
{
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
Srs
ApiSummaries
::~
Srs
ApiSummaries
()
Srs
GoApiSummaries
::
SrsGo
ApiSummaries
()
{
}
bool
SrsApiSummaries
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
SrsGoApiSummaries
::~
SrsGoApiSummaries
(
)
{
return
srs_path_equals
(
"/summaries"
,
path
,
length
);
}
int
Srs
ApiSummaries
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
Srs
GoApiSummaries
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
std
::
stringstream
ss
;
srs_api_dump_summaries
(
ss
);
return
res_json
(
skt
,
req
,
ss
.
str
());
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
Srs
ApiRusages
::
Srs
ApiRusages
()
Srs
GoApiRusages
::
SrsGo
ApiRusages
()
{
}
Srs
ApiRusages
::~
Srs
ApiRusages
()
Srs
GoApiRusages
::~
SrsGo
ApiRusages
()
{
}
bool
SrsApiRusages
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
{
return
srs_path_equals
(
"/rusages"
,
path
,
length
);
}
int
SrsApiRusages
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
SrsGoApiRusages
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
req
)
{
std
::
stringstream
ss
;
...
...
@@ -317,23 +191,18 @@ int SrsApiRusages::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
}
SrsApiSelfProcStats
::
SrsApiSelfProcStats
()
{
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
Srs
ApiSelfProcStats
::~
Srs
ApiSelfProcStats
()
Srs
GoApiSelfProcStats
::
SrsGo
ApiSelfProcStats
()
{
}
bool
SrsApiSelfProcStats
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
SrsGoApiSelfProcStats
::~
SrsGoApiSelfProcStats
(
)
{
return
srs_path_equals
(
"/self_proc_stats"
,
path
,
length
);
}
int
Srs
ApiSelfProcStats
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
Srs
GoApiSelfProcStats
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
std
::
stringstream
ss
;
...
...
@@ -392,23 +261,18 @@ int SrsApiSelfProcStats::do_process_request(SrsStSocket* skt, SrsHttpMessage* re
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
Srs
ApiSystemProcStats
::
Srs
ApiSystemProcStats
()
Srs
GoApiSystemProcStats
::
SrsGo
ApiSystemProcStats
()
{
}
Srs
ApiSystemProcStats
::~
Srs
ApiSystemProcStats
()
Srs
GoApiSystemProcStats
::~
SrsGo
ApiSystemProcStats
()
{
}
bool
SrsApiSystemProcStats
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
{
return
srs_path_equals
(
"/system_proc_stats"
,
path
,
length
);
}
int
SrsApiSystemProcStats
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
SrsGoApiSystemProcStats
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
std
::
stringstream
ss
;
...
...
@@ -432,23 +296,18 @@ int SrsApiSystemProcStats::do_process_request(SrsStSocket* skt, SrsHttpMessage*
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
Srs
ApiMemInfos
::
Srs
ApiMemInfos
()
Srs
GoApiMemInfos
::
SrsGo
ApiMemInfos
()
{
}
Srs
ApiMemInfos
::~
Srs
ApiMemInfos
()
Srs
GoApiMemInfos
::~
SrsGo
ApiMemInfos
()
{
}
bool
SrsApiMemInfos
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
{
return
srs_path_equals
(
"/meminfos"
,
path
,
length
);
}
int
SrsApiMemInfos
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
SrsGoApiMemInfos
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
std
::
stringstream
ss
;
...
...
@@ -473,23 +332,18 @@ int SrsApiMemInfos::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
Srs
ApiAuthors
::
Srs
ApiAuthors
()
Srs
GoApiAuthors
::
SrsGo
ApiAuthors
()
{
}
Srs
ApiAuthors
::~
Srs
ApiAuthors
()
Srs
GoApiAuthors
::~
SrsGo
ApiAuthors
()
{
}
bool
SrsApiAuthors
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
{
return
srs_path_equals
(
"/authors"
,
path
,
length
);
}
int
SrsApiAuthors
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
SrsGoApiAuthors
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
std
::
stringstream
ss
;
...
...
@@ -503,24 +357,82 @@ int SrsApiAuthors::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
SrsGoApiRequests
::
SrsGoApiRequests
()
{
}
SrsGoApiRequests
::~
SrsGoApiRequests
()
{
}
SrsApiVhosts
::
SrsApiVhosts
(
)
int
SrsGoApiRequests
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
SrsHttpMessage
*
req
=
r
;
std
::
stringstream
ss
;
ss
<<
__SRS_JOBJECT_START
<<
__SRS_JFIELD_ERROR
(
ERROR_SUCCESS
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_ORG
(
"data"
,
__SRS_JOBJECT_START
)
<<
__SRS_JFIELD_STR
(
"uri"
,
req
->
uri
())
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_STR
(
"path"
,
req
->
path
())
<<
__SRS_JFIELD_CONT
;
// method
if
(
req
->
is_http_get
())
{
ss
<<
__SRS_JFIELD_STR
(
"METHOD"
,
"GET"
);
}
else
if
(
req
->
is_http_post
())
{
ss
<<
__SRS_JFIELD_STR
(
"METHOD"
,
"POST"
);
}
else
if
(
req
->
is_http_put
())
{
ss
<<
__SRS_JFIELD_STR
(
"METHOD"
,
"PUT"
);
}
else
if
(
req
->
is_http_delete
())
{
ss
<<
__SRS_JFIELD_STR
(
"METHOD"
,
"DELETE"
);
}
else
{
ss
<<
__SRS_JFIELD_ORG
(
"METHOD"
,
req
->
method
());
}
ss
<<
__SRS_JFIELD_CONT
;
// request headers
ss
<<
__SRS_JFIELD_NAME
(
"headers"
)
<<
__SRS_JOBJECT_START
;
for
(
int
i
=
0
;
i
<
req
->
request_header_count
();
i
++
)
{
std
::
string
key
=
req
->
request_header_key_at
(
i
);
std
::
string
value
=
req
->
request_header_value_at
(
i
);
if
(
i
<
req
->
request_header_count
()
-
1
)
{
ss
<<
__SRS_JFIELD_STR
(
key
,
value
)
<<
__SRS_JFIELD_CONT
;
}
else
{
ss
<<
__SRS_JFIELD_STR
(
key
,
value
);
}
}
ss
<<
__SRS_JOBJECT_END
<<
__SRS_JFIELD_CONT
;
// server informations
ss
<<
__SRS_JFIELD_NAME
(
"server"
)
<<
__SRS_JOBJECT_START
<<
__SRS_JFIELD_STR
(
"sigature"
,
RTMP_SIG_SRS_KEY
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_STR
(
"name"
,
RTMP_SIG_SRS_NAME
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_STR
(
"version"
,
RTMP_SIG_SRS_VERSION
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_STR
(
"link"
,
RTMP_SIG_SRS_URL
)
<<
__SRS_JFIELD_CONT
<<
__SRS_JFIELD_ORG
(
"time"
,
srs_get_system_time_ms
())
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
<<
__SRS_JOBJECT_END
;
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
Srs
ApiVhosts
::~
Srs
ApiVhosts
()
Srs
GoApiVhosts
::
SrsGo
ApiVhosts
()
{
}
bool
SrsApiVhosts
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
SrsGoApiVhosts
::~
SrsGoApiVhosts
(
)
{
return
srs_path_equals
(
"/vhosts"
,
path
,
length
);
}
int
Srs
ApiVhosts
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
Srs
GoApiVhosts
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
SrsHttpMessage
*
req
=
r
;
std
::
stringstream
data
;
SrsStatistic
*
stat
=
SrsStatistic
::
instance
();
int
ret
=
stat
->
dumps_vhosts
(
data
);
...
...
@@ -533,23 +445,18 @@ int SrsApiVhosts::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
<<
__SRS_JFIELD_ORG
(
"vhosts"
,
data
.
str
())
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
Srs
ApiStreams
::
Srs
ApiStreams
()
Srs
GoApiStreams
::
SrsGo
ApiStreams
()
{
}
Srs
ApiStreams
::~
Srs
ApiStreams
()
Srs
GoApiStreams
::~
SrsGo
ApiStreams
()
{
}
bool
SrsApiStreams
::
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
/*pchild*/
)
{
return
srs_path_equals
(
"/streams"
,
path
,
length
);
}
int
SrsApiStreams
::
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
SrsGoApiStreams
::
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
std
::
stringstream
data
;
SrsStatistic
*
stat
=
SrsStatistic
::
instance
();
...
...
@@ -563,15 +470,14 @@ int SrsApiStreams::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
<<
__SRS_JFIELD_ORG
(
"streams"
,
data
.
str
())
<<
__SRS_JOBJECT_END
;
return
res_json
(
skt
,
req
,
ss
.
str
());
return
srs_go_http_response_json
(
w
,
ss
.
str
());
}
SrsHttpApi
::
SrsHttpApi
(
SrsServer
*
srs_server
,
st_netfd_t
client_stfd
,
SrsHttpHandler
*
_handler
)
:
SrsConnection
(
srs_server
,
client_stfd
)
SrsHttpApi
::
SrsHttpApi
(
SrsServer
*
svr
,
st_netfd_t
fd
,
SrsGoHttpServeMux
*
m
)
:
SrsConnection
(
svr
,
fd
)
{
mux
=
m
;
parser
=
new
SrsHttpParser
();
handler
=
_handler
;
requires_crossdomain
=
false
;
}
SrsHttpApi
::~
SrsHttpApi
()
...
...
@@ -628,7 +534,8 @@ int SrsHttpApi::do_cycle()
SrsAutoFree
(
SrsHttpMessage
,
req
);
// ok, handle http request.
if
((
ret
=
process_request
(
&
skt
,
req
))
!=
ERROR_SUCCESS
)
{
SrsGoHttpResponseWriter
writer
(
&
skt
);
if
((
ret
=
process_request
(
&
writer
,
req
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
...
...
@@ -636,46 +543,21 @@ int SrsHttpApi::do_cycle()
return
ret
;
}
int
SrsHttpApi
::
process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
int
SrsHttpApi
::
process_request
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
{
int
ret
=
ERROR_SUCCESS
;
// parse uri to schema/server:port/path?query
if
((
ret
=
req
->
parse_uri
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_trace
(
"HTTP %s %s, content-length=%"
PRId64
""
,
req
->
method_str
().
c_str
(),
req
->
url
().
c_str
(),
req
->
content_length
());
// TODO: maybe need to parse the url.
std
::
string
url
=
req
->
path
();
SrsHttpHandlerMatch
*
p
=
NULL
;
if
((
ret
=
handler
->
best_match
(
url
.
data
(),
url
.
length
(),
&
p
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"failed to find the best match handler for url. ret=%d"
,
ret
);
return
ret
;
}
r
->
method_str
().
c_str
(),
r
->
url
().
c_str
(),
r
->
content_length
());
// if success, p and pstart should be valid.
srs_assert
(
p
);
srs_assert
(
p
->
handler
);
srs_assert
(
p
->
matched_url
.
length
()
<=
url
.
length
());
srs_info
(
"best match handler, matched_url=%s"
,
p
->
matched_url
.
c_str
());
req
->
set_match
(
p
);
req
->
set_requires_crossdomain
(
requires_crossdomain
);
// use handler to process request.
if
((
ret
=
p
->
handler
->
process_request
(
skt
,
req
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"handler failed to process http request. ret=%d"
,
ret
);
// use default server mux to serve http request.
if
((
ret
=
mux
->
serve_http
(
w
,
r
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"serve http msg failed. ret=%d"
,
ret
);
}
return
ret
;
}
if
(
req
->
requires_crossdomain
())
{
requires_crossdomain
=
true
;
}
return
ret
;
}
...
...
trunk/src/app/srs_app_http_api.hpp
查看文件 @
9bbbaad
...
...
@@ -42,158 +42,130 @@ class SrsHttpHandler;
#include <srs_app_http.hpp>
// for http root.
class
Srs
ApiRoot
:
public
Srs
HttpHandler
class
Srs
GoApiRoot
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiRoot
();
virtual
~
SrsApiRoot
();
SrsGoApiRoot
();
virtual
~
SrsGoApiRoot
();
public
:
virtual
bool
is_handler_valid
(
SrsHttpMessage
*
req
,
int
&
status_code
,
std
::
string
&
reason_phrase
);
protected
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiApi
:
public
Srs
HttpHandler
class
Srs
GoApiApi
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiApi
();
virtual
~
SrsApiApi
();
SrsGoApiApi
();
virtual
~
SrsGoApiApi
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiV1
:
public
Srs
HttpHandler
class
Srs
GoApiV1
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiV1
();
virtual
~
SrsApiV1
();
SrsGoApiV1
();
virtual
~
SrsGoApiV1
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiRequests
:
public
Srs
HttpHandler
class
Srs
GoApiVersion
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiRequests
();
virtual
~
SrsApiRequests
();
SrsGoApiVersion
();
virtual
~
SrsGoApiVersion
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiVersion
:
public
Srs
HttpHandler
class
Srs
GoApiSummaries
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiVersion
();
virtual
~
SrsApiVersion
();
SrsGoApiSummaries
();
virtual
~
SrsGoApiSummaries
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiSummaries
:
public
Srs
HttpHandler
class
Srs
GoApiRusages
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiSummaries
();
virtual
~
SrsApiSummaries
();
SrsGoApiRusages
();
virtual
~
SrsGoApiRusages
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiRusages
:
public
Srs
HttpHandler
class
Srs
GoApiSelfProcStats
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiRusages
();
virtual
~
SrsApiRusages
();
SrsGoApiSelfProcStats
();
virtual
~
SrsGoApiSelfProcStats
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiSelfProcStats
:
public
Srs
HttpHandler
class
Srs
GoApiSystemProcStats
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiSelfProcStats
();
virtual
~
SrsApiSelfProcStats
();
SrsGoApiSystemProcStats
();
virtual
~
SrsGoApiSystemProcStats
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiSystemProcStats
:
public
Srs
HttpHandler
class
Srs
GoApiMemInfos
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiSystemProcStats
();
virtual
~
SrsApiSystemProcStats
();
SrsGoApiMemInfos
();
virtual
~
SrsGoApiMemInfos
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiMemInfos
:
public
Srs
HttpHandler
class
Srs
GoApiAuthors
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiMemInfos
();
virtual
~
SrsApiMemInfos
();
SrsGoApiAuthors
();
virtual
~
SrsGoApiAuthors
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiAuthors
:
public
Srs
HttpHandler
class
Srs
GoApiRequests
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiAuthors
();
virtual
~
SrsApiAuthors
();
SrsGoApiRequests
();
virtual
~
SrsGoApiRequests
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiVhosts
:
public
Srs
HttpHandler
class
Srs
GoApiVhosts
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiVhosts
();
virtual
~
SrsApiVhosts
();
SrsGoApiVhosts
();
virtual
~
SrsGoApiVhosts
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
Srs
ApiStreams
:
public
Srs
HttpHandler
class
Srs
GoApiStreams
:
public
ISrsGo
HttpHandler
{
public
:
SrsApiStreams
();
virtual
~
SrsApiStreams
();
SrsGoApiStreams
();
virtual
~
SrsGoApiStreams
();
public
:
virtual
bool
can_handle
(
const
char
*
path
,
int
length
,
const
char
**
pchild
);
protected
:
virtual
int
do_process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
class
SrsHttpApi
:
public
SrsConnection
{
private
:
SrsHttpParser
*
parser
;
SrsHttpHandler
*
handler
;
bool
requires_crossdomain
;
SrsGoHttpServeMux
*
mux
;
public
:
SrsHttpApi
(
SrsServer
*
s
rs_server
,
st_netfd_t
client_stfd
,
SrsHttpHandler
*
_handler
);
SrsHttpApi
(
SrsServer
*
s
vr
,
st_netfd_t
fd
,
SrsGoHttpServeMux
*
m
);
virtual
~
SrsHttpApi
();
public
:
virtual
void
kbps_resample
();
...
...
@@ -204,7 +176,7 @@ public:
protected
:
virtual
int
do_cycle
();
private
:
virtual
int
process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
);
virtual
int
process_request
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
};
#endif
...
...
trunk/src/app/srs_app_http_conn.cpp
查看文件 @
9bbbaad
...
...
@@ -549,11 +549,6 @@ int SrsHttpConn::do_cycle()
int
SrsHttpConn
::
process_request
(
SrsStSocket
*
skt
,
SrsHttpMessage
*
req
)
{
int
ret
=
ERROR_SUCCESS
;
// parse uri to schema/server:port/path?query
if
((
ret
=
req
->
parse_uri
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_trace
(
"HTTP %s %s, content-length=%"
PRId64
""
,
req
->
method_str
().
c_str
(),
req
->
url
().
c_str
(),
req
->
content_length
());
...
...
trunk/src/app/srs_app_server.cpp
查看文件 @
9bbbaad
...
...
@@ -330,7 +330,7 @@ SrsServer::SrsServer()
// for some global instance is not ready now,
// new these objects in initialize instead.
#ifdef SRS_AUTO_HTTP_API
http_api_
handler
=
NULL
;
http_api_
mux
=
new
SrsGoHttpServeMux
()
;
#endif
#ifdef SRS_AUTO_HTTP_SERVER
http_stream_handler
=
NULL
;
...
...
@@ -363,7 +363,7 @@ void SrsServer::destroy()
#endif
#ifdef SRS_AUTO_HTTP_API
srs_freep
(
http_api_
handler
);
srs_freep
(
http_api_
mux
);
#endif
#ifdef SRS_AUTO_HTTP_SERVER
...
...
@@ -415,8 +415,52 @@ int SrsServer::initialize()
kbps
->
set_io
(
NULL
,
NULL
);
#ifdef SRS_AUTO_HTTP_API
srs_assert
(
!
http_api_handler
);
http_api_handler
=
SrsHttpHandler
::
create_http_api
();
if
((
ret
=
http_api_mux
->
initialize
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
#endif
#ifdef SRS_AUTO_HTTP_API
srs_assert
(
http_api_mux
);
if
((
ret
=
http_api_mux
->
handle
(
"/"
,
new
SrsGoApiRoot
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api"
,
new
SrsGoApiApi
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api/v1"
,
new
SrsGoApiV1
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api/v1/versions"
,
new
SrsGoApiVersion
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api/v1/summaries"
,
new
SrsGoApiSummaries
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api/v1/rusages"
,
new
SrsGoApiRusages
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api/v1/self_proc_stats"
,
new
SrsGoApiSelfProcStats
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api/v1/system_proc_stats"
,
new
SrsGoApiSystemProcStats
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api/v1/meminfos"
,
new
SrsGoApiMemInfos
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api/v1/authors"
,
new
SrsGoApiAuthors
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api/v1/requests"
,
new
SrsGoApiRequests
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api/v1/vhosts"
,
new
SrsGoApiVhosts
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
http_api_mux
->
handle
(
"/api/v1/streams"
,
new
SrsGoApiStreams
()))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
#endif
#ifdef SRS_AUTO_HTTP_SERVER
srs_assert
(
!
http_stream_handler
);
...
...
@@ -430,12 +474,6 @@ int SrsServer::initialize()
srs_assert
(
!
ingester
);
ingester
=
new
SrsIngester
();
#endif
#ifdef SRS_AUTO_HTTP_API
if
((
ret
=
http_api_handler
->
initialize
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
#endif
#ifdef SRS_AUTO_HTTP_SERVER
if
((
ret
=
http_stream_handler
->
initialize
())
!=
ERROR_SUCCESS
)
{
...
...
@@ -896,7 +934,7 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
conn
=
new
SrsRtmpConn
(
this
,
client_stfd
);
}
else
if
(
type
==
SrsListenerHttpApi
)
{
#ifdef SRS_AUTO_HTTP_API
conn
=
new
SrsHttpApi
(
this
,
client_stfd
,
http_api_
handler
);
conn
=
new
SrsHttpApi
(
this
,
client_stfd
,
http_api_
mux
);
#else
srs_warn
(
"close http client for server not support http-api"
);
srs_close_stfd
(
client_stfd
);
...
...
trunk/src/app/srs_app_server.hpp
查看文件 @
9bbbaad
...
...
@@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class
SrsServer
;
class
SrsConnection
;
class
SrsGoHttpServeMux
;
class
SrsHttpHandler
;
class
SrsIngester
;
class
SrsHttpHeartbeat
;
...
...
@@ -116,7 +117,7 @@ class SrsServer : public ISrsReloadHandler
{
private
:
#ifdef SRS_AUTO_HTTP_API
Srs
HttpHandler
*
http_api_handler
;
Srs
GoHttpServeMux
*
http_api_mux
;
#endif
#ifdef SRS_AUTO_HTTP_SERVER
SrsHttpHandler
*
http_stream_handler
;
...
...
trunk/src/core/srs_core.hpp
查看文件 @
9bbbaad
...
...
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
#define VERSION_REVISION 9
5
#define VERSION_REVISION 9
6
// server info.
#define RTMP_SIG_SRS_KEY "SRS"
...
...
trunk/src/kernel/srs_kernel_error.hpp
查看文件 @
9bbbaad
...
...
@@ -204,6 +204,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_AAC_DATA_INVALID 3048
#define ERROR_HTTP_STATUS_INVLIAD 3049
///////////////////////////////////////////////////////
// HTTP protocol error.
///////////////////////////////////////////////////////
#define ERROR_HTTP_PATTERN_EMPTY 4000
#define ERROR_HTTP_PATTERN_DUPLICATED 4001
#define ERROR_HTTP_URL_NOT_CLEAN 4002
#define ERROR_HTTP_CONTENT_LENGTH 4003
/**
* whether the error code is an system control error.
*/
...
...
请
注册
或
登录
后发表评论