fix the http read chunked encoding bug.

pull/133/head
winlin 10 years ago
parent a95fd6d140
commit ea1e015a4e

@ -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…
Cancel
Save