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
2014-04-02 12:03:49 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
ec6d696565a20c39e72f27956ddb1e1b76fd505d
ec6d6965
1 parent
e70609ce
refine http framework, use http message
隐藏空白字符变更
内嵌
并排对比
正在显示
7 个修改的文件
包含
343 行增加
和
314 行删除
trunk/conf/console.conf
trunk/src/app/srs_app_http.cpp
trunk/src/app/srs_app_http.hpp
trunk/src/app/srs_app_http_conn.cpp
trunk/src/app/srs_app_http_conn.hpp
trunk/src/app/srs_app_http_hooks.cpp
trunk/src/app/srs_app_http_hooks.hpp
trunk/conf/console.conf
100755 → 100644
查看文件 @
ec6d696
trunk/src/app/srs_app_http.cpp
查看文件 @
ec6d696
...
...
@@ -27,41 +27,263 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <stdlib.h>
using
namespace
std
;
#include <srs_kernel_error.hpp>
#include <srs_kernel_log.hpp>
#include <srs_app_socket.hpp>
#define SRS_DEFAULT_HTTP_PORT 80
#define SRS_HTTP_HEADER_BUFFER 1024
SrsHttpMessage
::
SrsHttpMessage
()
{
body
=
new
SrsBuffer
();
state
=
SrsHttpParseStateInit
;
_body
=
new
SrsBuffer
();
_state
=
SrsHttpParseStateInit
;
}
SrsHttpMessage
::~
SrsHttpMessage
()
{
srs_freep
(
body
);
srs_freep
(
_
body
);
}
void
SrsHttpMessage
::
reset
()
{
state
=
SrsHttpParseStateInit
;
body
->
clear
();
url
=
""
;
_state
=
SrsHttpParseStateInit
;
_body
->
clear
();
_url
=
""
;
}
bool
SrsHttpMessage
::
is_complete
()
{
return
state
==
SrsHttpParseStateComplete
;
return
_state
==
SrsHttpParseStateComplete
;
}
u_int8_t
SrsHttpMessage
::
method
()
{
return
(
u_int8_t
)
_header
.
method
;
}
string
SrsHttpMessage
::
url
()
{
return
_url
;
}
string
SrsHttpMessage
::
body
()
{
std
::
string
b
;
if
(
_body
&&
!
_body
->
empty
())
{
b
.
append
(
_body
->
bytes
(),
_body
->
size
());
}
return
b
;
}
int64_t
SrsHttpMessage
::
body_size
()
{
return
(
int64_t
)
_body
->
size
();
}
int64_t
SrsHttpMessage
::
content_length
()
{
return
_header
.
content_length
;
}
void
SrsHttpMessage
::
set_url
(
std
::
string
url
)
{
_url
=
url
;
}
void
SrsHttpMessage
::
set_state
(
SrsHttpParseState
state
)
{
_state
=
state
;
}
void
SrsHttpMessage
::
set_header
(
http_parser
*
header
)
{
memcpy
(
&
_header
,
header
,
sizeof
(
http_parser
));
}
void
SrsHttpMessage
::
append_body
(
const
char
*
body
,
int
length
)
{
_body
->
append
(
body
,
length
);
}
SrsHttpParser
::
SrsHttpParser
()
{
msg
=
NULL
;
}
SrsHttpParser
::~
SrsHttpParser
()
{
srs_freep
(
msg
);
}
int
SrsHttpParser
::
initialize
(
enum
http_parser_type
type
)
{
int
ret
=
ERROR_SUCCESS
;
memset
(
&
settings
,
0
,
sizeof
(
settings
));
settings
.
on_message_begin
=
on_message_begin
;
settings
.
on_url
=
on_url
;
settings
.
on_header_field
=
on_header_field
;
settings
.
on_header_value
=
on_header_value
;
settings
.
on_headers_complete
=
on_headers_complete
;
settings
.
on_body
=
on_body
;
settings
.
on_message_complete
=
on_message_complete
;
http_parser_init
(
&
parser
,
type
);
// callback object ptr.
parser
.
data
=
(
void
*
)
this
;
return
ret
;
}
int
SrsHttpParser
::
parse_message
(
SrsSocket
*
skt
,
SrsHttpMessage
**
ppmsg
)
{
*
ppmsg
=
NULL
;
int
ret
=
ERROR_SUCCESS
;
// the msg must be always NULL
srs_assert
(
msg
==
NULL
);
msg
=
new
SrsHttpMessage
();
// reset response header.
msg
->
reset
();
// do parse
if
((
ret
=
parse_message_imp
(
skt
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"parse http msg failed. ret=%d"
,
ret
);
}
srs_freep
(
msg
);
return
ret
;
}
// parse ok, return the msg.
*
ppmsg
=
msg
;
msg
=
NULL
;
return
ret
;
}
int
SrsHttpParser
::
parse_message_imp
(
SrsSocket
*
skt
)
{
int
ret
=
ERROR_SUCCESS
;
// the msg should never be NULL
srs_assert
(
msg
!=
NULL
);
// parser header.
char
buf
[
SRS_HTTP_HEADER_BUFFER
];
for
(;;)
{
ssize_t
nread
;
if
((
ret
=
skt
->
read
(
buf
,
(
size_t
)
sizeof
(
buf
),
&
nread
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"read body from server failed. ret=%d"
,
ret
);
}
return
ret
;
}
ssize_t
nparsed
=
http_parser_execute
(
&
parser
,
&
settings
,
buf
,
nread
);
srs_info
(
"read_size=%d, nparsed=%d"
,
(
int
)
nread
,
(
int
)
nparsed
);
// check header size.
if
(
msg
->
is_complete
())
{
srs_trace
(
"http request parsed, method=%d, url=%s, content-length=%"
PRId64
""
,
msg
->
method
(),
msg
->
url
().
c_str
(),
msg
->
content_length
());
return
ret
;
}
if
(
nparsed
!=
nread
)
{
ret
=
ERROR_HTTP_PARSE_HEADER
;
srs_error
(
"parse response error, parsed(%d)!=read(%d), ret=%d"
,
(
int
)
nparsed
,
(
int
)
nread
,
ret
);
return
ret
;
}
}
return
ret
;
}
int
SrsHttpParser
::
on_message_begin
(
http_parser
*
parser
)
{
SrsHttpParser
*
obj
=
(
SrsHttpParser
*
)
parser
->
data
;
obj
->
msg
->
set_state
(
SrsHttpParseStateStart
);
srs_info
(
"***MESSAGE BEGIN***"
);
return
0
;
}
int
SrsHttpParser
::
on_headers_complete
(
http_parser
*
parser
)
{
SrsHttpParser
*
obj
=
(
SrsHttpParser
*
)
parser
->
data
;
obj
->
msg
->
set_header
(
parser
);
srs_info
(
"***HEADERS COMPLETE***"
);
// see http_parser.c:1570, return 1 to skip body.
return
0
;
}
int
SrsHttpParser
::
on_message_complete
(
http_parser
*
parser
)
{
SrsHttpParser
*
obj
=
(
SrsHttpParser
*
)
parser
->
data
;
// save the parser when header parse completed.
obj
->
msg
->
set_state
(
SrsHttpParseStateComplete
);
srs_info
(
"***MESSAGE COMPLETE***
\n
"
);
return
0
;
}
int
SrsHttpParser
::
on_url
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
)
{
SrsHttpParser
*
obj
=
(
SrsHttpParser
*
)
parser
->
data
;
if
(
length
>
0
)
{
std
::
string
url
;
url
.
append
(
at
,
(
int
)
length
);
obj
->
msg
->
set_url
(
url
);
}
srs_info
(
"Method: %d, Url: %.*s"
,
parser
->
method
,
(
int
)
length
,
at
);
return
0
;
}
int
SrsHttpParser
::
on_header_field
(
http_parser
*
/*parser*/
,
const
char
*
at
,
size_t
length
)
{
srs_info
(
"Header field: %.*s"
,
(
int
)
length
,
at
);
return
0
;
}
int
SrsHttpParser
::
on_header_value
(
http_parser
*
/*parser*/
,
const
char
*
at
,
size_t
length
)
{
srs_info
(
"Header value: %.*s"
,
(
int
)
length
,
at
);
return
0
;
}
int
SrsHttpParser
::
on_body
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
)
{
SrsHttpParser
*
obj
=
(
SrsHttpParser
*
)
parser
->
data
;
if
(
length
>
0
)
{
srs_assert
(
obj
);
srs_assert
(
obj
->
msg
);
obj
->
msg
->
append_body
(
at
,
(
int
)
length
);
}
srs_info
(
"Body: %.*s"
,
(
int
)
length
,
at
);
return
0
;
}
SrsHttpUri
::
SrsHttpUri
()
...
...
trunk/src/app/srs_app_http.hpp
查看文件 @
ec6d696
...
...
@@ -68,17 +68,43 @@ enum SrsHttpParseState {
*/
class
SrsHttpMessage
{
public
:
std
::
string
url
;
http_parser
header
;
SrsBuffer
*
body
;
SrsHttpParseState
state
;
private
:
/**
* parsed url.
*/
std
::
string
_url
;
/**
* parsed http header.
*/
http_parser
_header
;
/**
* body object, in bytes.
* @remark, user can get body in string by get_body().
*/
SrsBuffer
*
_body
;
/**
* parser state
* @remark, user can use is_complete() to determine the state.
*/
SrsHttpParseState
_state
;
public
:
SrsHttpMessage
();
virtual
~
SrsHttpMessage
();
public
:
virtual
void
reset
();
public
:
virtual
bool
is_complete
();
virtual
u_int8_t
method
();
virtual
std
::
string
url
();
virtual
std
::
string
body
();
virtual
int64_t
body_size
();
virtual
int64_t
content_length
();
virtual
void
set_url
(
std
::
string
url
);
virtual
void
set_state
(
SrsHttpParseState
state
);
virtual
void
set_header
(
http_parser
*
header
);
virtual
void
append_body
(
const
char
*
body
,
int
length
);
};
/**
...
...
@@ -87,11 +113,39 @@ public:
*/
class
SrsHttpParser
{
private
:
http_parser_settings
settings
;
http_parser
parser
;
SrsHttpMessage
*
msg
;
public
:
SrsHttpParser
();
virtual
~
SrsHttpParser
();
public
:
//virtual int parse_requst(SrsHttpMessage** ppreq);
/**
* initialize the http parser with specified type,
* one parser can only parse request or response messages.
*/
virtual
int
initialize
(
enum
http_parser_type
type
);
/**
* always parse a http message,
* that is, the *ppmsg always NOT-NULL when return success.
* or error and *ppmsg must be NULL.
* @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete().
*/
virtual
int
parse_message
(
SrsSocket
*
skt
,
SrsHttpMessage
**
ppmsg
);
private
:
/**
* parse the HTTP message to member field: msg.
*/
virtual
int
parse_message_imp
(
SrsSocket
*
skt
);
private
:
static
int
on_message_begin
(
http_parser
*
parser
);
static
int
on_headers_complete
(
http_parser
*
parser
);
static
int
on_message_complete
(
http_parser
*
parser
);
static
int
on_url
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
);
static
int
on_header_field
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
);
static
int
on_header_value
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
);
static
int
on_body
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
);
};
/**
...
...
trunk/src/app/srs_app_http_conn.cpp
查看文件 @
ec6d696
...
...
@@ -33,18 +33,19 @@ using namespace std;
#include <srs_app_socket.hpp>
#include <srs_app_http.hpp>
#include <srs_kernel_buffer.hpp>
#include <srs_core_autofree.hpp>
#define SRS_HTTP_HEADER_BUFFER 1024
SrsHttpConn
::
SrsHttpConn
(
SrsServer
*
srs_server
,
st_netfd_t
client_stfd
)
:
SrsConnection
(
srs_server
,
client_stfd
)
{
req
=
new
SrsHttpMessage
();
parser
=
new
SrsHttpParser
();
}
SrsHttpConn
::~
SrsHttpConn
()
{
srs_freep
(
req
);
srs_freep
(
parser
);
}
int
SrsHttpConn
::
do_cycle
()
...
...
@@ -56,83 +57,46 @@ int SrsHttpConn::do_cycle()
return
ret
;
}
srs_trace
(
"http get peer ip success. ip=%s"
,
ip
);
// setup http parser
http_parser_settings
settings
;
memset
(
&
settings
,
0
,
sizeof
(
settings
));
settings
.
on_message_begin
=
on_message_begin
;
settings
.
on_url
=
on_url
;
settings
.
on_header_field
=
on_header_field
;
settings
.
on_header_value
=
on_header_value
;
settings
.
on_headers_complete
=
on_headers_complete
;
settings
.
on_body
=
on_body
;
settings
.
on_message_complete
=
on_message_complete
;
http_parser
parser
;
http_parser_init
(
&
parser
,
HTTP_REQUEST
);
// callback object ptr.
parser
.
data
=
(
void
*
)
this
;
// initialize parser
if
((
ret
=
parser
->
initialize
(
HTTP_REQUEST
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"initialize http parser failed. ret=%d"
,
ret
);
return
ret
;
}
// underlayer socket
SrsSocket
skt
(
stfd
);
// process http messages.
for
(;;)
{
if
((
ret
=
parse_request
(
&
skt
,
&
parser
,
&
settings
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"http client cycle failed. ret=%d"
,
ret
);
}
return
ret
;
}
}
SrsHttpMessage
*
req
=
NULL
;
return
ret
;
}
int
SrsHttpConn
::
parse_request
(
SrsSocket
*
skt
,
http_parser
*
parser
,
http_parser_settings
*
settings
)
{
int
ret
=
ERROR_SUCCESS
;
// reset response header.
req
->
reset
();
// parser header.
char
buf
[
SRS_HTTP_HEADER_BUFFER
];
for
(;;)
{
ssize_t
nread
;
if
((
ret
=
skt
->
read
(
buf
,
(
size_t
)
sizeof
(
buf
),
&
nread
))
!=
ERROR_SUCCESS
)
{
if
(
!
srs_is_client_gracefully_close
(
ret
))
{
srs_error
(
"read body from server failed. ret=%d"
,
ret
);
}
// get a http message
if
((
ret
=
parser
->
parse_message
(
&
skt
,
&
req
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
ssize_t
nparsed
=
http_parser_execute
(
parser
,
settings
,
buf
,
nread
);
srs_info
(
"read_size=%d, nparsed=%d"
,
(
int
)
nread
,
(
int
)
nparsed
);
// check header size.
if
(
req
->
is_complete
())
{
srs_trace
(
"http request parsed, method=%d, url=%s, content-length=%"
PRId64
""
,
req
->
header
.
method
,
req
->
url
.
c_str
(),
req
->
header
.
content_length
);
return
process_request
(
skt
);
}
// if SUCCESS, always NOT-NULL and completed message.
srs_assert
(
req
);
srs_assert
(
req
->
is_complete
());
// always free it in this scope.
SrsAutoFree
(
SrsHttpMessage
,
req
,
false
);
if
(
nparsed
!=
nread
)
{
ret
=
ERROR_HTTP_PARSE_HEADER
;
srs_error
(
"parse response error, parsed(%d)!=read(%d), ret=%d"
,
(
int
)
nparsed
,
(
int
)
nread
,
ret
);
// ok, handle http request.
if
((
ret
=
process_request
(
&
skt
,
req
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
return
ret
;
}
int
SrsHttpConn
::
process_request
(
SrsSocket
*
skt
)
int
SrsHttpConn
::
process_request
(
SrsSocket
*
skt
,
SrsHttpMessage
*
req
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
req
->
header
.
method
==
HTTP_OPTIONS
)
{
if
(
req
->
method
()
==
HTTP_OPTIONS
)
{
char
data
[]
=
"HTTP/1.1 200 OK"
__CRLF
"Content-Length: 0"
__CRLF
"Server: SRS/"
RTMP_SIG_SRS_VERSION
""
__CRLF
...
...
@@ -149,14 +113,14 @@ int SrsHttpConn::process_request(SrsSocket* skt)
std
::
stringstream
ss
;
ss
<<
"HTTP/1.1 200 OK "
<<
__CRLF
<<
"Content-Length: "
<<
tilte
.
length
()
+
req
->
body
->
size
()
<<
__CRLF
<<
"Content-Length: "
<<
tilte
.
length
()
+
req
->
body
_
size
()
<<
__CRLF
<<
"Server: SRS/"
RTMP_SIG_SRS_VERSION
""
<<
__CRLF
<<
"Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT"
<<
__CRLF
<<
"Access-Control-Allow-Origin: *"
<<
__CRLF
<<
"Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE"
<<
__CRLF
<<
"Access-Control-Allow-Headers: Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type"
<<
__CRLF
<<
"Content-Type: text/html;charset=utf-8"
<<
__CRLFCRLF
<<
tilte
<<
(
req
->
body
->
empty
()
?
""
:
req
->
body
->
bytes
()
)
<<
tilte
<<
req
->
body
().
c_str
(
)
<<
""
;
return
skt
->
write
(
ss
.
str
().
c_str
(),
ss
.
str
().
length
(),
NULL
);
}
...
...
@@ -164,74 +128,4 @@ int SrsHttpConn::process_request(SrsSocket* skt)
return
ret
;
}
int
SrsHttpConn
::
on_message_begin
(
http_parser
*
parser
)
{
SrsHttpConn
*
obj
=
(
SrsHttpConn
*
)
parser
->
data
;
obj
->
req
->
state
=
SrsHttpParseStateStart
;
srs_info
(
"***MESSAGE BEGIN***"
);
return
0
;
}
int
SrsHttpConn
::
on_headers_complete
(
http_parser
*
parser
)
{
SrsHttpConn
*
obj
=
(
SrsHttpConn
*
)
parser
->
data
;
memcpy
(
&
obj
->
req
->
header
,
parser
,
sizeof
(
http_parser
));
srs_info
(
"***HEADERS COMPLETE***"
);
// see http_parser.c:1570, return 1 to skip body.
return
0
;
}
int
SrsHttpConn
::
on_message_complete
(
http_parser
*
parser
)
{
SrsHttpConn
*
obj
=
(
SrsHttpConn
*
)
parser
->
data
;
// save the parser when header parse completed.
obj
->
req
->
state
=
SrsHttpParseStateComplete
;
srs_info
(
"***MESSAGE COMPLETE***
\n
"
);
return
0
;
}
int
SrsHttpConn
::
on_url
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
)
{
SrsHttpConn
*
obj
=
(
SrsHttpConn
*
)
parser
->
data
;
if
(
length
>
0
)
{
obj
->
req
->
url
.
append
(
at
,
(
int
)
length
);
}
srs_info
(
"Method: %d, Url: %.*s"
,
parser
->
method
,
(
int
)
length
,
at
);
return
0
;
}
int
SrsHttpConn
::
on_header_field
(
http_parser
*
/*parser*/
,
const
char
*
at
,
size_t
length
)
{
srs_info
(
"Header field: %.*s"
,
(
int
)
length
,
at
);
return
0
;
}
int
SrsHttpConn
::
on_header_value
(
http_parser
*
/*parser*/
,
const
char
*
at
,
size_t
length
)
{
srs_info
(
"Header value: %.*s"
,
(
int
)
length
,
at
);
return
0
;
}
int
SrsHttpConn
::
on_body
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
)
{
SrsHttpConn
*
obj
=
(
SrsHttpConn
*
)
parser
->
data
;
if
(
length
>
0
)
{
obj
->
req
->
body
->
append
(
at
,
(
int
)
length
);
}
srs_info
(
"Body: %.*s"
,
(
int
)
length
,
at
);
return
0
;
}
#endif
...
...
trunk/src/app/srs_app_http_conn.hpp
查看文件 @
ec6d696
...
...
@@ -38,28 +38,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <http_parser.h>
class
SrsSocket
;
class
SrsHttpParser
;
class
SrsHttpMessage
;
class
SrsHttpConn
:
public
SrsConnection
{
private
:
SrsHttp
Message
*
req
;
SrsHttp
Parser
*
parser
;
public
:
SrsHttpConn
(
SrsServer
*
srs_server
,
st_netfd_t
client_stfd
);
virtual
~
SrsHttpConn
();
protected
:
virtual
int
do_cycle
();
private
:
virtual
int
parse_request
(
SrsSocket
*
skt
,
http_parser
*
parser
,
http_parser_settings
*
settings
);
virtual
int
process_request
(
SrsSocket
*
skt
);
private
:
static
int
on_message_begin
(
http_parser
*
parser
);
static
int
on_headers_complete
(
http_parser
*
parser
);
static
int
on_message_complete
(
http_parser
*
parser
);
static
int
on_url
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
);
static
int
on_header_field
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
);
static
int
on_header_value
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
);
static
int
on_body
(
http_parser
*
parser
,
const
char
*
at
,
size_t
length
);
virtual
int
process_request
(
SrsSocket
*
skt
,
SrsHttpMessage
*
req
);
};
#endif
...
...
trunk/src/app/srs_app_http_hooks.cpp
查看文件 @
ec6d696
...
...
@@ -45,17 +45,30 @@ SrsHttpClient::SrsHttpClient()
{
connected
=
false
;
stfd
=
NULL
;
parser
=
NULL
;
}
SrsHttpClient
::~
SrsHttpClient
()
{
disconnect
();
srs_freep
(
parser
);
}
int
SrsHttpClient
::
post
(
SrsHttpUri
*
uri
,
std
::
string
req
,
std
::
string
&
res
)
{
res
=
""
;
int
ret
=
ERROR_SUCCESS
;
if
(
!
parser
)
{
parser
=
new
SrsHttpParser
();
if
((
ret
=
parser
->
initialize
(
HTTP_RESPONSE
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"initialize parser failed. ret=%d"
,
ret
);
return
ret
;
}
}
if
((
ret
=
connect
(
uri
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"http connect server failed. ret=%d"
,
ret
);
return
ret
;
...
...
@@ -77,8 +90,7 @@ int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res)
SrsSocket
skt
(
stfd
);
std
::
string
data
=
ss
.
str
();
ssize_t
nwrite
;
if
((
ret
=
skt
.
write
(
data
.
c_str
(),
data
.
length
(),
&
nwrite
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
skt
.
write
(
data
.
c_str
(),
data
.
length
(),
NULL
))
!=
ERROR_SUCCESS
)
{
// disconnect when error.
disconnect
();
...
...
@@ -86,10 +98,19 @@ int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res)
return
ret
;
}
if
((
ret
=
parse_response
(
uri
,
&
skt
,
&
res
))
!=
ERROR_SUCCESS
)
{
SrsHttpMessage
*
msg
=
NULL
;
if
((
ret
=
parser
->
parse_message
(
&
skt
,
&
msg
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"parse http post response failed. ret=%d"
,
ret
);
return
ret
;
}
srs_assert
(
msg
);
srs_assert
(
msg
->
is_complete
());
// get response body.
if
(
msg
->
body_size
()
>
0
)
{
res
=
msg
->
body
();
}
srs_info
(
"parse http post response success."
);
return
ret
;
...
...
@@ -153,152 +174,6 @@ int SrsHttpClient::connect(SrsHttpUri* uri)
return
ret
;
}
int
SrsHttpClient
::
parse_response
(
SrsHttpUri
*
uri
,
SrsSocket
*
skt
,
std
::
string
*
response
)
{
int
ret
=
ERROR_SUCCESS
;
int
body_received
=
0
;
if
((
ret
=
parse_response_header
(
skt
,
response
,
body_received
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"parse response header failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
parse_response_body
(
uri
,
skt
,
response
,
body_received
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"parse response body failed. ret=%d"
,
ret
);
return
ret
;
}
srs_info
(
"url %s download, body size=%"
PRId64
,
uri
->
get_url
(),
http_header
.
content_length
);
return
ret
;
}
int
SrsHttpClient
::
parse_response_header
(
SrsSocket
*
skt
,
std
::
string
*
response
,
int
&
body_received
)
{
int
ret
=
ERROR_SUCCESS
;
http_parser_settings
settings
;
memset
(
&
settings
,
0
,
sizeof
(
settings
));
settings
.
on_headers_complete
=
on_headers_complete
;
http_parser
parser
;
http_parser_init
(
&
parser
,
HTTP_RESPONSE
);
// callback object ptr.
parser
.
data
=
(
void
*
)
this
;
// reset response header.
memset
(
&
http_header
,
0
,
sizeof
(
http_header
));
// parser header.
char
buf
[
SRS_HTTP_HEADER_BUFFER
];
for
(;;)
{
ssize_t
nread
;
if
((
ret
=
skt
->
read
(
buf
,
(
size_t
)
sizeof
(
buf
),
&
nread
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"read body from server failed. ret=%d"
,
ret
);
return
ret
;
}
ssize_t
nparsed
=
http_parser_execute
(
&
parser
,
&
settings
,
buf
,
nread
);
srs_info
(
"read_size=%d, nparsed=%d"
,
(
int
)
nread
,
(
int
)
nparsed
);
// check header size.
if
(
http_header
.
nread
!=
0
)
{
body_received
=
nread
-
nparsed
;
srs_info
(
"http header parsed, size=%d, content-length=%"
PRId64
", body-received=%d"
,
http_header
.
nread
,
http_header
.
content_length
,
body_received
);
if
(
response
!=
NULL
&&
body_received
>
0
){
response
->
append
(
buf
+
nparsed
,
body_received
);
}
return
ret
;
}
if
(
nparsed
!=
nread
)
{
ret
=
ERROR_HTTP_PARSE_HEADER
;
srs_error
(
"parse response error, parsed(%d)!=read(%d), ret=%d"
,
(
int
)
nparsed
,
(
int
)
nread
,
ret
);
return
ret
;
}
}
return
ret
;
}
int
SrsHttpClient
::
parse_response_body
(
SrsHttpUri
*
uri
,
SrsSocket
*
skt
,
std
::
string
*
response
,
int
body_received
)
{
int
ret
=
ERROR_SUCCESS
;
srs_assert
(
uri
!=
NULL
);
uint64_t
body_left
=
http_header
.
content_length
-
body_received
;
if
(
body_left
<=
0
)
{
return
ret
;
}
if
(
response
!=
NULL
)
{
char
buf
[
SRS_HTTP_BODY_BUFFER
];
return
parse_response_body_data
(
uri
,
skt
,
response
,
(
size_t
)
body_left
,
(
const
void
*
)
buf
,
(
size_t
)
SRS_HTTP_BODY_BUFFER
);
}
else
{
// if ignore response, use shared fast memory.
static
char
buf
[
SRS_HTTP_BODY_BUFFER
];
return
parse_response_body_data
(
uri
,
skt
,
response
,
(
size_t
)
body_left
,
(
const
void
*
)
buf
,
(
size_t
)
SRS_HTTP_BODY_BUFFER
);
}
return
ret
;
}
int
SrsHttpClient
::
parse_response_body_data
(
SrsHttpUri
*
uri
,
SrsSocket
*
skt
,
std
::
string
*
response
,
size_t
body_left
,
const
void
*
buf
,
size_t
size
)
{
int
ret
=
ERROR_SUCCESS
;
srs_assert
(
uri
!=
NULL
);
while
(
body_left
>
0
)
{
ssize_t
nread
;
int
size_to_read
=
srs_min
(
size
,
body_left
);
if
((
ret
=
skt
->
read
(
buf
,
size_to_read
,
&
nread
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"read header from server failed. ret=%d"
,
ret
);
return
ret
;
}
if
(
response
!=
NULL
&&
nread
>
0
)
{
response
->
append
((
char
*
)
buf
,
nread
);
}
body_left
-=
nread
;
srs_info
(
"read url(%s) content partial %"
PRId64
"/%"
PRId64
""
,
uri
->
get_url
(),
http_header
.
content_length
-
body_left
,
http_header
.
content_length
);
}
return
ret
;
}
int
SrsHttpClient
::
on_headers_complete
(
http_parser
*
parser
)
{
SrsHttpClient
*
obj
=
(
SrsHttpClient
*
)
parser
->
data
;
obj
->
complete_header
(
parser
);
// see http_parser.c:1570, return 1 to skip body.
return
1
;
}
void
SrsHttpClient
::
complete_header
(
http_parser
*
parser
)
{
// save the parser status when header parse completed.
memcpy
(
&
http_header
,
parser
,
sizeof
(
http_header
));
}
SrsHttpHooks
::
SrsHttpHooks
()
{
}
...
...
trunk/src/app/srs_app_http_hooks.hpp
查看文件 @
ec6d696
...
...
@@ -36,6 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class
SrsHttpUri
;
class
SrsSocket
;
class
SrsRequest
;
class
SrsHttpParser
;
#include <srs_app_st.hpp>
...
...
@@ -47,8 +48,7 @@ class SrsHttpClient
private
:
bool
connected
;
st_netfd_t
stfd
;
private
:
http_parser
http_header
;
SrsHttpParser
*
parser
;
public
:
SrsHttpClient
();
virtual
~
SrsHttpClient
();
...
...
@@ -62,14 +62,6 @@ public:
private
:
virtual
void
disconnect
();
virtual
int
connect
(
SrsHttpUri
*
uri
);
private
:
virtual
int
parse_response
(
SrsHttpUri
*
uri
,
SrsSocket
*
skt
,
std
::
string
*
response
);
virtual
int
parse_response_header
(
SrsSocket
*
skt
,
std
::
string
*
response
,
int
&
body_received
);
virtual
int
parse_response_body
(
SrsHttpUri
*
uri
,
SrsSocket
*
skt
,
std
::
string
*
response
,
int
body_received
);
virtual
int
parse_response_body_data
(
SrsHttpUri
*
uri
,
SrsSocket
*
skt
,
std
::
string
*
response
,
size_t
body_left
,
const
void
*
buf
,
size_t
size
);
private
:
static
int
on_headers_complete
(
http_parser
*
parser
);
virtual
void
complete_header
(
http_parser
*
parser
);
};
/**
...
...
请
注册
或
登录
后发表评论