mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
fix #442: HTTP API kickoff client.
This commit is contained in:
parent
0e3128d3e3
commit
e8c0ca7af0
10 changed files with 121 additions and 18 deletions
54
trunk/src/app/srs_app_http_api.cpp
Normal file → Executable file
54
trunk/src/app/srs_app_http_api.cpp
Normal file → Executable file
|
@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#ifdef SRS_AUTO_HTTP_API
|
||||
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
using namespace std;
|
||||
|
||||
#include <srs_kernel_log.hpp>
|
||||
|
@ -39,6 +40,7 @@ using namespace std;
|
|||
#include <srs_rtmp_stack.hpp>
|
||||
#include <srs_app_dvr.hpp>
|
||||
#include <srs_app_config.hpp>
|
||||
#include <srs_app_source.hpp>
|
||||
#include <srs_app_http_conn.hpp>
|
||||
|
||||
SrsGoApiRoot::SrsGoApiRoot()
|
||||
|
@ -459,12 +461,56 @@ SrsGoApiStreams::~SrsGoApiStreams()
|
|||
|
||||
int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
{
|
||||
std::stringstream data;
|
||||
int ret = ERROR_SUCCESS;
|
||||
SrsStatistic* stat = SrsStatistic::instance();
|
||||
int ret = stat->dumps_streams(data);
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
if (r->is_http_delete()) {
|
||||
// path: {pattern}{stream_id}
|
||||
// e.g. /api/v1/streams/100 pattern= /api/v1/streams/, stream_id=100
|
||||
string sid = r->path().substr((int)entry->pattern.length());
|
||||
if (sid.empty()) {
|
||||
ret = ERROR_REQUEST_DATA;
|
||||
srs_error("invalid param, stream_id=%s. ret=%d", sid.c_str(), ret);
|
||||
|
||||
ss << SRS_JOBJECT_START
|
||||
<< SRS_JFIELD_ERROR(ret)
|
||||
<< SRS_JOBJECT_END;
|
||||
|
||||
return srs_http_response_json(w, ss.str());
|
||||
}
|
||||
|
||||
int stream_id = ::atoi(sid.c_str());
|
||||
SrsStatisticStream* stream = stat->find_stream(stream_id);
|
||||
if (stream == NULL) {
|
||||
ret = ERROR_RTMP_STREAM_NOT_FOUND;
|
||||
srs_error("stream stream_id=%s not found. ret=%d", sid.c_str(), ret);
|
||||
|
||||
ss << SRS_JOBJECT_START
|
||||
<< SRS_JFIELD_ERROR(ret)
|
||||
<< SRS_JOBJECT_END;
|
||||
|
||||
return srs_http_response_json(w, ss.str());
|
||||
}
|
||||
|
||||
SrsSource* source = SrsSource::fetch(stream->vhost->vhost, stream->app, stream->stream);
|
||||
if (source) {
|
||||
source->set_expired();
|
||||
srs_warn("disconnent stream=%d successfully. vhost=%s, app=%s, stream=%s.",
|
||||
stream_id, stream->vhost->vhost.c_str(), stream->app.c_str(), stream->stream.c_str());
|
||||
} else {
|
||||
ret = ERROR_SOURCE_NOT_FOUND;
|
||||
}
|
||||
|
||||
ss << SRS_JOBJECT_START
|
||||
<< SRS_JFIELD_ERROR(ret)
|
||||
<< SRS_JOBJECT_END;
|
||||
|
||||
return srs_http_response_json(w, ss.str());
|
||||
} else {
|
||||
std::stringstream data;
|
||||
int ret = stat->dumps_streams(data);
|
||||
|
||||
ss << SRS_JOBJECT_START
|
||||
<< SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
|
||||
<< SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
|
||||
|
@ -473,6 +519,8 @@ int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
|||
|
||||
return srs_http_response_json(w, ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SrsHttpApi::SrsHttpApi(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m)
|
||||
: SrsConnection(cm, fd)
|
||||
|
|
2
trunk/src/app/srs_app_http_conn.cpp
Normal file → Executable file
2
trunk/src/app/srs_app_http_conn.cpp
Normal file → Executable file
|
@ -104,12 +104,12 @@ int SrsHttpResponseWriter::write(char* data, int size)
|
|||
|
||||
if (!header_wrote) {
|
||||
write_header(SRS_CONSTS_HTTP_OK);
|
||||
}
|
||||
|
||||
if ((ret = send_header(data, size)) != ERROR_SUCCESS) {
|
||||
srs_error("http: send header failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// check the bytes send and content length.
|
||||
written += size;
|
||||
|
|
|
@ -774,6 +774,13 @@ int SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* trd)
|
|||
while (!disposed) {
|
||||
pprint->elapse();
|
||||
|
||||
// when source is set to expired, disconnect it.
|
||||
if (source->expired()) {
|
||||
ret = ERROR_USER_DISCONNECT;
|
||||
srs_error("source is expired. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// cond wait for timeout.
|
||||
if (nb_msgs == 0) {
|
||||
// when not got msgs, wait for a larger timeout.
|
||||
|
|
2
trunk/src/app/srs_app_server.cpp
Normal file → Executable file
2
trunk/src/app/srs_app_server.cpp
Normal file → Executable file
|
@ -806,7 +806,7 @@ int SrsServer::http_handle()
|
|||
if ((ret = http_api_mux->handle("/api/v1/vhosts", new SrsGoApiVhosts())) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = http_api_mux->handle("/api/v1/streams", new SrsGoApiStreams())) != ERROR_SUCCESS) {
|
||||
if ((ret = http_api_mux->handle("/api/v1/streams/", new SrsGoApiStreams())) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -890,6 +890,7 @@ SrsSource::SrsSource()
|
|||
jitter_algorithm = SrsRtmpJitterAlgorithmOFF;
|
||||
mix_correct = false;
|
||||
mix_queue = new SrsMixQueue();
|
||||
is_expired = false;
|
||||
|
||||
#ifdef SRS_AUTO_HLS
|
||||
hls = new SrsHls();
|
||||
|
@ -2071,6 +2072,7 @@ void SrsSource::on_unpublish()
|
|||
|
||||
_can_publish = true;
|
||||
_source_id = -1;
|
||||
is_expired = false;
|
||||
|
||||
// notify the handler.
|
||||
srs_assert(handler);
|
||||
|
@ -2229,3 +2231,13 @@ void SrsSource::destroy_forwarders()
|
|||
forwarders.clear();
|
||||
}
|
||||
|
||||
bool SrsSource::expired()
|
||||
{
|
||||
return is_expired;
|
||||
}
|
||||
|
||||
void SrsSource::set_expired()
|
||||
{
|
||||
is_expired = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -452,6 +452,8 @@ private:
|
|||
// whether use interlaced/mixed algorithm to correct timestamp.
|
||||
bool mix_correct;
|
||||
SrsMixQueue* mix_queue;
|
||||
// the flag of source expired or not.
|
||||
bool is_expired;
|
||||
// whether stream is monotonically increase.
|
||||
bool is_monotonically_increase;
|
||||
int64_t last_packet_time;
|
||||
|
@ -583,6 +585,12 @@ public:
|
|||
private:
|
||||
virtual int create_forwarders();
|
||||
virtual void destroy_forwarders();
|
||||
public:
|
||||
virtual bool expired();
|
||||
/**
|
||||
* set source expired.
|
||||
*/
|
||||
virtual void set_expired();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
14
trunk/src/app/srs_app_statistic.cpp
Normal file → Executable file
14
trunk/src/app/srs_app_statistic.cpp
Normal file → Executable file
|
@ -134,6 +134,20 @@ SrsStatistic* SrsStatistic::instance()
|
|||
return _instance;
|
||||
}
|
||||
|
||||
SrsStatisticStream* SrsStatistic::find_stream(int stream_id)
|
||||
{
|
||||
std::map<int, SrsStatisticClient*>::iterator it;
|
||||
for (it = clients.begin(); it != clients.end(); it++) {
|
||||
SrsStatisticClient* client = it->second;
|
||||
SrsStatisticStream* stream = client->stream;
|
||||
|
||||
if (stream_id == stream->id) {
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int SrsStatistic::on_video_info(SrsRequest* req,
|
||||
SrsCodecVideo vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level
|
||||
) {
|
||||
|
|
1
trunk/src/app/srs_app_statistic.hpp
Normal file → Executable file
1
trunk/src/app/srs_app_statistic.hpp
Normal file → Executable file
|
@ -131,6 +131,7 @@ private:
|
|||
public:
|
||||
static SrsStatistic* instance();
|
||||
public:
|
||||
virtual SrsStatisticStream* find_stream(int stream_id);
|
||||
/**
|
||||
* when got video info for stream.
|
||||
*/
|
||||
|
|
3
trunk/src/kernel/srs_kernel_error.hpp
Normal file → Executable file
3
trunk/src/kernel/srs_kernel_error.hpp
Normal file → Executable file
|
@ -149,6 +149,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define ERROR_RTP_TYPE96_CORRUPT 2045
|
||||
#define ERROR_RTP_TYPE97_CORRUPT 2046
|
||||
#define ERROR_RTSP_AUDIO_CONFIG 2047
|
||||
#define ERROR_RTMP_STREAM_NOT_FOUND 2048
|
||||
//
|
||||
// system control message,
|
||||
// not an error, but special control logic.
|
||||
|
@ -225,6 +226,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define ERROR_HLS_NO_STREAM 3062
|
||||
#define ERROR_JSON_LOADS 3063
|
||||
#define ERROR_RESPONSE_CODE 3064
|
||||
#define ERROR_RESPONSE_DATA 3065
|
||||
#define ERROR_REQUEST_DATA 3066
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// HTTP/StreamCaster protocol error.
|
||||
|
|
12
trunk/src/protocol/srs_http_stack.cpp
Normal file → Executable file
12
trunk/src/protocol/srs_http_stack.cpp
Normal file → Executable file
|
@ -246,7 +246,17 @@ SrsHttpRedirectHandler::~SrsHttpRedirectHandler()
|
|||
int SrsHttpRedirectHandler::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
// TODO: FIXME: implements it.
|
||||
string msg = "Moved Permsanently";
|
||||
|
||||
w->header()->set_content_type("text/plain; charset=utf-8");
|
||||
w->header()->set_content_length(msg.length());
|
||||
w->header()->set("Location", url);
|
||||
w->write_header(code);
|
||||
|
||||
w->write((char*)msg.data(), (int)msg.length());
|
||||
w->final_request();
|
||||
|
||||
srs_info("redirect to %s.", url.c_str());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue