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

Fix #2881: HTTP: Support merging api to server. v5.0.47

This commit is contained in:
winlin 2022-08-28 09:10:13 +08:00
parent 6508a082e9
commit 457738f6eb
34 changed files with 333 additions and 934 deletions

View file

@ -287,7 +287,7 @@ void SrsHttpConn::expire()
trd->interrupt();
}
SrsResponseOnlyHttpConn::SrsResponseOnlyHttpConn(bool https, ISrsResourceManager* cm, srs_netfd_t fd, ISrsHttpServeMux* m, string cip, int port)
SrsHttpxConn::SrsHttpxConn(bool https, ISrsResourceManager* cm, srs_netfd_t fd, ISrsHttpServeMux* m, string cip, int port)
{
// Create a identify for this client.
_srs_context->set_id(_srs_context->generate_id());
@ -306,7 +306,7 @@ SrsResponseOnlyHttpConn::SrsResponseOnlyHttpConn(bool https, ISrsResourceManager
_srs_config->subscribe(this);
}
SrsResponseOnlyHttpConn::~SrsResponseOnlyHttpConn()
SrsHttpxConn::~SrsHttpxConn()
{
_srs_config->unsubscribe(this);
@ -315,7 +315,7 @@ SrsResponseOnlyHttpConn::~SrsResponseOnlyHttpConn()
srs_freep(skt);
}
srs_error_t SrsResponseOnlyHttpConn::pop_message(ISrsHttpMessage** preq)
srs_error_t SrsHttpxConn::pop_message(ISrsHttpMessage** preq)
{
srs_error_t err = srs_success;
@ -330,13 +330,13 @@ srs_error_t SrsResponseOnlyHttpConn::pop_message(ISrsHttpMessage** preq)
// We start a socket to read the stfd, which is writing by conn.
// It's ok, because conn never read it after processing the HTTP request.
// drop all request body.
char body[4096];
static char body[SRS_HTTP_READ_CACHE_BYTES];
while (true) {
if ((err = conn->pull()) != srs_success) {
return srs_error_wrap(err, "timeout");
}
if ((err = io->read(body, 4096, NULL)) != srs_success) {
if ((err = io->read(body, SRS_HTTP_READ_CACHE_BYTES, NULL)) != srs_success) {
// Because we use timeout to check trd state, so we should ignore any timeout.
if (srs_error_code(err) == ERROR_SOCKET_TIMEOUT) {
srs_freep(err);
@ -350,16 +350,16 @@ srs_error_t SrsResponseOnlyHttpConn::pop_message(ISrsHttpMessage** preq)
return err;
}
srs_error_t SrsResponseOnlyHttpConn::on_reload_http_stream_crossdomain()
{
bool v = _srs_config->get_http_stream_crossdomain();
return conn->set_crossdomain_enabled(v);
}
srs_error_t SrsResponseOnlyHttpConn::on_start()
srs_error_t SrsHttpxConn::on_start()
{
srs_error_t err = srs_success;
// Enable JSONP for HTTP API.
if ((err = conn->set_jsonp(true)) != srs_success) {
return srs_error_wrap(err, "set jsonp");
}
// Do SSL handshake if HTTPS.
if (ssl) {
srs_utime_t starttime = srs_update_system_time();
string crt_file = _srs_config->get_https_stream_ssl_cert();
@ -376,7 +376,7 @@ srs_error_t SrsResponseOnlyHttpConn::on_start()
return err;
}
srs_error_t SrsResponseOnlyHttpConn::on_http_message(ISrsHttpMessage* r, SrsHttpResponseWriter* w)
srs_error_t SrsHttpxConn::on_http_message(ISrsHttpMessage* r, SrsHttpResponseWriter* w)
{
srs_error_t err = srs_success;
@ -385,32 +385,25 @@ srs_error_t SrsResponseOnlyHttpConn::on_http_message(ISrsHttpMessage* r, SrsHttp
SrsHttpMessage* hm = dynamic_cast<SrsHttpMessage*>(r);
hm->set_https(true);
}
ISrsHttpResponseReader* br = r->body_reader();
// when not specified the content length, ignore.
if (r->content_length() == -1) {
return err;
}
// For each session, we use short-term HTTP connection.
SrsHttpHeader* hdr = w->header();
hdr->set("Connection", "Close");
// Drop all request body.
// TODO: Should we set timeout for max reading?
char body[4096];
while (!br->eof()) {
if ((err = br->read(body, 4096, NULL)) != srs_success) {
return srs_error_wrap(err, "read response");
}
// Not support HTTP request with body.
if (r->content_length() > 0) {
return srs_error_new(ERROR_HTTP_WITH_BODY, "with %d body", r->content_length());
}
return err;
}
srs_error_t SrsResponseOnlyHttpConn::on_message_done(ISrsHttpMessage* r, SrsHttpResponseWriter* w)
srs_error_t SrsHttpxConn::on_message_done(ISrsHttpMessage* r, SrsHttpResponseWriter* w)
{
return srs_success;
}
srs_error_t SrsResponseOnlyHttpConn::on_conn_done(srs_error_t r0)
srs_error_t SrsHttpxConn::on_conn_done(srs_error_t r0)
{
// Update statistic when done.
SrsStatistic* stat = SrsStatistic::instance();
@ -421,38 +414,45 @@ srs_error_t SrsResponseOnlyHttpConn::on_conn_done(srs_error_t r0)
// not the http connection object, so we must remove it here.
manager->remove(this);
// For HTTP-API timeout, we think it's done successfully,
// because there may be no request or response for HTTP-API.
if (srs_error_code(r0) == ERROR_SOCKET_TIMEOUT) {
srs_freep(r0);
return srs_success;
}
return r0;
}
srs_error_t SrsResponseOnlyHttpConn::set_tcp_nodelay(bool v)
srs_error_t SrsHttpxConn::set_tcp_nodelay(bool v)
{
return skt->set_tcp_nodelay(v);
}
srs_error_t SrsResponseOnlyHttpConn::set_socket_buffer(srs_utime_t buffer_v)
srs_error_t SrsHttpxConn::set_socket_buffer(srs_utime_t buffer_v)
{
return skt->set_socket_buffer(buffer_v);
}
std::string SrsResponseOnlyHttpConn::desc()
std::string SrsHttpxConn::desc()
{
if (ssl) {
return "HttpsStream";
return "HttpsConn";
}
return "HttpStream";
return "HttpConn";
}
std::string SrsResponseOnlyHttpConn::remote_ip()
std::string SrsHttpxConn::remote_ip()
{
return conn->remote_ip();
}
const SrsContextId& SrsResponseOnlyHttpConn::get_id()
const SrsContextId& SrsHttpxConn::get_id()
{
return conn->get_id();
}
srs_error_t SrsResponseOnlyHttpConn::start()
srs_error_t SrsHttpxConn::start()
{
srs_error_t err = srs_success;
@ -468,7 +468,7 @@ srs_error_t SrsResponseOnlyHttpConn::start()
return conn->start();
}
void SrsResponseOnlyHttpConn::remark(int64_t* in, int64_t* out)
void SrsHttpxConn::remark(int64_t* in, int64_t* out)
{
conn->remark(in, out);
}
@ -506,11 +506,28 @@ srs_error_t SrsHttpServer::initialize()
return err;
}
srs_error_t SrsHttpServer::handle(std::string pattern, ISrsHttpHandler* handler)
{
return http_static->mux.handle(pattern, handler);
}
srs_error_t SrsHttpServer::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{
srs_error_t err = srs_success;
string path = r->path();
const char* p = path.data();
// For /api/ or /console/, try static only.
if (path.length() > 4 && p[0] == '/') {
bool is_api = memcmp(p, "/api/", 5) == 0;
bool is_console = path.length() > 8 && memcmp(p, "/console/", 9) == 0;
if (is_api || is_console) {
return http_static->mux.serve_http(w, r);
}
}
// try http stream first.
// Try http stream first, then http static if not found.
ISrsHttpHandler* h = NULL;
if ((err = http_stream->mux.find_handler(r, &h)) != srs_success) {
return srs_error_wrap(err, "find handler");
@ -518,7 +535,8 @@ srs_error_t SrsHttpServer::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage
if (!h->is_not_found()) {
return http_stream->mux.serve_http(w, r);
}
// Use http static as default server.
return http_static->mux.serve_http(w, r);
}