mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
refine http
This commit is contained in:
parent
6fccfa061d
commit
4325809daf
9 changed files with 190 additions and 16 deletions
|
@ -904,6 +904,7 @@ int SrsHttpResponseReader::read(int max, std::string& data)
|
|||
|
||||
SrsHttpMessage::SrsHttpMessage(SrsStSocket* io)
|
||||
{
|
||||
chunked = false;
|
||||
_uri = new SrsHttpUri();
|
||||
_body = new SrsHttpResponseReader(this, io);
|
||||
_http_ts_send_buffer = new char[__SRS_HTTP_TS_SEND_BUFFER_SIZE];
|
||||
|
@ -924,6 +925,11 @@ int SrsHttpMessage::initialize(string url, http_parser* header, string body, vec
|
|||
_header = *header;
|
||||
_headers = headers;
|
||||
|
||||
// whether chunked.
|
||||
std::string transfer_encoding = get_request_header("Transfer-Encoding");
|
||||
chunked = (transfer_encoding == "chunked");
|
||||
|
||||
// TODO: FIXME: remove it, use fast buffer instead.
|
||||
if (!body.empty()) {
|
||||
_body->append((char*)body.data(), (int)body.length());
|
||||
}
|
||||
|
@ -1031,6 +1037,11 @@ bool SrsHttpMessage::is_http_options()
|
|||
return _header.method == SRS_CONSTS_HTTP_OPTIONS;
|
||||
}
|
||||
|
||||
bool SrsHttpMessage::is_chunked()
|
||||
{
|
||||
return chunked;
|
||||
}
|
||||
|
||||
string SrsHttpMessage::uri()
|
||||
{
|
||||
std::string uri = _uri->get_schema();
|
||||
|
@ -1104,6 +1115,11 @@ int SrsHttpMessage::body_read_all(string body)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ISrsHttpResponseReader* SrsHttpMessage::body_reader()
|
||||
{
|
||||
return _body;
|
||||
}
|
||||
|
||||
int64_t SrsHttpMessage::content_length()
|
||||
{
|
||||
return _header.content_length;
|
||||
|
@ -1258,6 +1274,11 @@ int SrsHttpParser::parse_message_imp(SrsStSocket* skt)
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// parse last header.
|
||||
if (!filed_name.empty() && !field_value.empty()) {
|
||||
headers.push_back(std::make_pair(filed_name, field_value));
|
||||
}
|
||||
|
||||
// when parse completed, cache the left body.
|
||||
if (nread && nparsed < nread) {
|
||||
|
@ -1341,7 +1362,7 @@ int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t l
|
|||
obj->filed_name.append(at, (int)length);
|
||||
}
|
||||
|
||||
srs_trace("Header field(%d bytes): %.*s", (int)length, (int)length, at);
|
||||
srs_info("Header field(%d bytes): %.*s", (int)length, (int)length, at);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1355,7 +1376,7 @@ int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t l
|
|||
}
|
||||
obj->expect_filed_name = false;
|
||||
|
||||
srs_trace("Header value(%d bytes): %.*s", (int)length, (int)length, at);
|
||||
srs_info("Header value(%d bytes): %.*s", (int)length, (int)length, at);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ class SrsFileReader;
|
|||
class SrsSimpleBuffer;
|
||||
class SrsHttpMuxEntry;
|
||||
class ISrsHttpResponseWriter;
|
||||
class SrsFastBuffer;
|
||||
|
||||
// http specification
|
||||
// CR = <US-ASCII CR, carriage return (13)>
|
||||
|
@ -442,6 +443,10 @@ private:
|
|||
*/
|
||||
SrsHttpResponseReader* _body;
|
||||
/**
|
||||
* whether the body is chunked.
|
||||
*/
|
||||
bool chunked;
|
||||
/**
|
||||
* uri parser
|
||||
*/
|
||||
SrsHttpUri* _uri;
|
||||
|
@ -474,12 +479,14 @@ public:
|
|||
virtual bool is_http_post();
|
||||
virtual bool is_http_delete();
|
||||
virtual bool is_http_options();
|
||||
virtual bool is_chunked();
|
||||
virtual std::string uri();
|
||||
virtual std::string url();
|
||||
virtual std::string host();
|
||||
virtual std::string path();
|
||||
public:
|
||||
virtual int body_read_all(std::string body);
|
||||
virtual ISrsHttpResponseReader* body_reader();
|
||||
virtual int64_t content_length();
|
||||
/**
|
||||
* get the param in query string,
|
||||
|
@ -502,6 +509,8 @@ class SrsHttpParser
|
|||
private:
|
||||
http_parser_settings settings;
|
||||
http_parser parser;
|
||||
// the global parse buffer.
|
||||
SrsFastBuffer* fbuffer;
|
||||
private:
|
||||
// http parse data, reset before parse message.
|
||||
bool expect_filed_name;
|
||||
|
|
|
@ -45,6 +45,7 @@ SrsHttpClient::SrsHttpClient()
|
|||
connected = false;
|
||||
stfd = NULL;
|
||||
parser = NULL;
|
||||
skt = NULL;
|
||||
}
|
||||
|
||||
SrsHttpClient::~SrsHttpClient()
|
||||
|
@ -86,10 +87,8 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r
|
|||
<< __SRS_HTTP_CRLF
|
||||
<< req;
|
||||
|
||||
SrsStSocket skt(stfd);
|
||||
|
||||
std::string data = ss.str();
|
||||
if ((ret = skt.write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) {
|
||||
if ((ret = skt->write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) {
|
||||
// disconnect when error.
|
||||
disconnect();
|
||||
|
||||
|
@ -98,7 +97,7 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r
|
|||
}
|
||||
|
||||
SrsHttpMessage* msg = NULL;
|
||||
if ((ret = parser->parse_message(&skt, &msg)) != ERROR_SUCCESS) {
|
||||
if ((ret = parser->parse_message(skt, &msg)) != ERROR_SUCCESS) {
|
||||
srs_error("parse http post response failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -119,11 +118,67 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsHttpClient::get(SrsHttpUri* uri, std::string req, SrsHttpMessage** ppmsg)
|
||||
{
|
||||
*ppmsg = NULL;
|
||||
|
||||
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_warn("http connect server failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// send POST request to uri
|
||||
// GET %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s
|
||||
std::stringstream ss;
|
||||
ss << "GET " << uri->get_path() << " "
|
||||
<< "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;
|
||||
|
||||
std::string data = ss.str();
|
||||
if ((ret = skt->write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) {
|
||||
// disconnect when error.
|
||||
disconnect();
|
||||
|
||||
srs_error("write http get failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
*ppmsg = msg;
|
||||
srs_info("parse http get response success.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SrsHttpClient::disconnect()
|
||||
{
|
||||
connected = false;
|
||||
|
||||
srs_close_stfd(stfd);
|
||||
srs_freep(skt);
|
||||
}
|
||||
|
||||
int SrsHttpClient::connect(SrsHttpUri* uri)
|
||||
|
@ -149,6 +204,8 @@ int SrsHttpClient::connect(SrsHttpUri* uri)
|
|||
srs_info("connect to server success. http url=%s, server=%s, port=%d",
|
||||
uri->get_url(), uri->get_host(), uri->get_port());
|
||||
|
||||
srs_assert(!skt);
|
||||
skt = new SrsStSocket(stfd);
|
||||
connected = true;
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -37,6 +37,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
class SrsHttpUri;
|
||||
class SrsHttpParser;
|
||||
class SrsHttpMessage;
|
||||
class SrsStSocket;
|
||||
|
||||
/**
|
||||
* http client to GET/POST/PUT/DELETE uri
|
||||
|
@ -46,6 +48,7 @@ class SrsHttpClient
|
|||
private:
|
||||
bool connected;
|
||||
st_netfd_t stfd;
|
||||
SrsStSocket* skt;
|
||||
SrsHttpParser* parser;
|
||||
public:
|
||||
SrsHttpClient();
|
||||
|
@ -53,11 +56,17 @@ public:
|
|||
public:
|
||||
/**
|
||||
* to post data to the uri.
|
||||
* @param req the data post to uri.
|
||||
* @param req the data post to uri. empty string to ignore.
|
||||
* @param status_code the output status code response by server.
|
||||
* @param res output the response data from server.
|
||||
*/
|
||||
virtual int post(SrsHttpUri* uri, std::string req, int& status_code, std::string& res);
|
||||
/**
|
||||
* to get data from the uri.
|
||||
* @param req the data post to uri. empty string to ignore.
|
||||
* @param ppmsg output the http message to read the response.
|
||||
*/
|
||||
virtual int get(SrsHttpUri* uri, std::string req, SrsHttpMessage** ppmsg);
|
||||
private:
|
||||
virtual void disconnect();
|
||||
virtual int connect(SrsHttpUri* uri);
|
||||
|
|
|
@ -131,7 +131,7 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
|
|||
|
||||
SrsRtspAudioCache::SrsRtspAudioCache()
|
||||
{
|
||||
dts = NULL;
|
||||
dts = 0;
|
||||
audio_samples = NULL;
|
||||
payload = NULL;
|
||||
}
|
||||
|
|
|
@ -312,6 +312,8 @@ int run()
|
|||
return run_master();
|
||||
}
|
||||
|
||||
#include <srs_app_http.hpp>
|
||||
#include <srs_app_http_client.hpp>
|
||||
int run_master()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
@ -327,6 +329,22 @@ int run_master()
|
|||
if ((ret = _srs_server->initialize_st()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
/*SrsHttpClient client;
|
||||
SrsHttpUri uri;
|
||||
if ((ret = uri.initialize("http://ossrs.net:8081/live/livestream.flv")) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
SrsHttpMessage* msg = NULL;
|
||||
if ((ret = client.get(&uri, "", &msg)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
for (;;) {
|
||||
ISrsHttpResponseReader* br = msg->body_reader();
|
||||
std::string data;
|
||||
if ((ret = br->read(0, data)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}*/
|
||||
|
||||
if ((ret = _srs_server->listen()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
|
|
|
@ -130,6 +130,7 @@ public:
|
|||
* @param v true to ename merged read.
|
||||
* @param handler the handler when merge read is enabled.
|
||||
* @see https://github.com/winlinvip/simple-rtmp-server/issues/241
|
||||
* @remark the merged read is optional, ignore if not specifies.
|
||||
*/
|
||||
virtual void set_merge_read(bool v, IMergeReadHandler* handler);
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue