mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 11:51:57 +00:00
implements basic http response framework
This commit is contained in:
parent
341b5151d9
commit
bfa07465f0
4 changed files with 143 additions and 41 deletions
|
@ -59,7 +59,7 @@ int SrsHttpHandler::initialize()
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool SrsHttpHandler::can_handle(const char* /*path*/, int /*length*/)
|
||||
bool SrsHttpHandler::can_handle(const char* /*path*/, int /*length*/, const char** /*pnext_path*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -86,20 +86,23 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandler** ph
|
|||
}
|
||||
|
||||
// whether the handler can handler the node.
|
||||
int node_size = p - path;
|
||||
if (!can_handle(path, node_size)) {
|
||||
const char* pnext = p;
|
||||
if (!can_handle(path, p - path, &pnext)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// save current handler, it's ok for current handler atleast.
|
||||
*phandler = this;
|
||||
*pstart = path;
|
||||
*plength = node_size;
|
||||
*plength = p - path;
|
||||
|
||||
// find the best matched child handler.
|
||||
std::vector<SrsHttpHandler*>::iterator it;
|
||||
for (it = handlers.begin(); it != handlers.end(); ++it) {
|
||||
SrsHttpHandler* handler = *it;
|
||||
// matched, donot search.
|
||||
if (handler->best_match(p, length - node_size, phandler, pstart, plength) == ERROR_SUCCESS) {
|
||||
|
||||
// matched, donot search more.
|
||||
if (handler->best_match(pnext, length - (pnext - path), phandler, pstart, plength) == ERROR_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -116,6 +119,76 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandler** ph
|
|||
return ret;
|
||||
}
|
||||
|
||||
SrsHttpHandler* SrsHttpHandler::res_status_line(std::stringstream& ss)
|
||||
{
|
||||
ss << "HTTP/1.1 200 OK " << __CRLF
|
||||
<< "Server: SRS/"RTMP_SIG_SRS_VERSION"" << __CRLF;
|
||||
return this;
|
||||
}
|
||||
|
||||
SrsHttpHandler* SrsHttpHandler::res_content_type(std::stringstream& ss)
|
||||
{
|
||||
ss << "Content-Type: text/html;charset=utf-8" << __CRLF
|
||||
<< "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF;
|
||||
return this;
|
||||
}
|
||||
|
||||
SrsHttpHandler* SrsHttpHandler::res_content_length(std::stringstream& ss, int64_t length)
|
||||
{
|
||||
ss << "Content-Length: "<< length << __CRLF;
|
||||
return this;
|
||||
}
|
||||
|
||||
SrsHttpHandler* SrsHttpHandler::res_enable_crossdomain(std::stringstream& ss)
|
||||
{
|
||||
ss << "Access-Control-Allow-Origin: *" << __CRLF
|
||||
<< "Access-Control-Allow-Methods: "
|
||||
<< "GET, POST, HEAD, PUT, DELETE" << __CRLF
|
||||
<< "Access-Control-Allow-Headers: "
|
||||
<< "Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type" << __CRLF;
|
||||
return this;
|
||||
}
|
||||
|
||||
SrsHttpHandler* SrsHttpHandler::res_header_eof(std::stringstream& ss)
|
||||
{
|
||||
ss << __CRLF;
|
||||
return this;
|
||||
}
|
||||
|
||||
SrsHttpHandler* SrsHttpHandler::res_body(std::stringstream& ss, std::string body)
|
||||
{
|
||||
ss << body;
|
||||
return this;
|
||||
}
|
||||
|
||||
int SrsHttpHandler::res_flush(SrsSocket* skt, std::stringstream& ss)
|
||||
{
|
||||
return skt->write(ss.str().c_str(), ss.str().length(), NULL);
|
||||
}
|
||||
|
||||
int SrsHttpHandler::res_options(SrsSocket* skt)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
res_status_line(ss)->res_content_type(ss)
|
||||
->res_content_length(ss, 0)->res_enable_crossdomain(ss)
|
||||
->res_header_eof(ss);
|
||||
|
||||
return res_flush(skt, ss);
|
||||
}
|
||||
|
||||
int SrsHttpHandler::res_text(SrsSocket* skt, std::string body)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
res_status_line(ss)->res_content_type(ss)
|
||||
->res_content_length(ss, (int)body.length())->res_enable_crossdomain(ss)
|
||||
->res_header_eof(ss)
|
||||
->res_body(ss, body);
|
||||
|
||||
return res_flush(skt, ss);
|
||||
}
|
||||
|
||||
SrsHttpHandler* SrsHttpHandler::create_http_api()
|
||||
{
|
||||
return new SrsApiRoot();
|
||||
|
|
|
@ -33,6 +33,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include <http_parser.h>
|
||||
|
||||
|
@ -89,8 +90,9 @@ public:
|
|||
virtual int initialize();
|
||||
/**
|
||||
* whether current handler can handle the specified path.
|
||||
* @pnext_path set the next path, if needed.
|
||||
*/
|
||||
virtual bool can_handle(const char* path, int length);
|
||||
virtual bool can_handle(const char* path, int length, const char** pnext_path);
|
||||
/**
|
||||
* use the handler to process the request.
|
||||
*/
|
||||
|
@ -100,6 +102,17 @@ public:
|
|||
* find the best matched handler
|
||||
*/
|
||||
virtual int best_match(const char* path, int length, SrsHttpHandler** phandler, const char** pstart, int* plength);
|
||||
public:
|
||||
virtual SrsHttpHandler* res_status_line(std::stringstream& ss);
|
||||
virtual SrsHttpHandler* res_content_type(std::stringstream& ss);
|
||||
virtual SrsHttpHandler* res_content_length(std::stringstream& ss, int64_t length);
|
||||
virtual SrsHttpHandler* res_enable_crossdomain(std::stringstream& ss);
|
||||
virtual SrsHttpHandler* res_header_eof(std::stringstream& ss);
|
||||
virtual SrsHttpHandler* res_body(std::stringstream& ss, std::string body);
|
||||
virtual int res_flush(SrsSocket* skt, std::stringstream& ss);
|
||||
public:
|
||||
virtual int res_options(SrsSocket* skt);
|
||||
virtual int res_text(SrsSocket* skt, std::string body);
|
||||
public:
|
||||
/**
|
||||
* create http api resource handler.
|
||||
|
|
|
@ -36,21 +36,56 @@ using namespace std;
|
|||
|
||||
SrsApiRoot::SrsApiRoot()
|
||||
{
|
||||
handlers.push_back(new SrsApiApi());
|
||||
}
|
||||
|
||||
SrsApiRoot::~SrsApiRoot()
|
||||
{
|
||||
}
|
||||
|
||||
bool SrsApiRoot::can_handle(const char* /*path*/, int /*length*/)
|
||||
bool SrsApiRoot::can_handle(const char* path, int length, const char** pnext_path)
|
||||
{
|
||||
// reset the next path for child to parse.
|
||||
*pnext_path = path;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int SrsApiRoot::process_request(SrsSocket* /*skt*/, SrsHttpMessage* /*req*/, const char* /*path*/, int /*length*/)
|
||||
int SrsApiRoot::process_request(SrsSocket* skt, SrsHttpMessage* req, const char* /*path*/, int /*length*/)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
return ret;
|
||||
if (req->method() == HTTP_OPTIONS) {
|
||||
return res_options(skt);
|
||||
} else {
|
||||
std::string body = "hello, root";
|
||||
return res_text(skt, body);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
SrsApiApi::SrsApiApi()
|
||||
{
|
||||
}
|
||||
|
||||
SrsApiApi::~SrsApiApi()
|
||||
{
|
||||
}
|
||||
|
||||
bool SrsApiApi::can_handle(const char* path, int length, const char** /*pnext_path*/)
|
||||
{
|
||||
return !memcmp("/api", path, length);
|
||||
}
|
||||
|
||||
int SrsApiApi::process_request(SrsSocket* skt, SrsHttpMessage* req, const char* /*path*/, int /*length*/)
|
||||
{
|
||||
if (req->method() == HTTP_OPTIONS) {
|
||||
return res_options(skt);
|
||||
} else {
|
||||
std::string body = "hello, api";
|
||||
return res_text(skt, body);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
SrsHttpApi::SrsHttpApi(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler)
|
||||
|
@ -135,35 +170,6 @@ int SrsHttpApi::process_request(SrsSocket* skt, SrsHttpMessage* req)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (req->method() == HTTP_OPTIONS) {
|
||||
char data[] = "HTTP/1.1 200 OK" __CRLF
|
||||
"Content-Length: 0"__CRLF
|
||||
"Server: SRS/"RTMP_SIG_SRS_VERSION""__CRLF
|
||||
"Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT"__CRLF
|
||||
"Access-Control-Allow-Origin: *"__CRLF
|
||||
"Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE"__CRLF
|
||||
"Access-Control-Allow-Headers: Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type"__CRLF
|
||||
"Content-Type: text/html;charset=utf-8"__CRLFCRLF
|
||||
"";
|
||||
return skt->write(data, sizeof(data), NULL);
|
||||
} else {
|
||||
std::string tilte = "SRS/"RTMP_SIG_SRS_VERSION;
|
||||
tilte += " hello http/1.1 api~\n";
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "HTTP/1.1 200 OK " << __CRLF
|
||||
<< "Content-Length: "<< tilte.length() + req->body_size() << __CRLF
|
||||
<< "Server: SRS/"RTMP_SIG_SRS_VERSION"" << __CRLF
|
||||
<< "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF
|
||||
<< "Access-Control-Allow-Origin: *" << __CRLF
|
||||
<< "Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE" << __CRLF
|
||||
<< "Access-Control-Allow-Headers: Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type" << __CRLF
|
||||
<< "Content-Type: text/html;charset=utf-8" << __CRLFCRLF
|
||||
<< tilte << req->body().c_str()
|
||||
<< "";
|
||||
return skt->write(ss.str().c_str(), ss.str().length(), NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,17 @@ public:
|
|||
SrsApiRoot();
|
||||
virtual ~SrsApiRoot();
|
||||
public:
|
||||
virtual bool can_handle(const char* path, int length);
|
||||
virtual bool can_handle(const char* path, int length, const char** pnext_path);
|
||||
virtual int process_request(SrsSocket* skt, SrsHttpMessage* req, const char* path, int length);
|
||||
};
|
||||
|
||||
class SrsApiApi : public SrsHttpHandler
|
||||
{
|
||||
public:
|
||||
SrsApiApi();
|
||||
virtual ~SrsApiApi();
|
||||
public:
|
||||
virtual bool can_handle(const char* path, int length, const char** pnext_path);
|
||||
virtual int process_request(SrsSocket* skt, SrsHttpMessage* req, const char* path, int length);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue