mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Refactor HttpResponseWriter.write, default to single text mode.
This commit is contained in:
parent
8cdb7cc727
commit
d9842b0371
6 changed files with 96 additions and 24 deletions
|
@ -117,6 +117,7 @@ srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
|
||||||
// write http header for ts.
|
// write http header for ts.
|
||||||
w->header()->set_content_length((int)(sizeof(flv_header) + sh_size + left));
|
w->header()->set_content_length((int)(sizeof(flv_header) + sh_size + left));
|
||||||
w->header()->set_content_type("video/x-flv");
|
w->header()->set_content_type("video/x-flv");
|
||||||
|
w->write_header(SRS_CONSTS_HTTP_OK);
|
||||||
|
|
||||||
// write flv header and sequence header.
|
// write flv header and sequence header.
|
||||||
if ((err = w->write(flv_header, sizeof(flv_header))) != srs_success) {
|
if ((err = w->write(flv_header, sizeof(flv_header))) != srs_success) {
|
||||||
|
@ -170,8 +171,6 @@ srs_error_t SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
|
||||||
// write http header for ts.
|
// write http header for ts.
|
||||||
w->header()->set_content_length(left);
|
w->header()->set_content_length(left);
|
||||||
w->header()->set_content_type("video/mp4");
|
w->header()->set_content_type("video/mp4");
|
||||||
|
|
||||||
// status code 206 to make dash.as happy.
|
|
||||||
w->write_header(SRS_CONSTS_HTTP_PartialContent);
|
w->write_header(SRS_CONSTS_HTTP_PartialContent);
|
||||||
|
|
||||||
// response the content range header.
|
// response the content range header.
|
||||||
|
|
|
@ -541,6 +541,9 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess
|
||||||
}
|
}
|
||||||
SrsAutoFree(ISrsBufferEncoder, enc);
|
SrsAutoFree(ISrsBufferEncoder, enc);
|
||||||
|
|
||||||
|
// Enter chunked mode, because we didn't set the content-length.
|
||||||
|
w->write_header(SRS_CONSTS_HTTP_OK);
|
||||||
|
|
||||||
// create consumer of souce, ignore gop cache, use the audio gop cache.
|
// create consumer of souce, ignore gop cache, use the audio gop cache.
|
||||||
SrsConsumer* consumer = NULL;
|
SrsConsumer* consumer = NULL;
|
||||||
if ((err = source->create_consumer(NULL, consumer, true, true, !enc->has_cache())) != srs_success) {
|
if ((err = source->create_consumer(NULL, consumer, true, true, !enc->has_cache())) != srs_success) {
|
||||||
|
|
|
@ -447,6 +447,9 @@ srs_error_t SrsHttpFileServer::serve_file(ISrsHttpResponseWriter* w, ISrsHttpMes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enter chunked mode, because we didn't set the content-length.
|
||||||
|
w->write_header(SRS_CONSTS_HTTP_OK);
|
||||||
|
|
||||||
// write body.
|
// write body.
|
||||||
int64_t left = length;
|
int64_t left = length;
|
||||||
if ((err = copy(w, fs, r, (int)left)) != srs_success) {
|
if ((err = copy(w, fs, r, (int)left)) != srs_success) {
|
||||||
|
|
|
@ -150,7 +150,11 @@ public:
|
||||||
|
|
||||||
// A ResponseWriter interface is used by an HTTP handler to
|
// A ResponseWriter interface is used by an HTTP handler to
|
||||||
// construct an HTTP response.
|
// construct an HTTP response.
|
||||||
// Usage 1, response with specified length content:
|
// Usage 0, response with a message once:
|
||||||
|
// ISrsHttpResponseWriter* w; // create or get response.
|
||||||
|
// std::string msg = "Hello, HTTP!";
|
||||||
|
// w->write((char*)msg.data(), (int)msg.length());
|
||||||
|
// Usage 1, response with specified length content, same to #0:
|
||||||
// ISrsHttpResponseWriter* w; // create or get response.
|
// ISrsHttpResponseWriter* w; // create or get response.
|
||||||
// std::string msg = "Hello, HTTP!";
|
// std::string msg = "Hello, HTTP!";
|
||||||
// w->header()->set_content_type("text/plain; charset=utf-8");
|
// w->header()->set_content_type("text/plain; charset=utf-8");
|
||||||
|
|
|
@ -647,6 +647,10 @@ srs_error_t SrsHttpResponseWriter::write(char* data, int size)
|
||||||
|
|
||||||
// write the header data in memory.
|
// write the header data in memory.
|
||||||
if (!header_wrote) {
|
if (!header_wrote) {
|
||||||
|
if (hdr->content_type().empty()) {
|
||||||
|
hdr->set_content_type("text/plain; charset=utf-8");
|
||||||
|
}
|
||||||
|
hdr->set_content_length(size);
|
||||||
write_header(SRS_CONSTS_HTTP_OK);
|
write_header(SRS_CONSTS_HTTP_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,47 @@ string mock_http_response(int status, string content)
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MockFileReaderFactory : public ISrsFileReaderFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
string bytes;
|
||||||
|
MockFileReaderFactory(string data) {
|
||||||
|
bytes = data;
|
||||||
|
}
|
||||||
|
virtual ~MockFileReaderFactory() {
|
||||||
|
}
|
||||||
|
virtual SrsFileReader* create_file_reader() {
|
||||||
|
return new MockSrsFileReader((const char*)bytes.data(), (int)bytes.length());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MockHttpHandler : public ISrsHttpHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
string bytes;
|
||||||
|
MockHttpHandler(string data) {
|
||||||
|
bytes = data;
|
||||||
|
}
|
||||||
|
virtual ~MockHttpHandler() {
|
||||||
|
}
|
||||||
|
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* /*r*/) {
|
||||||
|
return w->write((char*)bytes.data(), (int)bytes.length());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool _mock_srs_path_always_exists(std::string /*path*/)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _mock_srs_path_not_exists(std::string /*path*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __MOCK_HTTP_EXPECT_STREQ(status, text, w) \
|
||||||
|
EXPECT_STREQ(mock_http_response(status, text).c_str(), HELPER_BUFFER2STR(&w.io.out_buffer).c_str())
|
||||||
|
|
||||||
VOID TEST(ProtocolHTTPTest, StatusCode2Text)
|
VOID TEST(ProtocolHTTPTest, StatusCode2Text)
|
||||||
{
|
{
|
||||||
EXPECT_STREQ(SRS_CONSTS_HTTP_OK_str, srs_generate_http_status_text(SRS_CONSTS_HTTP_OK).c_str());
|
EXPECT_STREQ(SRS_CONSTS_HTTP_OK_str, srs_generate_http_status_text(SRS_CONSTS_HTTP_OK).c_str());
|
||||||
|
@ -123,10 +164,20 @@ VOID TEST(ProtocolHTTPTest, StatusCode2Text)
|
||||||
VOID TEST(ProtocolHTTPTest, ResponseDetect)
|
VOID TEST(ProtocolHTTPTest, ResponseDetect)
|
||||||
{
|
{
|
||||||
EXPECT_STREQ("application/octet-stream", srs_go_http_detect(NULL, 0).c_str());
|
EXPECT_STREQ("application/octet-stream", srs_go_http_detect(NULL, 0).c_str());
|
||||||
|
EXPECT_STREQ("application/octet-stream", srs_go_http_detect((char*)"Hello, world!", 0).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __MOCK_HTTP_EXPECT_STREQ(status, text, w) \
|
VOID TEST(ProtocolHTTPTest, ResponseWriter)
|
||||||
EXPECT_STREQ(mock_http_response(status, text).c_str(), HELPER_BUFFER2STR(&w.io.out_buffer).c_str())
|
{
|
||||||
|
if (true) {
|
||||||
|
MockResponseWriter w;
|
||||||
|
|
||||||
|
char msg[] = "Hello, world!";
|
||||||
|
w.write((char*)msg, sizeof(msg) - 1);
|
||||||
|
|
||||||
|
__MOCK_HTTP_EXPECT_STREQ(200, "Hello, world!", w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID TEST(ProtocolHTTPTest, ResponseHTTPError)
|
VOID TEST(ProtocolHTTPTest, ResponseHTTPError)
|
||||||
{
|
{
|
||||||
|
@ -137,6 +188,18 @@ VOID TEST(ProtocolHTTPTest, ResponseHTTPError)
|
||||||
HELPER_EXPECT_SUCCESS(srs_go_http_error(&w, SRS_CONSTS_HTTP_Found));
|
HELPER_EXPECT_SUCCESS(srs_go_http_error(&w, SRS_CONSTS_HTTP_Found));
|
||||||
__MOCK_HTTP_EXPECT_STREQ(302, "Found", w);
|
__MOCK_HTTP_EXPECT_STREQ(302, "Found", w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockResponseWriter w;
|
||||||
|
HELPER_EXPECT_SUCCESS(srs_go_http_error(&w, SRS_CONSTS_HTTP_InternalServerError));
|
||||||
|
__MOCK_HTTP_EXPECT_STREQ(500, "Internal Server Error", w);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockResponseWriter w;
|
||||||
|
HELPER_EXPECT_SUCCESS(srs_go_http_error(&w, SRS_CONSTS_HTTP_ServiceUnavailable));
|
||||||
|
__MOCK_HTTP_EXPECT_STREQ(503, "Service Unavailable", w);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID TEST(ProtocolHTTPTest, HTTPHeader)
|
VOID TEST(ProtocolHTTPTest, HTTPHeader)
|
||||||
|
@ -173,28 +236,24 @@ VOID TEST(ProtocolHTTPTest, HTTPHeader)
|
||||||
srs_freep(o);
|
srs_freep(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockFileReaderFactory : public ISrsFileReaderFactory
|
VOID TEST(ProtocolHTTPTest, HTTPServerMuxer)
|
||||||
{
|
{
|
||||||
public:
|
srs_error_t err;
|
||||||
string bytes;
|
|
||||||
MockFileReaderFactory(string data) {
|
|
||||||
bytes = data;
|
|
||||||
}
|
|
||||||
virtual ~MockFileReaderFactory() {
|
|
||||||
}
|
|
||||||
virtual SrsFileReader* create_file_reader() {
|
|
||||||
return new MockSrsFileReader((const char*)bytes.data(), (int)bytes.length());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool _mock_srs_path_always_exists(std::string /*path*/)
|
if (true) {
|
||||||
{
|
SrsHttpServeMux s;
|
||||||
return true;
|
HELPER_ASSERT_SUCCESS(s.initialize());
|
||||||
}
|
|
||||||
|
|
||||||
bool _mock_srs_path_not_exists(std::string /*path*/)
|
MockHttpHandler* hroot = new MockHttpHandler("Hello, world!");
|
||||||
{
|
HELPER_ASSERT_SUCCESS(s.handle("/", hroot));
|
||||||
return false;
|
|
||||||
|
MockResponseWriter w;
|
||||||
|
SrsHttpMessage r(NULL, NULL);
|
||||||
|
HELPER_ASSERT_SUCCESS(r.set_url("/index.html", false));
|
||||||
|
|
||||||
|
HELPER_ASSERT_SUCCESS(s.serve_http(&w, &r));
|
||||||
|
__MOCK_HTTP_EXPECT_STREQ(200, "Hello, world!", w);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID TEST(ProtocolHTTPTest, VodStreamHandlers)
|
VOID TEST(ProtocolHTTPTest, VodStreamHandlers)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue