mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
For #913, use complex error for http
This commit is contained in:
parent
661eb8b37c
commit
9f5224c34a
24 changed files with 388 additions and 453 deletions
|
@ -122,21 +122,23 @@ string srs_go_http_detect(char* data, int size)
|
|||
return "application/octet-stream"; // fallback
|
||||
}
|
||||
|
||||
int srs_go_http_error(ISrsHttpResponseWriter* w, int code)
|
||||
srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code)
|
||||
{
|
||||
return srs_go_http_error(w, code, srs_generate_http_status_text(code));
|
||||
}
|
||||
|
||||
int srs_go_http_error(ISrsHttpResponseWriter* w, int code, string error)
|
||||
srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code, string error)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
w->header()->set_content_type("text/plain; charset=utf-8");
|
||||
w->header()->set_content_length(error.length());
|
||||
w->write_header(code);
|
||||
w->write((char*)error.data(), (int)error.length());
|
||||
if ((ret = w->write((char*)error.data(), (int)error.length())) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "http write");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
SrsHttpHeader::SrsHttpHeader()
|
||||
|
@ -237,10 +239,8 @@ SrsHttpRedirectHandler::~SrsHttpRedirectHandler()
|
|||
{
|
||||
}
|
||||
|
||||
int SrsHttpRedirectHandler::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
srs_error_t SrsHttpRedirectHandler::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
string location = url;
|
||||
if (!r->query().empty()) {
|
||||
location += "?" + r->query();
|
||||
|
@ -257,7 +257,7 @@ int SrsHttpRedirectHandler::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessag
|
|||
w->final_request();
|
||||
|
||||
srs_info("redirect to %s.", location.c_str());
|
||||
return ret;
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
SrsHttpNotFoundHandler::SrsHttpNotFoundHandler()
|
||||
|
@ -273,7 +273,7 @@ bool SrsHttpNotFoundHandler::is_not_found()
|
|||
return true;
|
||||
}
|
||||
|
||||
int SrsHttpNotFoundHandler::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
srs_error_t SrsHttpNotFoundHandler::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
{
|
||||
return srs_go_http_error(w, SRS_CONSTS_HTTP_NotFound);
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ SrsHttpFileServer::~SrsHttpFileServer()
|
|||
{
|
||||
}
|
||||
|
||||
int SrsHttpFileServer::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
srs_error_t SrsHttpFileServer::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
{
|
||||
string upath = r->path();
|
||||
|
||||
|
@ -328,16 +328,16 @@ int SrsHttpFileServer::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
|||
return serve_file(w, r, fullpath);
|
||||
}
|
||||
|
||||
int SrsHttpFileServer::serve_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath)
|
||||
srs_error_t SrsHttpFileServer::serve_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// open the target file.
|
||||
SrsFileReader fs;
|
||||
|
||||
if ((ret = fs.open(fullpath)) != ERROR_SUCCESS) {
|
||||
srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret);
|
||||
return ret;
|
||||
return srs_error_new(ret, "open file %s", fullpath.c_str());
|
||||
}
|
||||
|
||||
int64_t length = fs.filesize();
|
||||
|
@ -393,17 +393,18 @@ int SrsHttpFileServer::serve_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r,
|
|||
|
||||
// write body.
|
||||
int64_t left = length;
|
||||
if ((ret = copy(w, &fs, r, (int)left)) != ERROR_SUCCESS) {
|
||||
if (!srs_is_client_gracefully_close(ret)) {
|
||||
srs_error("read file=%s size=%d failed, ret=%d", fullpath.c_str(), left, ret);
|
||||
}
|
||||
return ret;
|
||||
if ((err = copy(w, &fs, r, (int)left)) != srs_success) {
|
||||
return srs_error_wrap(err, "copy file=%s size=%d", fullpath.c_str(), left);
|
||||
}
|
||||
|
||||
return w->final_request();
|
||||
if ((ret = w->final_request()) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "final request");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHttpFileServer::serve_flv_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath)
|
||||
srs_error_t SrsHttpFileServer::serve_flv_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath)
|
||||
{
|
||||
std::string start = r->query_get("start");
|
||||
if (start.empty()) {
|
||||
|
@ -418,7 +419,7 @@ int SrsHttpFileServer::serve_flv_file(ISrsHttpResponseWriter* w, ISrsHttpMessage
|
|||
return serve_flv_stream(w, r, fullpath, offset);
|
||||
}
|
||||
|
||||
int SrsHttpFileServer::serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath)
|
||||
srs_error_t SrsHttpFileServer::serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath)
|
||||
{
|
||||
// for flash to request mp4 range in query string.
|
||||
// for example, http://digitalprimates.net/dash/DashTest.html?url=http://dashdemo.edgesuite.net/digitalprimates/nexus/oops-20120802-manifest.mpd
|
||||
|
@ -455,17 +456,17 @@ int SrsHttpFileServer::serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHttpMessage
|
|||
return serve_mp4_stream(w, r, fullpath, start, end);
|
||||
}
|
||||
|
||||
int SrsHttpFileServer::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int offset)
|
||||
srs_error_t SrsHttpFileServer::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int offset)
|
||||
{
|
||||
return serve_file(w, r, fullpath);
|
||||
}
|
||||
|
||||
int SrsHttpFileServer::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int start, int end)
|
||||
srs_error_t SrsHttpFileServer::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int start, int end)
|
||||
{
|
||||
return serve_file(w, r, fullpath);
|
||||
}
|
||||
|
||||
int SrsHttpFileServer::copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int size)
|
||||
srs_error_t SrsHttpFileServer::copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int size)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
@ -485,7 +486,11 @@ int SrsHttpFileServer::copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHt
|
|||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (ret != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "copy");
|
||||
}
|
||||
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
SrsHttpMuxEntry::SrsHttpMuxEntry()
|
||||
|
@ -629,54 +634,34 @@ srs_error_t SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler* handle
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
bool SrsHttpServeMux::can_serve(ISrsHttpMessage* r)
|
||||
srs_error_t SrsHttpServeMux::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
ISrsHttpHandler* h = NULL;
|
||||
if ((ret = find_handler(r, &h)) != ERROR_SUCCESS) {
|
||||
return false;
|
||||
if ((err = find_handler(r, &h)) != srs_success) {
|
||||
return srs_error_wrap(err, "find handler");
|
||||
}
|
||||
|
||||
srs_assert(h);
|
||||
return !h->is_not_found();
|
||||
}
|
||||
|
||||
int SrsHttpServeMux::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
ISrsHttpHandler* h = NULL;
|
||||
if ((ret = find_handler(r, &h)) != ERROR_SUCCESS) {
|
||||
srs_error("find handler failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = h->serve_http(w, r)) != srs_success) {
|
||||
return srs_error_wrap(err, "serve http");
|
||||
}
|
||||
|
||||
srs_assert(h);
|
||||
if ((ret = h->serve_http(w, r)) != ERROR_SUCCESS) {
|
||||
if (!srs_is_client_gracefully_close(ret)) {
|
||||
srs_error("handler serve http failed. ret=%d", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHttpServeMux::find_handler(ISrsHttpMessage* r, ISrsHttpHandler** ph)
|
||||
srs_error_t SrsHttpServeMux::find_handler(ISrsHttpMessage* r, ISrsHttpHandler** ph)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// TODO: FIXME: support the path . and ..
|
||||
if (r->url().find("..") != std::string::npos) {
|
||||
ret = ERROR_HTTP_URL_NOT_CLEAN;
|
||||
srs_error("htt url not canonical, url=%s. ret=%d", r->url().c_str(), ret);
|
||||
return ret;
|
||||
return srs_error_new(ERROR_HTTP_URL_NOT_CLEAN, "url %s not canonical", r->url().c_str());
|
||||
}
|
||||
|
||||
if ((ret = match(r, ph)) != ERROR_SUCCESS) {
|
||||
srs_error("http match handler failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = match(r, ph)) != srs_success) {
|
||||
return srs_error_wrap(err, "http match");
|
||||
}
|
||||
|
||||
// always hijack.
|
||||
|
@ -685,9 +670,8 @@ int SrsHttpServeMux::find_handler(ISrsHttpMessage* r, ISrsHttpHandler** ph)
|
|||
std::vector<ISrsHttpMatchHijacker*>::iterator it;
|
||||
for (it = hijackers.begin(); it != hijackers.end(); ++it) {
|
||||
ISrsHttpMatchHijacker* hijacker = *it;
|
||||
if ((ret = hijacker->hijack(r, ph)) != ERROR_SUCCESS) {
|
||||
srs_error("hijacker match failed. ret=%d", ret);
|
||||
return ret;
|
||||
if ((err = hijacker->hijack(r, ph)) != srs_success) {
|
||||
return srs_error_wrap(err, "http hijack");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -697,13 +681,11 @@ int SrsHttpServeMux::find_handler(ISrsHttpMessage* r, ISrsHttpHandler** ph)
|
|||
*ph = h404;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int SrsHttpServeMux::match(ISrsHttpMessage* r, ISrsHttpHandler** ph)
|
||||
srs_error_t SrsHttpServeMux::match(ISrsHttpMessage* r, ISrsHttpHandler** ph)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
std::string path = r->path();
|
||||
|
||||
// Host-specific pattern takes precedence over generic ones
|
||||
|
@ -735,7 +717,7 @@ int SrsHttpServeMux::match(ISrsHttpMessage* r, ISrsHttpHandler** ph)
|
|||
|
||||
*ph = h;
|
||||
|
||||
return ret;
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
bool SrsHttpServeMux::path_match(string pattern, string path)
|
||||
|
@ -773,16 +755,18 @@ SrsHttpCorsMux::~SrsHttpCorsMux()
|
|||
{
|
||||
}
|
||||
|
||||
int SrsHttpCorsMux::initialize(ISrsHttpServeMux* worker, bool cros_enabled)
|
||||
srs_error_t SrsHttpCorsMux::initialize(ISrsHttpServeMux* worker, bool cros_enabled)
|
||||
{
|
||||
next = worker;
|
||||
enabled = cros_enabled;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
int SrsHttpCorsMux::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
srs_error_t SrsHttpCorsMux::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// If CORS enabled, and there is a "Origin" header, it's CORS.
|
||||
if (enabled) {
|
||||
for (int i = 0; i < r->request_header_count(); i++) {
|
||||
|
@ -811,7 +795,9 @@ int SrsHttpCorsMux::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
|||
} else {
|
||||
w->write_header(SRS_CONSTS_HTTP_MethodNotAllowed);
|
||||
}
|
||||
return w->final_request();
|
||||
if ((ret = w->final_request()) != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "final request");
|
||||
}
|
||||
}
|
||||
|
||||
srs_assert(next);
|
||||
|
|
|
@ -77,8 +77,8 @@ class ISrsHttpResponseWriter;
|
|||
|
||||
// Error replies to the request with the specified error message and HTTP code.
|
||||
// The error message should be plain text.
|
||||
extern int srs_go_http_error(ISrsHttpResponseWriter* w, int code);
|
||||
extern int srs_go_http_error(ISrsHttpResponseWriter* w, int code, std::string error);
|
||||
extern srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code);
|
||||
extern srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code, std::string error);
|
||||
|
||||
// get the status text of code.
|
||||
extern std::string srs_generate_http_status_text(int status);
|
||||
|
@ -255,7 +255,7 @@ public:
|
|||
virtual ~ISrsHttpHandler();
|
||||
public:
|
||||
virtual bool is_not_found();
|
||||
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) = 0;
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) = 0;
|
||||
};
|
||||
|
||||
// Redirect to a fixed URL
|
||||
|
@ -268,7 +268,7 @@ public:
|
|||
SrsHttpRedirectHandler(std::string u, int c);
|
||||
virtual ~SrsHttpRedirectHandler();
|
||||
public:
|
||||
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
};
|
||||
|
||||
// NotFound replies to the request with an HTTP 404 not found error.
|
||||
|
@ -279,7 +279,7 @@ public:
|
|||
virtual ~SrsHttpNotFoundHandler();
|
||||
public:
|
||||
virtual bool is_not_found();
|
||||
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
};
|
||||
|
||||
// FileServer returns a handler that serves HTTP requests
|
||||
|
@ -298,31 +298,31 @@ public:
|
|||
SrsHttpFileServer(std::string root_dir);
|
||||
virtual ~SrsHttpFileServer();
|
||||
public:
|
||||
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
private:
|
||||
/**
|
||||
* serve the file by specified path
|
||||
*/
|
||||
virtual int serve_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
||||
virtual int serve_flv_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
||||
virtual int serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
||||
virtual srs_error_t serve_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
||||
virtual srs_error_t serve_flv_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
||||
virtual srs_error_t serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
||||
protected:
|
||||
/**
|
||||
* when access flv file with x.flv?start=xxx
|
||||
*/
|
||||
virtual int serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int offset);
|
||||
virtual srs_error_t serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int offset);
|
||||
/**
|
||||
* when access mp4 file with x.mp4?range=start-end
|
||||
* @param start the start offset in bytes.
|
||||
* @param end the end offset in bytes. -1 to end of file.
|
||||
* @remark response data in [start, end].
|
||||
*/
|
||||
virtual int serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end);
|
||||
virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end);
|
||||
protected:
|
||||
/**
|
||||
* copy the fs to response writer in size bytes.
|
||||
*/
|
||||
virtual int copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int size);
|
||||
virtual srs_error_t copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int size);
|
||||
};
|
||||
|
||||
// the mux entry for server mux.
|
||||
|
@ -353,7 +353,7 @@ public:
|
|||
* @param request the http request message to match the handler.
|
||||
* @param ph the already matched handler, hijack can rewrite it.
|
||||
*/
|
||||
virtual int hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) = 0;
|
||||
virtual srs_error_t hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -365,7 +365,7 @@ public:
|
|||
ISrsHttpServeMux();
|
||||
virtual ~ISrsHttpServeMux();
|
||||
public:
|
||||
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) = 0;
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) = 0;
|
||||
};
|
||||
|
||||
// ServeMux is an HTTP request multiplexer.
|
||||
|
@ -427,15 +427,13 @@ public:
|
|||
// Handle registers the handler for the given pattern.
|
||||
// If a handler already exists for pattern, Handle panics.
|
||||
virtual srs_error_t handle(std::string pattern, ISrsHttpHandler* handler);
|
||||
// whether the http muxer can serve the specified message,
|
||||
// if not, user can try next muxer.
|
||||
virtual bool can_serve(ISrsHttpMessage* r);
|
||||
// interface ISrsHttpServeMux
|
||||
public:
|
||||
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
public:
|
||||
virtual srs_error_t find_handler(ISrsHttpMessage* r, ISrsHttpHandler** ph);
|
||||
private:
|
||||
virtual int find_handler(ISrsHttpMessage* r, ISrsHttpHandler** ph);
|
||||
virtual int match(ISrsHttpMessage* r, ISrsHttpHandler** ph);
|
||||
virtual srs_error_t match(ISrsHttpMessage* r, ISrsHttpHandler** ph);
|
||||
virtual bool path_match(std::string pattern, std::string path);
|
||||
};
|
||||
|
||||
|
@ -453,10 +451,10 @@ public:
|
|||
SrsHttpCorsMux();
|
||||
virtual ~SrsHttpCorsMux();
|
||||
public:
|
||||
virtual int initialize(ISrsHttpServeMux* worker, bool cros_enabled);
|
||||
virtual srs_error_t initialize(ISrsHttpServeMux* worker, bool cros_enabled);
|
||||
// interface ISrsHttpServeMux
|
||||
public:
|
||||
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
};
|
||||
|
||||
// for http header.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue