mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
fix the http read chunked encoding bug.
This commit is contained in:
parent
a95fd6d140
commit
ea1e015a4e
7 changed files with 104 additions and 34 deletions
|
@ -37,6 +37,8 @@ using namespace std;
|
|||
#include <srs_app_http_conn.hpp>
|
||||
#include <srs_core_autofree.hpp>
|
||||
|
||||
#define SRS_HTTP_FLV_STREAM_BUFFER 4096
|
||||
|
||||
SrsAppCasterFlv::SrsAppCasterFlv(SrsConfDirective* c)
|
||||
{
|
||||
http_mux = new SrsHttpServeMux();
|
||||
|
@ -62,7 +64,7 @@ int SrsAppCasterFlv::on_tcp_client(st_netfd_t stfd)
|
|||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
SrsHttpConn* conn = new SrsHttpConn(this, stfd, http_mux);
|
||||
SrsHttpConn* conn = new SrsDynamicHttpConn(this, stfd, http_mux);
|
||||
conns.push_back(conn);
|
||||
|
||||
if ((ret = conn->start()) != ERROR_SUCCESS) {
|
||||
|
@ -79,7 +81,7 @@ void SrsAppCasterFlv::remove(SrsConnection* c)
|
|||
conns.erase(it);
|
||||
}
|
||||
}
|
||||
#define SRS_HTTP_FLV_STREAM_BUFFER 4096
|
||||
|
||||
int SrsAppCasterFlv::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
@ -95,10 +97,25 @@ int SrsAppCasterFlv::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
|||
if ((ret = rr->read(buffer, SRS_HTTP_FLV_STREAM_BUFFER, &nb_read)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
srs_trace("flv: read %dB from %s", nb_read, r->path().c_str());
|
||||
//srs_trace("flv: read %dB from %s", nb_read, r->path().c_str());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SrsDynamicHttpConn::SrsDynamicHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m)
|
||||
: SrsHttpConn(cm, fd, m)
|
||||
{
|
||||
}
|
||||
|
||||
SrsDynamicHttpConn::~SrsDynamicHttpConn()
|
||||
{
|
||||
}
|
||||
|
||||
int SrsDynamicHttpConn::on_got_http_message(SrsHttpMessage* msg)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,7 @@ class SrsHttpConn;
|
|||
#include <srs_app_listener.hpp>
|
||||
#include <srs_app_conn.hpp>
|
||||
#include <srs_app_http.hpp>
|
||||
#include <srs_app_http_conn.hpp>
|
||||
|
||||
class SrsAppCasterFlv : virtual public ISrsTcpHandler
|
||||
, virtual public IConnectionManager, virtual public ISrsHttpHandler
|
||||
|
@ -67,6 +68,15 @@ public:
|
|||
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||
};
|
||||
|
||||
class SrsDynamicHttpConn : public SrsHttpConn
|
||||
{
|
||||
public:
|
||||
SrsDynamicHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m);
|
||||
virtual ~SrsDynamicHttpConn();
|
||||
public:
|
||||
virtual int on_got_http_message(SrsHttpMessage* msg);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -905,6 +905,7 @@ int SrsHttpResponseReader::initialize(SrsFastBuffer* body)
|
|||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
nb_chunk = 0;
|
||||
nb_left_chunk = 0;
|
||||
nb_total_read = 0;
|
||||
buffer = body;
|
||||
|
@ -999,33 +1000,35 @@ int SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb_read)
|
|||
}
|
||||
|
||||
// all bytes in chunk is left now.
|
||||
nb_left_chunk = ilength;
|
||||
nb_chunk = nb_left_chunk = ilength;
|
||||
}
|
||||
|
||||
// left bytes in chunk, read some.
|
||||
srs_assert(nb_left_chunk);
|
||||
|
||||
int nb_bytes = srs_min(nb_left_chunk, nb_data);
|
||||
ret = read_specified(data, nb_bytes, &nb_bytes);
|
||||
|
||||
// the nb_bytes used for output already read size of bytes.
|
||||
if (nb_read) {
|
||||
*nb_read = nb_bytes;
|
||||
}
|
||||
nb_left_chunk -= nb_bytes;
|
||||
|
||||
// error or still left bytes in chunk, ignore and read in future.
|
||||
if (nb_left_chunk > 0 || (ret != ERROR_SUCCESS)) {
|
||||
return ret;
|
||||
}
|
||||
srs_info("http: read %d bytes of chunk", nb_bytes);
|
||||
|
||||
// read payload when length specifies some payload.
|
||||
if (nb_left_chunk <= 0) {
|
||||
if (nb_chunk <= 0) {
|
||||
// for the last chunk, eof.
|
||||
is_eof = true;
|
||||
} else {
|
||||
// for not the last chunk, there must always exists bytes.
|
||||
// left bytes in chunk, read some.
|
||||
srs_assert(nb_left_chunk);
|
||||
|
||||
int nb_bytes = srs_min(nb_left_chunk, nb_data);
|
||||
ret = read_specified(data, nb_bytes, &nb_bytes);
|
||||
|
||||
// the nb_bytes used for output already read size of bytes.
|
||||
if (nb_read) {
|
||||
*nb_read = nb_bytes;
|
||||
}
|
||||
nb_left_chunk -= nb_bytes;
|
||||
srs_info("http: read %d bytes of chunk", nb_bytes);
|
||||
|
||||
// error or still left bytes in chunk, ignore and read in future.
|
||||
if (nb_left_chunk > 0 || (ret != ERROR_SUCCESS)) {
|
||||
return ret;
|
||||
}
|
||||
srs_info("http: read total chunk %dB", nb_chunk);
|
||||
}
|
||||
|
||||
// the CRLF of chunk payload end.
|
||||
// for both the last or not, the CRLF of chunk payload end.
|
||||
if ((ret = buffer->grow(skt, 2)) != ERROR_SUCCESS) {
|
||||
if (!srs_is_client_gracefully_close(ret)) {
|
||||
srs_error("read EOF of chunk from server failed. ret=%d", ret);
|
||||
|
@ -1064,9 +1067,12 @@ int SrsHttpResponseReader::read_specified(char* data, int nb_data, int* nb_read)
|
|||
// increase the total read to determine whether EOF.
|
||||
nb_total_read += nb_bytes;
|
||||
|
||||
// when read completed, eof.
|
||||
if (nb_total_read >= (int)owner->content_length()) {
|
||||
is_eof = true;
|
||||
// for not chunked
|
||||
if (!owner->is_chunked()) {
|
||||
// when read completed, eof.
|
||||
if (nb_total_read >= (int)owner->content_length()) {
|
||||
is_eof = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -436,6 +436,8 @@ private:
|
|||
bool is_eof;
|
||||
// the left bytes in chunk.
|
||||
int nb_left_chunk;
|
||||
// the number of bytes of current chunk.
|
||||
int nb_chunk;
|
||||
// already read total bytes.
|
||||
int64_t nb_total_read;
|
||||
public:
|
||||
|
|
|
@ -1398,11 +1398,8 @@ int SrsHttpConn::do_cycle()
|
|||
// always free it in this scope.
|
||||
SrsAutoFree(SrsHttpMessage, req);
|
||||
|
||||
// TODO: FIXME: use the post body.
|
||||
std::string res;
|
||||
|
||||
// get response body.
|
||||
if ((ret = req->body_read_all(res)) != ERROR_SUCCESS) {
|
||||
// may should discard the body.
|
||||
if ((ret = on_got_http_message(req)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1434,5 +1431,29 @@ int SrsHttpConn::process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
|||
return ret;
|
||||
}
|
||||
|
||||
SrsStaticHttpConn::SrsStaticHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m)
|
||||
: SrsHttpConn(cm, fd, m)
|
||||
{
|
||||
}
|
||||
|
||||
SrsStaticHttpConn::~SrsStaticHttpConn()
|
||||
{
|
||||
}
|
||||
|
||||
int SrsStaticHttpConn::on_got_http_message(SrsHttpMessage* msg)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// TODO: FIXME: use the post body.
|
||||
std::string res;
|
||||
|
||||
// get response body.
|
||||
if ((ret = msg->body_read_all(res)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -388,10 +388,24 @@ public:
|
|||
virtual void cleanup();
|
||||
protected:
|
||||
virtual int do_cycle();
|
||||
protected:
|
||||
// when got http message,
|
||||
// for the static service or api, discard any body.
|
||||
// for the stream caster, for instance, http flv streaming, may discard the flv header or not.
|
||||
virtual int on_got_http_message(SrsHttpMessage* msg) = 0;
|
||||
private:
|
||||
virtual int process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||
};
|
||||
|
||||
class SrsStaticHttpConn : public SrsHttpConn
|
||||
{
|
||||
public:
|
||||
SrsStaticHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m);
|
||||
virtual ~SrsStaticHttpConn();
|
||||
public:
|
||||
virtual int on_got_http_message(SrsHttpMessage* msg);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1163,7 +1163,7 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
|
|||
#endif
|
||||
} else if (type == SrsListenerHttpStream) {
|
||||
#ifdef SRS_AUTO_HTTP_SERVER
|
||||
conn = new SrsHttpConn(this, client_stfd, &http_stream_mux->mux);
|
||||
conn = new SrsStaticHttpConn(this, client_stfd, &http_stream_mux->mux);
|
||||
#else
|
||||
srs_warn("close http client for server not support http-server");
|
||||
srs_close_stfd(client_stfd);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue