mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Improve the coverage for HTTP error response.
This commit is contained in:
parent
474266eae7
commit
8c10c26f00
6 changed files with 141 additions and 8 deletions
|
@ -156,14 +156,23 @@ void SrsHttpHeader::set(string key, string value)
|
||||||
string SrsHttpHeader::get(string key)
|
string SrsHttpHeader::get(string key)
|
||||||
{
|
{
|
||||||
std::string v;
|
std::string v;
|
||||||
|
|
||||||
if (headers.find(key) != headers.end()) {
|
map<string, string>::iterator it = headers.find(key);
|
||||||
v = headers[key];
|
if (it != headers.end()) {
|
||||||
|
v = it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsHttpHeader::del(string key)
|
||||||
|
{
|
||||||
|
map<string, string>::iterator it = headers.find(key);
|
||||||
|
if (it != headers.end()) {
|
||||||
|
headers.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int64_t SrsHttpHeader::content_length()
|
int64_t SrsHttpHeader::content_length()
|
||||||
{
|
{
|
||||||
std::string cl = get("Content-Length");
|
std::string cl = get("Content-Length");
|
||||||
|
@ -192,7 +201,7 @@ void SrsHttpHeader::set_content_type(string ct)
|
||||||
|
|
||||||
void SrsHttpHeader::write(stringstream& ss)
|
void SrsHttpHeader::write(stringstream& ss)
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string>::iterator it;
|
map<string, string>::iterator it;
|
||||||
for (it = headers.begin(); it != headers.end(); ++it) {
|
for (it = headers.begin(); it != headers.end(); ++it) {
|
||||||
ss << it->first << ": " << it->second << SRS_HTTP_CRLF;
|
ss << it->first << ": " << it->second << SRS_HTTP_CRLF;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,6 +121,9 @@ public:
|
||||||
// To access multiple values of a key, access the map directly
|
// To access multiple values of a key, access the map directly
|
||||||
// with CanonicalHeaderKey.
|
// with CanonicalHeaderKey.
|
||||||
virtual std::string get(std::string key);
|
virtual std::string get(std::string key);
|
||||||
|
// Delete the http header indicated by key.
|
||||||
|
// Return the removed header field.
|
||||||
|
virtual void del(std::string);
|
||||||
public:
|
public:
|
||||||
// Get the content length. -1 if not set.
|
// Get the content length. -1 if not set.
|
||||||
virtual int64_t content_length();
|
virtual int64_t content_length();
|
||||||
|
|
|
@ -614,7 +614,15 @@ bool SrsHttpMessage::is_jsonp()
|
||||||
return jsonp;
|
return jsonp;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHttpResponseWriter::SrsHttpResponseWriter(SrsStSocket* io)
|
ISrsHttpHeaderFilter::ISrsHttpHeaderFilter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ISrsHttpHeaderFilter::~ISrsHttpHeaderFilter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpResponseWriter::SrsHttpResponseWriter(ISrsProtocolReadWriter* io)
|
||||||
{
|
{
|
||||||
skt = io;
|
skt = io;
|
||||||
hdr = new SrsHttpHeader();
|
hdr = new SrsHttpHeader();
|
||||||
|
@ -625,6 +633,7 @@ SrsHttpResponseWriter::SrsHttpResponseWriter(SrsStSocket* io)
|
||||||
header_sent = false;
|
header_sent = false;
|
||||||
nb_iovss_cache = 0;
|
nb_iovss_cache = 0;
|
||||||
iovss_cache = NULL;
|
iovss_cache = NULL;
|
||||||
|
hf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHttpResponseWriter::~SrsHttpResponseWriter()
|
SrsHttpResponseWriter::~SrsHttpResponseWriter()
|
||||||
|
@ -840,6 +849,11 @@ srs_error_t SrsHttpResponseWriter::send_header(char* data, int size)
|
||||||
|
|
||||||
// keep alive to make vlc happy.
|
// keep alive to make vlc happy.
|
||||||
hdr->set("Connection", "Keep-Alive");
|
hdr->set("Connection", "Keep-Alive");
|
||||||
|
|
||||||
|
// Filter the header before writing it.
|
||||||
|
if (hf && ((err = hf->filter(hdr)) != srs_success)) {
|
||||||
|
return srs_error_wrap(err, "filter header");
|
||||||
|
}
|
||||||
|
|
||||||
// write headers
|
// write headers
|
||||||
hdr->write(ss);
|
hdr->write(ss);
|
||||||
|
|
|
@ -35,7 +35,7 @@ class SrsFastStream;
|
||||||
class SrsRequest;
|
class SrsRequest;
|
||||||
class ISrsReader;
|
class ISrsReader;
|
||||||
class SrsHttpResponseReader;
|
class SrsHttpResponseReader;
|
||||||
class SrsStSocket;
|
class ISrsProtocolReadWriter;
|
||||||
|
|
||||||
// A wrapper for http-parser,
|
// A wrapper for http-parser,
|
||||||
// provides HTTP message originted service.
|
// provides HTTP message originted service.
|
||||||
|
@ -195,12 +195,25 @@ public:
|
||||||
// for writev, there always one chunk to send it.
|
// for writev, there always one chunk to send it.
|
||||||
#define SRS_HTTP_HEADER_CACHE_SIZE 64
|
#define SRS_HTTP_HEADER_CACHE_SIZE 64
|
||||||
|
|
||||||
|
class ISrsHttpHeaderFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ISrsHttpHeaderFilter();
|
||||||
|
virtual ~ISrsHttpHeaderFilter();
|
||||||
|
public:
|
||||||
|
// Filter the HTTP header h.
|
||||||
|
virtual srs_error_t filter(SrsHttpHeader* h) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
// Response writer use st socket
|
// Response writer use st socket
|
||||||
class SrsHttpResponseWriter : public ISrsHttpResponseWriter
|
class SrsHttpResponseWriter : public ISrsHttpResponseWriter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsStSocket* skt;
|
ISrsProtocolReadWriter* skt;
|
||||||
SrsHttpHeader* hdr;
|
SrsHttpHeader* hdr;
|
||||||
|
// Before writing header, there is a chance to filter it,
|
||||||
|
// such as remove some headers or inject new.
|
||||||
|
ISrsHttpHeaderFilter* hf;
|
||||||
private:
|
private:
|
||||||
char header_cache[SRS_HTTP_HEADER_CACHE_SIZE];
|
char header_cache[SRS_HTTP_HEADER_CACHE_SIZE];
|
||||||
iovec* iovss_cache;
|
iovec* iovss_cache;
|
||||||
|
@ -222,7 +235,7 @@ private:
|
||||||
// logically written.
|
// logically written.
|
||||||
bool header_sent;
|
bool header_sent;
|
||||||
public:
|
public:
|
||||||
SrsHttpResponseWriter(SrsStSocket* io);
|
SrsHttpResponseWriter(ISrsProtocolReadWriter* io);
|
||||||
virtual ~SrsHttpResponseWriter();
|
virtual ~SrsHttpResponseWriter();
|
||||||
public:
|
public:
|
||||||
virtual srs_error_t final_request();
|
virtual srs_error_t final_request();
|
||||||
|
|
|
@ -35,8 +35,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
#include <srs_app_log.hpp>
|
#include <srs_app_log.hpp>
|
||||||
|
#include <srs_kernel_stream.hpp>
|
||||||
|
|
||||||
// we add an empty macro for upp to show the smart tips.
|
// we add an empty macro for upp to show the smart tips.
|
||||||
#define VOID
|
#define VOID
|
||||||
|
@ -61,6 +63,10 @@ extern srs_utime_t _srs_tmp_timeout;
|
||||||
#define HELPER_ARRAY_INIT(buf, sz, val) \
|
#define HELPER_ARRAY_INIT(buf, sz, val) \
|
||||||
for (int i = 0; i < (int)sz; i++) (buf)[i]=val
|
for (int i = 0; i < (int)sz; i++) (buf)[i]=val
|
||||||
|
|
||||||
|
// Dump simple stream to string.
|
||||||
|
#define HELPER_BUFFER2STR(io) \
|
||||||
|
string((const char*)(io)->bytes(), (size_t)(io)->length())
|
||||||
|
|
||||||
// the asserts of gtest:
|
// the asserts of gtest:
|
||||||
// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
|
// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
|
||||||
// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2
|
// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2
|
||||||
|
|
|
@ -22,7 +22,84 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include <srs_utest_http.hpp>
|
#include <srs_utest_http.hpp>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
#include <srs_http_stack.hpp>
|
#include <srs_http_stack.hpp>
|
||||||
|
#include <srs_service_http_conn.hpp>
|
||||||
|
#include <srs_utest_protocol.hpp>
|
||||||
|
|
||||||
|
class MockResponseWriter : virtual public ISrsHttpResponseWriter, virtual public ISrsHttpHeaderFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SrsHttpResponseWriter* w;
|
||||||
|
MockBufferIO io;
|
||||||
|
public:
|
||||||
|
MockResponseWriter();
|
||||||
|
virtual ~MockResponseWriter();
|
||||||
|
public:
|
||||||
|
virtual srs_error_t final_request();
|
||||||
|
virtual SrsHttpHeader* header();
|
||||||
|
virtual srs_error_t write(char* data, int size);
|
||||||
|
virtual srs_error_t writev(const iovec* iov, int iovcnt, ssize_t* pnwrite);
|
||||||
|
virtual void write_header(int code);
|
||||||
|
public:
|
||||||
|
virtual srs_error_t filter(SrsHttpHeader* h);
|
||||||
|
};
|
||||||
|
|
||||||
|
MockResponseWriter::MockResponseWriter()
|
||||||
|
{
|
||||||
|
w = new SrsHttpResponseWriter(&io);
|
||||||
|
w->hf = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
MockResponseWriter::~MockResponseWriter()
|
||||||
|
{
|
||||||
|
srs_freep(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
srs_error_t MockResponseWriter::final_request()
|
||||||
|
{
|
||||||
|
return w->final_request();
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpHeader* MockResponseWriter::header()
|
||||||
|
{
|
||||||
|
return w->header();
|
||||||
|
}
|
||||||
|
|
||||||
|
srs_error_t MockResponseWriter::write(char* data, int size)
|
||||||
|
{
|
||||||
|
return w->write(data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
srs_error_t MockResponseWriter::writev(const iovec* iov, int iovcnt, ssize_t* pnwrite)
|
||||||
|
{
|
||||||
|
return w->writev(iov, iovcnt, pnwrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MockResponseWriter::write_header(int code)
|
||||||
|
{
|
||||||
|
w->write_header(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
srs_error_t MockResponseWriter::filter(SrsHttpHeader* h)
|
||||||
|
{
|
||||||
|
h->del("Content-Type");
|
||||||
|
h->del("Server");
|
||||||
|
h->del("Connection");
|
||||||
|
return srs_success;
|
||||||
|
}
|
||||||
|
|
||||||
|
string mock_http_response(int status, string content)
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
ss << "HTTP/1.1 " << status << " " << srs_generate_http_status_text(status) << "\r\n"
|
||||||
|
<< "Content-Length: " << content.length() << "\r\n"
|
||||||
|
<< "\r\n"
|
||||||
|
<< content;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
VOID TEST(ProtocolHTTPTest, StatusCode2Text)
|
VOID TEST(ProtocolHTTPTest, StatusCode2Text)
|
||||||
{
|
{
|
||||||
|
@ -40,3 +117,14 @@ 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID TEST(ProtocolHTTPTest, ResponseHTTPError)
|
||||||
|
{
|
||||||
|
srs_error_t err;
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
MockResponseWriter w;
|
||||||
|
HELPER_EXPECT_SUCCESS(srs_go_http_error(&w, SRS_CONSTS_HTTP_Found));
|
||||||
|
EXPECT_STREQ(mock_http_response(302,"Found").c_str(), HELPER_BUFFER2STR(&w.io.out_buffer).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue