1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

RTC: Fix the OPTIONS read, no infinited chunked mode

This commit is contained in:
winlin 2020-07-02 12:41:08 +08:00
parent a273298e63
commit 9ff8bff601
3 changed files with 76 additions and 0 deletions

View file

@ -334,6 +334,12 @@ void SrsHttpMessage::set_header(SrsHttpHeader* header, bool keep_alive)
if (!clv.empty()) {
_content_length = ::atoll(clv.c_str());
}
// If method is OPTIONS, and no size(content-length or chunked), it's not infinite chunked,
// it means there is no body, so we must close the body reader.
if (_method == SRS_CONSTS_HTTP_OPTIONS && !chunked && _content_length == -1) {
_body->close();
}
}
srs_error_t SrsHttpMessage::set_url(string url, bool allow_jsonp)
@ -921,6 +927,11 @@ SrsHttpResponseReader::~SrsHttpResponseReader()
{
}
void SrsHttpResponseReader::close()
{
is_eof = true;
}
bool SrsHttpResponseReader::eof()
{
return is_eof;

View file

@ -264,6 +264,11 @@ public:
// while buffer is a fast cache which may have cached some data from reader.
SrsHttpResponseReader(SrsHttpMessage* msg, ISrsReader* reader, SrsFastStream* buffer);
virtual ~SrsHttpResponseReader();
public:
// User close the HTTP response reader.
// For example, OPTIONS has no body, no content-length and not chunked,
// so we must close it(set to eof) to avoid reading the response body.
void close();
// Interface ISrsHttpResponseReader
public:
virtual bool eof();

View file

@ -678,6 +678,7 @@ VOID TEST(HTTPServerTest, InfiniteChunked)
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_RESPONSE, false));
ISrsHttpMessage* msg = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &msg));
SrsAutoFree(ISrsHttpMessage, msg);
char buf[32]; ssize_t nread = 0;
ISrsHttpResponseReader* r = msg->body_reader();
@ -696,6 +697,65 @@ VOID TEST(HTTPServerTest, InfiniteChunked)
}
}
VOID TEST(HTTPServerTest, OPTIONSRead)
{
srs_error_t err;
// If OPTIONS, it has no content-length, not chunkted, but not infinite chunked,
// instead, it has no body.
if (true) {
MockBufferIO io;
io.append("OPTIONS /rtc/v1/play HTTP/1.1\r\n\r\n");
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST, false));
ISrsHttpMessage* req = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &req));
SrsAutoFree(ISrsHttpMessage, req);
ISrsHttpResponseReader* br = req->body_reader();
EXPECT_TRUE(br->eof());
}
// So if OPTIONS has body, with chunked or content-length, it's ok to parsing it.
if (true) {
MockBufferIO io;
io.append("OPTIONS /rtc/v1/play HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello");
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST, false));
ISrsHttpMessage* req = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &req));
SrsAutoFree(ISrsHttpMessage, req);
ISrsHttpResponseReader* br = req->body_reader();
EXPECT_FALSE(br->eof());
string b; HELPER_ASSERT_SUCCESS(req->body_read_all(b));
EXPECT_STREQ("Hello", b.c_str());
// The body will use as next HTTP request message.
io.append("GET /rtc/v1/play HTTP/1.1\r\n\r\n");
ISrsHttpMessage* req2 = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &req2));
SrsAutoFree(ISrsHttpMessage, req2);
}
// So if OPTIONS has body, but not specified the size, we think it has no body,
// and the body is parsed fail as the next parsing.
if (true) {
MockBufferIO io;
io.append("OPTIONS /rtc/v1/play HTTP/1.1\r\n\r\n");
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_REQUEST, false));
ISrsHttpMessage* req = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &req));
SrsAutoFree(ISrsHttpMessage, req);
ISrsHttpResponseReader* br = req->body_reader();
EXPECT_TRUE(br->eof());
// The body will use as next HTTP request message.
io.append("Hello");
ISrsHttpMessage* req2 = NULL; HELPER_ASSERT_FAILED(hp.parse_message(&io, &req2));
SrsAutoFree(ISrsHttpMessage, req2);
}
}
VOID TEST(HTTPServerTest, MessageWritev)
{
srs_error_t err;