mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
Refine typo in protocol.
This commit is contained in:
parent
35fe05d62c
commit
8bc77387ff
7 changed files with 1328 additions and 2117 deletions
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#include <srs_core.hpp>
|
#include <srs_core.hpp>
|
||||||
|
|
||||||
// default http listen port.
|
// Default http listen port.
|
||||||
#define SRS_DEFAULT_HTTP_PORT 80
|
#define SRS_DEFAULT_HTTP_PORT 80
|
||||||
|
|
||||||
#if !defined(SRS_EXPORT_LIBRTMP)
|
#if !defined(SRS_EXPORT_LIBRTMP)
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
|
// For srs-librtmp, @see https://github.com/ossrs/srs/issues/213
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,7 +46,7 @@ class ISrsHttpMessage;
|
||||||
class SrsHttpMuxEntry;
|
class SrsHttpMuxEntry;
|
||||||
class ISrsHttpResponseWriter;
|
class ISrsHttpResponseWriter;
|
||||||
|
|
||||||
// http specification
|
// From http specification
|
||||||
// CR = <US-ASCII CR, carriage return (13)>
|
// CR = <US-ASCII CR, carriage return (13)>
|
||||||
#define SRS_HTTP_CR SRS_CONSTS_CR // 0x0D
|
#define SRS_HTTP_CR SRS_CONSTS_CR // 0x0D
|
||||||
// LF = <US-ASCII LF, linefeed (10)>
|
// LF = <US-ASCII LF, linefeed (10)>
|
||||||
|
@ -65,10 +65,10 @@ class ISrsHttpResponseWriter;
|
||||||
// @see ISrsHttpMessage._http_ts_send_buffer
|
// @see ISrsHttpMessage._http_ts_send_buffer
|
||||||
#define SRS_HTTP_TS_SEND_BUFFER_SIZE 4096
|
#define SRS_HTTP_TS_SEND_BUFFER_SIZE 4096
|
||||||
|
|
||||||
// for ead all of http body, read each time.
|
// For ead all of http body, read each time.
|
||||||
#define SRS_HTTP_READ_CACHE_BYTES 4096
|
#define SRS_HTTP_READ_CACHE_BYTES 4096
|
||||||
|
|
||||||
// for http parser macros
|
// For http parser macros
|
||||||
#define SRS_CONSTS_HTTP_OPTIONS HTTP_OPTIONS
|
#define SRS_CONSTS_HTTP_OPTIONS HTTP_OPTIONS
|
||||||
#define SRS_CONSTS_HTTP_GET HTTP_GET
|
#define SRS_CONSTS_HTTP_GET HTTP_GET
|
||||||
#define SRS_CONSTS_HTTP_POST HTTP_POST
|
#define SRS_CONSTS_HTTP_POST HTTP_POST
|
||||||
|
@ -80,10 +80,10 @@ class ISrsHttpResponseWriter;
|
||||||
extern srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code);
|
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);
|
extern srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code, std::string error);
|
||||||
|
|
||||||
// get the status text of code.
|
// Get the status text of code.
|
||||||
extern std::string srs_generate_http_status_text(int status);
|
extern std::string srs_generate_http_status_text(int status);
|
||||||
|
|
||||||
// bodyAllowedForStatus reports whether a given response status code
|
// It reports whether a given response status code
|
||||||
// permits a body. See RFC2616, section 4.4.
|
// permits a body. See RFC2616, section 4.4.
|
||||||
extern bool srs_go_http_body_allowd(int status);
|
extern bool srs_go_http_body_allowd(int status);
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ extern bool srs_go_http_body_allowd(int status);
|
||||||
// returns "application/octet-stream".
|
// returns "application/octet-stream".
|
||||||
extern std::string srs_go_http_detect(char* data, int size);
|
extern std::string srs_go_http_detect(char* data, int size);
|
||||||
|
|
||||||
// state of message
|
// The state of HTTP message
|
||||||
enum SrsHttpParseState {
|
enum SrsHttpParseState {
|
||||||
SrsHttpParseStateInit = 0,
|
SrsHttpParseStateInit = 0,
|
||||||
SrsHttpParseStateStart,
|
SrsHttpParseStateStart,
|
||||||
|
@ -121,27 +121,17 @@ public:
|
||||||
// with CanonicalHeaderKey.
|
// with CanonicalHeaderKey.
|
||||||
virtual std::string get(std::string key);
|
virtual std::string get(std::string key);
|
||||||
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();
|
||||||
/**
|
// set the content length by header "Content-Length"
|
||||||
* set the content length by header "Content-Length"
|
|
||||||
*/
|
|
||||||
virtual void set_content_length(int64_t size);
|
virtual void set_content_length(int64_t size);
|
||||||
public:
|
public:
|
||||||
/**
|
// Get the content type. empty string if not set.
|
||||||
* get the content type. empty string if not set.
|
|
||||||
*/
|
|
||||||
virtual std::string content_type();
|
virtual std::string content_type();
|
||||||
/**
|
// set the content type by header "Content-Type"
|
||||||
* set the content type by header "Content-Type"
|
|
||||||
*/
|
|
||||||
virtual void set_content_type(std::string ct);
|
virtual void set_content_type(std::string ct);
|
||||||
public:
|
public:
|
||||||
/**
|
// write all headers to string stream.
|
||||||
* write all headers to string stream.
|
|
||||||
*/
|
|
||||||
virtual void write(std::stringstream& ss);
|
virtual void write(std::stringstream& ss);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -176,9 +166,9 @@ public:
|
||||||
ISrsHttpResponseWriter();
|
ISrsHttpResponseWriter();
|
||||||
virtual ~ISrsHttpResponseWriter();
|
virtual ~ISrsHttpResponseWriter();
|
||||||
public:
|
public:
|
||||||
// when chunked mode,
|
// When chunked mode,
|
||||||
// final the request to complete the chunked encoding.
|
// final the request to complete the chunked encoding.
|
||||||
// for no-chunked mode,
|
// For no-chunked mode,
|
||||||
// final to send request, for example, content-length is 0.
|
// final to send request, for example, content-length is 0.
|
||||||
virtual srs_error_t final_request() = 0;
|
virtual srs_error_t final_request() = 0;
|
||||||
|
|
||||||
|
@ -191,13 +181,11 @@ public:
|
||||||
// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
|
// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
|
||||||
// before writing the data. If the Header does not contain a
|
// before writing the data. If the Header does not contain a
|
||||||
// Content-Type line, Write adds a Content-Type set to the result of passing
|
// Content-Type line, Write adds a Content-Type set to the result of passing
|
||||||
// the initial 512 bytes of written data to DetectContentType.
|
// The initial 512 bytes of written data to DetectContentType.
|
||||||
// @param data, the data to send. NULL to flush header only.
|
// @param data, the data to send. NULL to flush header only.
|
||||||
virtual srs_error_t write(char* data, int size) = 0;
|
virtual srs_error_t write(char* data, int size) = 0;
|
||||||
/**
|
// for the HTTP FLV, to writev to improve performance.
|
||||||
* for the HTTP FLV, to writev to improve performance.
|
// @see https://github.com/ossrs/srs/issues/405
|
||||||
* @see https://github.com/ossrs/srs/issues/405
|
|
||||||
*/
|
|
||||||
virtual srs_error_t writev(const iovec* iov, int iovcnt, ssize_t* pnwrite) = 0;
|
virtual srs_error_t writev(const iovec* iov, int iovcnt, ssize_t* pnwrite) = 0;
|
||||||
|
|
||||||
// WriteHeader sends an HTTP response header with status code.
|
// WriteHeader sends an HTTP response header with status code.
|
||||||
|
@ -209,32 +197,26 @@ public:
|
||||||
virtual void write_header(int code) = 0;
|
virtual void write_header(int code) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The reader interface for http response.
|
||||||
* the reader interface for http response.
|
|
||||||
*/
|
|
||||||
class ISrsHttpResponseReader
|
class ISrsHttpResponseReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ISrsHttpResponseReader();
|
ISrsHttpResponseReader();
|
||||||
virtual ~ISrsHttpResponseReader();
|
virtual ~ISrsHttpResponseReader();
|
||||||
public:
|
public:
|
||||||
/**
|
// Whether response read EOF.
|
||||||
* whether response read EOF.
|
|
||||||
*/
|
|
||||||
virtual bool eof() = 0;
|
virtual bool eof() = 0;
|
||||||
/**
|
// Read from the response body.
|
||||||
* read from the response body.
|
// @param data, the buffer to read data buffer to.
|
||||||
* @param data, the buffer to read data buffer to.
|
// @param nb_data, the max size of data buffer.
|
||||||
* @param nb_data, the max size of data buffer.
|
// @param nb_read, the actual read size of bytes. NULL to ignore.
|
||||||
* @param nb_read, the actual read size of bytes. NULL to ignore.
|
// @remark when eof(), return error.
|
||||||
* @remark when eof(), return error.
|
// @remark for some server, the content-length not specified and not chunked,
|
||||||
* @remark for some server, the content-length not specified and not chunked,
|
// which is actually the infinite chunked encoding, which after http header
|
||||||
* which is actually the infinite chunked encoding, which after http header
|
// is http response data, it's ok for browser. that is,
|
||||||
* is http response data, it's ok for browser. that is,
|
// when user call this read, please ensure there is data to read(by content-length
|
||||||
* when user call this read, please ensure there is data to read(by content-length
|
// or by chunked), because the sdk never know whether there is no data or
|
||||||
* or by chunked), because the sdk never know whether there is no data or
|
// infinite chunked.
|
||||||
* infinite chunked.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t read(char* data, int nb_data, int* nb_read) = 0;
|
virtual srs_error_t read(char* data, int nb_data, int* nb_read) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -245,7 +227,7 @@ public:
|
||||||
// ServeHTTP should write reply headers and data to the ResponseWriter
|
// ServeHTTP should write reply headers and data to the ResponseWriter
|
||||||
// and then return. Returning signals that the request is finished
|
// and then return. Returning signals that the request is finished
|
||||||
// and that the HTTP server can move on to the next request on
|
// and that the HTTP server can move on to the next request on
|
||||||
// the connection.
|
// The connection.
|
||||||
class ISrsHttpHandler
|
class ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -300,33 +282,25 @@ public:
|
||||||
public:
|
public:
|
||||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||||
private:
|
private:
|
||||||
/**
|
// Serve the file by specified path
|
||||||
* serve the file by specified path
|
|
||||||
*/
|
|
||||||
virtual srs_error_t serve_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_flv_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
||||||
virtual srs_error_t serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
virtual srs_error_t serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
|
||||||
protected:
|
protected:
|
||||||
/**
|
// When access flv file with x.flv?start=xxx
|
||||||
* when access flv file with x.flv?start=xxx
|
|
||||||
*/
|
|
||||||
virtual srs_error_t 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
|
||||||
* when access mp4 file with x.mp4?range=start-end
|
// @param start the start offset in bytes.
|
||||||
* @param start the start offset in bytes.
|
// @param end the end offset in bytes. -1 to end of file.
|
||||||
* @param end the end offset in bytes. -1 to end of file.
|
// @remark response data in [start, end].
|
||||||
* @remark response data in [start, end].
|
|
||||||
*/
|
|
||||||
virtual srs_error_t 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:
|
protected:
|
||||||
/**
|
// Copy the fs to response writer in size bytes.
|
||||||
* copy the fs to response writer in size bytes.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t 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.
|
// The mux entry for server mux.
|
||||||
// the matcher info, for example, the pattern and handler.
|
// The matcher info, for example, the pattern and handler.
|
||||||
class SrsHttpMuxEntry
|
class SrsHttpMuxEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -339,26 +313,20 @@ public:
|
||||||
virtual ~SrsHttpMuxEntry();
|
virtual ~SrsHttpMuxEntry();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The hijacker for http pattern match.
|
||||||
* the hijacker for http pattern match.
|
|
||||||
*/
|
|
||||||
class ISrsHttpMatchHijacker
|
class ISrsHttpMatchHijacker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ISrsHttpMatchHijacker();
|
ISrsHttpMatchHijacker();
|
||||||
virtual ~ISrsHttpMatchHijacker();
|
virtual ~ISrsHttpMatchHijacker();
|
||||||
public:
|
public:
|
||||||
/**
|
// When match the request failed, no handler to process request.
|
||||||
* when match the request failed, no handler to process request.
|
// @param request the http request message to match the handler.
|
||||||
* @param request the http request message to match the handler.
|
// @param ph the already matched handler, hijack can rewrite it.
|
||||||
* @param ph the already matched handler, hijack can rewrite it.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) = 0;
|
virtual srs_error_t hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The server mux, all http server should implements it.
|
||||||
* the server mux, all http server should implements it.
|
|
||||||
*/
|
|
||||||
class ISrsHttpServeMux
|
class ISrsHttpServeMux
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -383,7 +351,7 @@ public:
|
||||||
// "/images/" subtree.
|
// "/images/" subtree.
|
||||||
//
|
//
|
||||||
// Note that since a pattern ending in a slash names a rooted subtree,
|
// Note that since a pattern ending in a slash names a rooted subtree,
|
||||||
// the pattern "/" matches all paths not matched by other registered
|
// The pattern "/" matches all paths not matched by other registered
|
||||||
// patterns, not just the URL with Path == "/".
|
// patterns, not just the URL with Path == "/".
|
||||||
//
|
//
|
||||||
// Patterns may optionally begin with a host name, restricting matches to
|
// Patterns may optionally begin with a host name, restricting matches to
|
||||||
|
@ -398,29 +366,25 @@ public:
|
||||||
class SrsHttpServeMux : public ISrsHttpServeMux
|
class SrsHttpServeMux : public ISrsHttpServeMux
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// the pattern handler, to handle the http request.
|
// The pattern handler, to handle the http request.
|
||||||
std::map<std::string, SrsHttpMuxEntry*> entries;
|
std::map<std::string, SrsHttpMuxEntry*> entries;
|
||||||
// the vhost handler.
|
// The vhost handler.
|
||||||
// when find the handler to process the request,
|
// When find the handler to process the request,
|
||||||
// append the matched vhost when pattern not starts with /,
|
// append the matched vhost when pattern not starts with /,
|
||||||
// for example, for pattern /live/livestream.flv of vhost ossrs.net,
|
// For example, for pattern /live/livestream.flv of vhost ossrs.net,
|
||||||
// the path will rewrite to ossrs.net/live/livestream.flv
|
// The path will rewrite to ossrs.net/live/livestream.flv
|
||||||
std::map<std::string, ISrsHttpHandler*> vhosts;
|
std::map<std::string, ISrsHttpHandler*> vhosts;
|
||||||
// all hijackers for http match.
|
// all hijackers for http match.
|
||||||
// for example, the hstrs(http stream trigger rtmp source)
|
// For example, the hstrs(http stream trigger rtmp source)
|
||||||
// can hijack and install handler when request incoming and no handler.
|
// can hijack and install handler when request incoming and no handler.
|
||||||
std::vector<ISrsHttpMatchHijacker*> hijackers;
|
std::vector<ISrsHttpMatchHijacker*> hijackers;
|
||||||
public:
|
public:
|
||||||
SrsHttpServeMux();
|
SrsHttpServeMux();
|
||||||
virtual ~SrsHttpServeMux();
|
virtual ~SrsHttpServeMux();
|
||||||
public:
|
public:
|
||||||
/**
|
// Initialize the http serve mux.
|
||||||
* initialize the http serve mux.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t initialize();
|
virtual srs_error_t initialize();
|
||||||
/**
|
// hijack the http match.
|
||||||
* hijack the http match.
|
|
||||||
*/
|
|
||||||
virtual void hijack(ISrsHttpMatchHijacker* h);
|
virtual void hijack(ISrsHttpMatchHijacker* h);
|
||||||
virtual void unhijack(ISrsHttpMatchHijacker* h);
|
virtual void unhijack(ISrsHttpMatchHijacker* h);
|
||||||
public:
|
public:
|
||||||
|
@ -437,10 +401,8 @@ private:
|
||||||
virtual bool path_match(std::string pattern, std::string path);
|
virtual bool path_match(std::string pattern, std::string path);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The filter http mux, directly serve the http CORS requests,
|
||||||
* The filter http mux, directly serve the http CORS requests,
|
// while proxy to the worker mux for services.
|
||||||
* while proxy to the worker mux for services.
|
|
||||||
*/
|
|
||||||
class SrsHttpCorsMux : public ISrsHttpServeMux
|
class SrsHttpCorsMux : public ISrsHttpServeMux
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -457,7 +419,7 @@ public:
|
||||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
// for http header.
|
// For http header.
|
||||||
typedef std::pair<std::string, std::string> SrsHttpHeaderField;
|
typedef std::pair<std::string, std::string> SrsHttpHeaderField;
|
||||||
|
|
||||||
// A Request represents an HTTP request received by a server
|
// A Request represents an HTTP request received by a server
|
||||||
|
@ -473,34 +435,28 @@ typedef std::pair<std::string, std::string> SrsHttpHeaderField;
|
||||||
// 3. no body or user not confirmed infinite chunked.
|
// 3. no body or user not confirmed infinite chunked.
|
||||||
// For example:
|
// For example:
|
||||||
// ISrsHttpMessage* r = ...;
|
// ISrsHttpMessage* r = ...;
|
||||||
// while (!r->eof()) r->read(); // read in mode 1 or 3.
|
// while (!r->eof()) r->read(); // Read in mode 1 or 3.
|
||||||
// For some server, we can confirm the body is infinite chunked:
|
// For some server, we can confirm the body is infinite chunked:
|
||||||
// ISrsHttpMessage* r = ...;
|
// ISrsHttpMessage* r = ...;
|
||||||
// r->enter_infinite_chunked();
|
// r->enter_infinite_chunked();
|
||||||
// while (!r->eof()) r->read(); // read in mode 2
|
// while (!r->eof()) r->read(); // Read in mode 2
|
||||||
// @rmark for mode 2, the infinite chunked, all left data is body.
|
// @rmark for mode 2, the infinite chunked, all left data is body.
|
||||||
class ISrsHttpMessage
|
class ISrsHttpMessage
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/**
|
// Use a buffer to read and send ts file.
|
||||||
* use a buffer to read and send ts file.
|
|
||||||
*/
|
|
||||||
// TODO: FIXME: remove it.
|
// TODO: FIXME: remove it.
|
||||||
char* _http_ts_send_buffer;
|
char* _http_ts_send_buffer;
|
||||||
public:
|
public:
|
||||||
ISrsHttpMessage();
|
ISrsHttpMessage();
|
||||||
virtual ~ISrsHttpMessage();
|
virtual ~ISrsHttpMessage();
|
||||||
public:
|
public:
|
||||||
/**
|
// The http request level cache.
|
||||||
* the http request level cache.
|
|
||||||
*/
|
|
||||||
virtual char* http_ts_send_buffer();
|
virtual char* http_ts_send_buffer();
|
||||||
public:
|
public:
|
||||||
virtual uint8_t method() = 0;
|
virtual uint8_t method() = 0;
|
||||||
virtual uint16_t status_code() = 0;
|
virtual uint16_t status_code() = 0;
|
||||||
/**
|
// Method helpers.
|
||||||
* method helpers.
|
|
||||||
*/
|
|
||||||
virtual std::string method_str() = 0;
|
virtual std::string method_str() = 0;
|
||||||
virtual bool is_http_get() = 0;
|
virtual bool is_http_get() = 0;
|
||||||
virtual bool is_http_put() = 0;
|
virtual bool is_http_put() = 0;
|
||||||
|
@ -508,94 +464,74 @@ public:
|
||||||
virtual bool is_http_delete() = 0;
|
virtual bool is_http_delete() = 0;
|
||||||
virtual bool is_http_options() = 0;
|
virtual bool is_http_options() = 0;
|
||||||
public:
|
public:
|
||||||
/**
|
// Whether should keep the connection alive.
|
||||||
* whether should keep the connection alive.
|
|
||||||
*/
|
|
||||||
virtual bool is_keep_alive() = 0;
|
virtual bool is_keep_alive() = 0;
|
||||||
/**
|
// The uri contains the host and path.
|
||||||
* the uri contains the host and path.
|
|
||||||
*/
|
|
||||||
virtual std::string uri() = 0;
|
virtual std::string uri() = 0;
|
||||||
/**
|
// The url maybe the path.
|
||||||
* the url maybe the path.
|
|
||||||
*/
|
|
||||||
virtual std::string url() = 0;
|
virtual std::string url() = 0;
|
||||||
virtual std::string host() = 0;
|
virtual std::string host() = 0;
|
||||||
virtual std::string path() = 0;
|
virtual std::string path() = 0;
|
||||||
virtual std::string query() = 0;
|
virtual std::string query() = 0;
|
||||||
virtual std::string ext() = 0;
|
virtual std::string ext() = 0;
|
||||||
/**
|
// Get the RESTful id,
|
||||||
* get the RESTful id,
|
// for example, pattern is /api/v1/streams, path is /api/v1/streams/100,
|
||||||
* for example, pattern is /api/v1/streams, path is /api/v1/streams/100,
|
// then the rest id is 100.
|
||||||
* then the rest id is 100.
|
// @param pattern the handler pattern which will serve the request.
|
||||||
* @param pattern the handler pattern which will serve the request.
|
// @return the REST id; -1 if not matched.
|
||||||
* @return the REST id; -1 if not matched.
|
|
||||||
*/
|
|
||||||
virtual int parse_rest_id(std::string pattern) = 0;
|
virtual int parse_rest_id(std::string pattern) = 0;
|
||||||
public:
|
public:
|
||||||
/**
|
// The left all data is chunked body, the infinite chunked mode,
|
||||||
* the left all data is chunked body, the infinite chunked mode,
|
// which is chunked encoding without chunked header.
|
||||||
* which is chunked encoding without chunked header.
|
// @remark error when message is in chunked or content-length specified.
|
||||||
* @remark error when message is in chunked or content-length specified.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t enter_infinite_chunked() = 0;
|
virtual srs_error_t enter_infinite_chunked() = 0;
|
||||||
/**
|
// Read body to string.
|
||||||
* read body to string.
|
// @remark for small http body.
|
||||||
* @remark for small http body.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t body_read_all(std::string& body) = 0;
|
virtual srs_error_t body_read_all(std::string& body) = 0;
|
||||||
/**
|
// Get the body reader, to read one by one.
|
||||||
* get the body reader, to read one by one.
|
// @remark when body is very large, or chunked, use this.
|
||||||
* @remark when body is very large, or chunked, use this.
|
|
||||||
*/
|
|
||||||
virtual ISrsHttpResponseReader* body_reader() = 0;
|
virtual ISrsHttpResponseReader* body_reader() = 0;
|
||||||
/**
|
// The content length, -1 for chunked or not set.
|
||||||
* the content length, -1 for chunked or not set.
|
|
||||||
*/
|
|
||||||
virtual int64_t content_length() = 0;
|
virtual int64_t content_length() = 0;
|
||||||
public:
|
public:
|
||||||
/**
|
// Get the param in query string,
|
||||||
* get the param in query string,
|
// for instance, query is "start=100&end=200",
|
||||||
* for instance, query is "start=100&end=200",
|
// then query_get("start") is "100", and query_get("end") is "200"
|
||||||
* then query_get("start") is "100", and query_get("end") is "200"
|
|
||||||
*/
|
|
||||||
virtual std::string query_get(std::string key) = 0;
|
virtual std::string query_get(std::string key) = 0;
|
||||||
/**
|
// Get the headers.
|
||||||
* get the headers.
|
|
||||||
*/
|
|
||||||
virtual int request_header_count() = 0;
|
virtual int request_header_count() = 0;
|
||||||
virtual std::string request_header_key_at(int index) = 0;
|
virtual std::string request_header_key_at(int index) = 0;
|
||||||
virtual std::string request_header_value_at(int index) = 0;
|
virtual std::string request_header_value_at(int index) = 0;
|
||||||
public:
|
public:
|
||||||
/**
|
// Whether the current request is JSONP,
|
||||||
* whether the current request is JSONP,
|
// which has a "callback=xxx" in QueryString.
|
||||||
* which has a "callback=xxx" in QueryString.
|
|
||||||
*/
|
|
||||||
virtual bool is_jsonp() = 0;
|
virtual bool is_jsonp() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
// The http-parser is license under MIT at https://github.com/nodejs/http-parser/blob/master/LICENSE-MIT
|
||||||
*
|
// Version: 2.1 from https://github.com/nodejs/http-parser/releases/tag/v2.1
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to
|
//Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||||
* deal in the Software without restriction, including without limitation the
|
//
|
||||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* sell copies of the Software, and to permit persons to whom the Software is
|
// of this software and associated documentation files (the "Software"), to
|
||||||
* furnished to do so, subject to the following conditions:
|
// deal in the Software without restriction, including without limitation the
|
||||||
*
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
* The above copyright notice and this permission notice shall be included in
|
// sell copies of the Software, and to permit persons to whom the Software is
|
||||||
* all copies or substantial portions of the Software.
|
// furnished to do so, subject to the following conditions:
|
||||||
*
|
//
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
// The above copyright notice and this permission notice shall be included in
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
// all copies or substantial portions of the Software.
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
//
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
// The SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* IN THE SOFTWARE.
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
*/
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
// IN THE SOFTWARE.
|
||||||
#ifndef http_parser_h
|
#ifndef http_parser_h
|
||||||
#define http_parser_h
|
#define http_parser_h
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -621,9 +557,8 @@ extern "C" {
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
|
// Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
|
||||||
* faster
|
// faster
|
||||||
*/
|
|
||||||
#ifndef HTTP_PARSER_STRICT
|
#ifndef HTTP_PARSER_STRICT
|
||||||
# define HTTP_PARSER_STRICT 1
|
# define HTTP_PARSER_STRICT 1
|
||||||
#endif
|
#endif
|
||||||
|
@ -636,19 +571,18 @@ extern "C" {
|
||||||
typedef struct http_parser_settings http_parser_settings;
|
typedef struct http_parser_settings http_parser_settings;
|
||||||
|
|
||||||
|
|
||||||
/* Callbacks should return non-zero to indicate an error. The parser will
|
// Callbacks should return non-zero to indicate an error. The parser will
|
||||||
* then halt execution.
|
// then halt execution.
|
||||||
*
|
//
|
||||||
* The one exception is on_headers_complete. In a HTTP_RESPONSE parser
|
// The one exception is on_headers_complete. In a HTTP_RESPONSE parser
|
||||||
* returning '1' from on_headers_complete will tell the parser that it
|
// returning '1' from on_headers_complete will tell the parser that it
|
||||||
* should not expect a body. This is used when receiving a response to a
|
// should not expect a body. This is used when receiving a response to a
|
||||||
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
|
// HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
|
||||||
* chunked' headers that indicate the presence of a body.
|
// chunked' headers that indicate the presence of a body.
|
||||||
*
|
//
|
||||||
* http_data_cb does not return data chunks. It will be call arbitrarally
|
// http_data_cb does not return data chunks. It will be call arbitrarally
|
||||||
* many times for each string. E.G. you might get 10 callbacks for "on_url"
|
// many times for each string. E.G. you might get 10 callbacks for "on_url"
|
||||||
* each providing just a few characters more data.
|
// each providing just a few characters more data.
|
||||||
*/
|
|
||||||
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
|
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
|
||||||
typedef int (*http_cb) (http_parser*);
|
typedef int (*http_cb) (http_parser*);
|
||||||
|
|
||||||
|
@ -709,10 +643,8 @@ extern "C" {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Map for errno-related constants
|
// Map for errno-related constants
|
||||||
*
|
// The provided argument should be a macro that takes 2 arguments.
|
||||||
* The provided argument should be a macro that takes 2 arguments.
|
|
||||||
*/
|
|
||||||
#define HTTP_ERRNO_MAP(XX) \
|
#define HTTP_ERRNO_MAP(XX) \
|
||||||
/* No error */ \
|
/* No error */ \
|
||||||
XX(OK, "success") \
|
XX(OK, "success") \
|
||||||
|
@ -785,11 +717,10 @@ extern "C" {
|
||||||
unsigned char method; /* requests only */
|
unsigned char method; /* requests only */
|
||||||
unsigned char http_errno : 7;
|
unsigned char http_errno : 7;
|
||||||
|
|
||||||
/* 1 = Upgrade header was present and the parser has exited because of that.
|
// 1 = Upgrade header was present and the parser has exited because of that.
|
||||||
* 0 = No upgrade header present.
|
// 0 = No upgrade header present.
|
||||||
* Should be checked when http_parser_execute() returns in addition to
|
// Should be checked when http_parser_execute() returns in addition to
|
||||||
* error checking.
|
// error checking.
|
||||||
*/
|
|
||||||
unsigned char upgrade : 1;
|
unsigned char upgrade : 1;
|
||||||
|
|
||||||
/** PUBLIC **/
|
/** PUBLIC **/
|
||||||
|
@ -821,13 +752,11 @@ extern "C" {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Result structure for http_parser_parse_url().
|
// Result structure for http_parser_parse_url().
|
||||||
*
|
// Callers should index into field_data[] with UF_* values iff field_set
|
||||||
* Callers should index into field_data[] with UF_* values iff field_set
|
// has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
|
||||||
* has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
|
// because we probably have padding left over), we convert any port to
|
||||||
* because we probably have padding left over), we convert any port to
|
// a uint16_t.
|
||||||
* a uint16_t.
|
|
||||||
*/
|
|
||||||
struct http_parser_url {
|
struct http_parser_url {
|
||||||
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
|
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
|
||||||
uint16_t port; /* Converted UF_PORT string */
|
uint16_t port; /* Converted UF_PORT string */
|
||||||
|
@ -848,12 +777,11 @@ extern "C" {
|
||||||
size_t len);
|
size_t len);
|
||||||
|
|
||||||
|
|
||||||
/* If http_should_keep_alive() in the on_headers_complete or
|
// If http_should_keep_alive() in the on_headers_complete or
|
||||||
* on_message_complete callback returns 0, then this should be
|
// on_message_complete callback returns 0, then this should be
|
||||||
* the last message on the connection.
|
// The last message on the connection.
|
||||||
* If you are the server, respond with the "Connection: close" header.
|
// If you are the server, respond with the "Connection: close" header.
|
||||||
* If you are the client, close the connection.
|
// If you are the client, close the connection.
|
||||||
*/
|
|
||||||
int http_should_keep_alive(const http_parser *parser);
|
int http_should_keep_alive(const http_parser *parser);
|
||||||
|
|
||||||
/* Returns a string version of the HTTP method. */
|
/* Returns a string version of the HTTP method. */
|
||||||
|
@ -881,9 +809,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
// Used to resolve the http uri.
|
||||||
* used to resolve the http uri.
|
|
||||||
*/
|
|
||||||
class SrsHttpUri
|
class SrsHttpUri
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -897,9 +823,7 @@ public:
|
||||||
SrsHttpUri();
|
SrsHttpUri();
|
||||||
virtual ~SrsHttpUri();
|
virtual ~SrsHttpUri();
|
||||||
public:
|
public:
|
||||||
/**
|
// Initialize the http uri.
|
||||||
* initialize the http uri.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t initialize(std::string _url);
|
virtual srs_error_t initialize(std::string _url);
|
||||||
public:
|
public:
|
||||||
virtual std::string get_url();
|
virtual std::string get_url();
|
||||||
|
@ -909,10 +833,8 @@ public:
|
||||||
virtual std::string get_path();
|
virtual std::string get_path();
|
||||||
virtual std::string get_query();
|
virtual std::string get_query();
|
||||||
private:
|
private:
|
||||||
/**
|
// Get the parsed url field.
|
||||||
* get the parsed url field.
|
// @return return empty string if not set.
|
||||||
* @return return empty string if not set.
|
|
||||||
*/
|
|
||||||
virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field);
|
virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// json decode
|
// JSON decode
|
||||||
// 1. SrsJsonAny: read any from str:char*
|
// 1. SrsJsonAny: read any from str:char*
|
||||||
// SrsJsonAny* any = NULL;
|
// SrsJsonAny* any = NULL;
|
||||||
// if ((any = SrsJsonAny::loads(str)) == NULL) {
|
// if ((any = SrsJsonAny::loads(str)) == NULL) {
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
// string v = any->to_str();
|
// string v = any->to_str();
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// for detail usage, see interfaces of each object.
|
// For detail usage, see interfaces of each object.
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -59,8 +59,8 @@ class SrsJsonAny
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
char marker;
|
char marker;
|
||||||
// donot directly create this object,
|
// Don't directly create this object,
|
||||||
// instead, for examle, use SrsJsonAny::str() to create a concreated one.
|
// please use SrsJsonAny::str() to create a concreated one.
|
||||||
protected:
|
protected:
|
||||||
SrsJsonAny();
|
SrsJsonAny();
|
||||||
public:
|
public:
|
||||||
|
@ -74,35 +74,23 @@ public:
|
||||||
virtual bool is_array();
|
virtual bool is_array();
|
||||||
virtual bool is_null();
|
virtual bool is_null();
|
||||||
public:
|
public:
|
||||||
/**
|
// Get the string of any when is_string() indicates true.
|
||||||
* get the string of any when is_string() indicates true.
|
// user must ensure the type is a string, or assert failed.
|
||||||
* user must ensure the type is a string, or assert failed.
|
|
||||||
*/
|
|
||||||
virtual std::string to_str();
|
virtual std::string to_str();
|
||||||
/**
|
// Get the boolean of any when is_boolean() indicates true.
|
||||||
* get the boolean of any when is_boolean() indicates true.
|
// user must ensure the type is a boolean, or assert failed.
|
||||||
* user must ensure the type is a boolean, or assert failed.
|
|
||||||
*/
|
|
||||||
virtual bool to_boolean();
|
virtual bool to_boolean();
|
||||||
/**
|
// Get the integer of any when is_integer() indicates true.
|
||||||
* get the integer of any when is_integer() indicates true.
|
// user must ensure the type is a integer, or assert failed.
|
||||||
* user must ensure the type is a integer, or assert failed.
|
|
||||||
*/
|
|
||||||
virtual int64_t to_integer();
|
virtual int64_t to_integer();
|
||||||
/**
|
// Get the number of any when is_number() indicates true.
|
||||||
* get the number of any when is_number() indicates true.
|
// user must ensure the type is a number, or assert failed.
|
||||||
* user must ensure the type is a number, or assert failed.
|
|
||||||
*/
|
|
||||||
virtual double to_number();
|
virtual double to_number();
|
||||||
/**
|
// Get the object of any when is_object() indicates true.
|
||||||
* get the object of any when is_object() indicates true.
|
// user must ensure the type is a object, or assert failed.
|
||||||
* user must ensure the type is a object, or assert failed.
|
|
||||||
*/
|
|
||||||
virtual SrsJsonObject* to_object();
|
virtual SrsJsonObject* to_object();
|
||||||
/**
|
// Get the ecma array of any when is_ecma_array() indicates true.
|
||||||
* get the ecma array of any when is_ecma_array() indicates true.
|
// user must ensure the type is a ecma array, or assert failed.
|
||||||
* user must ensure the type is a ecma array, or assert failed.
|
|
||||||
*/
|
|
||||||
virtual SrsJsonArray* to_array();
|
virtual SrsJsonArray* to_array();
|
||||||
public:
|
public:
|
||||||
virtual std::string dumps();
|
virtual std::string dumps();
|
||||||
|
@ -117,10 +105,8 @@ public:
|
||||||
static SrsJsonObject* object();
|
static SrsJsonObject* object();
|
||||||
static SrsJsonArray* array();
|
static SrsJsonArray* array();
|
||||||
public:
|
public:
|
||||||
/**
|
// Read json tree from string.
|
||||||
* read json tree from string.
|
// @return json object. NULL if error.
|
||||||
* @return json object. NULL if error.
|
|
||||||
*/
|
|
||||||
static SrsJsonAny* loads(const std::string& str);
|
static SrsJsonAny* loads(const std::string& str);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,7 +116,7 @@ private:
|
||||||
typedef std::pair<std::string, SrsJsonAny*> SrsJsonObjectPropertyType;
|
typedef std::pair<std::string, SrsJsonAny*> SrsJsonObjectPropertyType;
|
||||||
std::vector<SrsJsonObjectPropertyType> properties;
|
std::vector<SrsJsonObjectPropertyType> properties;
|
||||||
private:
|
private:
|
||||||
// use SrsJsonAny::object() to create it.
|
// Use SrsJsonAny::object() to create it.
|
||||||
friend class SrsJsonAny;
|
friend class SrsJsonAny;
|
||||||
SrsJsonObject();
|
SrsJsonObject();
|
||||||
public:
|
public:
|
||||||
|
@ -161,7 +147,7 @@ private:
|
||||||
std::vector<SrsJsonAny*> properties;
|
std::vector<SrsJsonAny*> properties;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// use SrsJsonAny::array() to create it.
|
// Use SrsJsonAny::array() to create it.
|
||||||
friend class SrsJsonAny;
|
friend class SrsJsonAny;
|
||||||
SrsJsonArray();
|
SrsJsonArray();
|
||||||
public:
|
public:
|
||||||
|
@ -181,6 +167,6 @@ public:
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// json encode, please use JSON.dumps() to encode json object.
|
// JSON encode, please use JSON.dumps() to encode json object.
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,61 +32,45 @@
|
||||||
|
|
||||||
class SrsBuffer;
|
class SrsBuffer;
|
||||||
|
|
||||||
/**
|
// The raw h.264 stream, in annexb.
|
||||||
* the raw h.264 stream, in annexb.
|
|
||||||
*/
|
|
||||||
class SrsRawH264Stream
|
class SrsRawH264Stream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsRawH264Stream();
|
SrsRawH264Stream();
|
||||||
virtual ~SrsRawH264Stream();
|
virtual ~SrsRawH264Stream();
|
||||||
public:
|
public:
|
||||||
/**
|
// Demux the stream in annexb format.
|
||||||
* demux the stream in annexb format.
|
// @param stream the input stream bytes.
|
||||||
* @param stream the input stream bytes.
|
// @param pframe the output h.264 frame in stream. user should never free it.
|
||||||
* @param pframe the output h.264 frame in stream. user should never free it.
|
// @param pnb_frame the output h.264 frame size.
|
||||||
* @param pnb_frame the output h.264 frame size.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_frame);
|
virtual srs_error_t annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_frame);
|
||||||
/**
|
// whether the frame is sps or pps.
|
||||||
* whether the frame is sps or pps.
|
|
||||||
*/
|
|
||||||
virtual bool is_sps(char* frame, int nb_frame);
|
virtual bool is_sps(char* frame, int nb_frame);
|
||||||
virtual bool is_pps(char* frame, int nb_frame);
|
virtual bool is_pps(char* frame, int nb_frame);
|
||||||
/**
|
// Demux the sps or pps to string.
|
||||||
* demux the sps or pps to string.
|
// @param sps/pps output the sps/pps.
|
||||||
* @param sps/pps output the sps/pps.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t sps_demux(char* frame, int nb_frame, std::string& sps);
|
virtual srs_error_t sps_demux(char* frame, int nb_frame, std::string& sps);
|
||||||
virtual srs_error_t pps_demux(char* frame, int nb_frame, std::string& pps);
|
virtual srs_error_t pps_demux(char* frame, int nb_frame, std::string& pps);
|
||||||
public:
|
public:
|
||||||
/**
|
// The h264 raw data to h264 packet, without flv payload header.
|
||||||
* h264 raw data to h264 packet, without flv payload header.
|
// Mux the sps/pps to flv sequence header packet.
|
||||||
* mux the sps/pps to flv sequence header packet.
|
// @param sh output the sequence header.
|
||||||
* @param sh output the sequence header.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t mux_sequence_header(std::string sps, std::string pps, uint32_t dts, uint32_t pts, std::string& sh);
|
virtual srs_error_t mux_sequence_header(std::string sps, std::string pps, uint32_t dts, uint32_t pts, std::string& sh);
|
||||||
/**
|
// The h264 raw data to h264 packet, without flv payload header.
|
||||||
* h264 raw data to h264 packet, without flv payload header.
|
// Mux the ibp to flv ibp packet.
|
||||||
* mux the ibp to flv ibp packet.
|
// @param ibp output the packet.
|
||||||
* @param ibp output the packet.
|
// @param frame_type output the frame type.
|
||||||
* @param frame_type output the frame type.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t mux_ipb_frame(char* frame, int nb_frame, std::string& ibp);
|
virtual srs_error_t mux_ipb_frame(char* frame, int nb_frame, std::string& ibp);
|
||||||
/**
|
// Mux the avc video packet to flv video packet.
|
||||||
* mux the avc video packet to flv video packet.
|
// @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame.
|
||||||
* @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame.
|
// @param avc_packet_type, SrsVideoAvcFrameTraitSequenceHeader or SrsVideoAvcFrameTraitNALU.
|
||||||
* @param avc_packet_type, SrsVideoAvcFrameTraitSequenceHeader or SrsVideoAvcFrameTraitNALU.
|
// @param video the h.264 raw data.
|
||||||
* @param video the h.264 raw data.
|
// @param flv output the muxed flv packet.
|
||||||
* @param flv output the muxed flv packet.
|
// @param nb_flv output the muxed flv size.
|
||||||
* @param nb_flv output the muxed flv size.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char** flv, int* nb_flv);
|
virtual srs_error_t mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char** flv, int* nb_flv);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The header of adts sample.
|
||||||
* the header of adts sample.
|
|
||||||
*/
|
|
||||||
struct SrsRawAacStreamCodec
|
struct SrsRawAacStreamCodec
|
||||||
{
|
{
|
||||||
int8_t protection_absent;
|
int8_t protection_absent;
|
||||||
|
@ -103,37 +87,29 @@ struct SrsRawAacStreamCodec
|
||||||
int8_t aac_packet_type;
|
int8_t aac_packet_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The raw aac stream, in adts.
|
||||||
* the raw aac stream, in adts.
|
|
||||||
*/
|
|
||||||
class SrsRawAacStream
|
class SrsRawAacStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsRawAacStream();
|
SrsRawAacStream();
|
||||||
virtual ~SrsRawAacStream();
|
virtual ~SrsRawAacStream();
|
||||||
public:
|
public:
|
||||||
/**
|
// Demux the stream in adts format.
|
||||||
* demux the stream in adts format.
|
// @param stream the input stream bytes.
|
||||||
* @param stream the input stream bytes.
|
// @param pframe the output aac frame in stream. user should never free it.
|
||||||
* @param pframe the output aac frame in stream. user should never free it.
|
// @param pnb_frame the output aac frame size.
|
||||||
* @param pnb_frame the output aac frame size.
|
// @param codec the output codec info.
|
||||||
* @param codec the output codec info.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec);
|
virtual srs_error_t adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec);
|
||||||
/**
|
// Mux aac raw data to aac packet, without flv payload header.
|
||||||
* aac raw data to aac packet, without flv payload header.
|
// Mux the aac specific config to flv sequence header packet.
|
||||||
* mux the aac specific config to flv sequence header packet.
|
// @param sh output the sequence header.
|
||||||
* @param sh output the sequence header.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t mux_sequence_header(SrsRawAacStreamCodec* codec, std::string& sh);
|
virtual srs_error_t mux_sequence_header(SrsRawAacStreamCodec* codec, std::string& sh);
|
||||||
/**
|
// Mux the aac audio packet to flv audio packet.
|
||||||
* mux the aac audio packet to flv audio packet.
|
// @param frame the aac raw data.
|
||||||
* @param frame the aac raw data.
|
// @param nb_frame the count of aac frame.
|
||||||
* @param nb_frame the count of aac frame.
|
// @param codec the codec info of aac.
|
||||||
* @param codec the codec info of aac.
|
// @param flv output the muxed flv packet.
|
||||||
* @param flv output the muxed flv packet.
|
// @param nb_flv output the muxed flv size.
|
||||||
* @param nb_flv output the muxed flv size.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, uint32_t dts, char** flv, int* nb_flv);
|
virtual srs_error_t mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, uint32_t dts, char** flv, int* nb_flv);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,21 +31,19 @@ class SrsComplexHandshake;
|
||||||
class SrsHandshakeBytes;
|
class SrsHandshakeBytes;
|
||||||
class SrsBuffer;
|
class SrsBuffer;
|
||||||
|
|
||||||
// for openssl.
|
// For openssl.
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
|
|
||||||
namespace _srs_internal
|
namespace _srs_internal
|
||||||
{
|
{
|
||||||
// the digest key generate size.
|
// The digest key generate size.
|
||||||
#define SRS_OpensslHashSize 512
|
#define SRS_OpensslHashSize 512
|
||||||
extern uint8_t SrsGenuineFMSKey[];
|
extern uint8_t SrsGenuineFMSKey[];
|
||||||
extern uint8_t SrsGenuineFPKey[];
|
extern uint8_t SrsGenuineFPKey[];
|
||||||
srs_error_t openssl_HMACsha256(const void* key, int key_size, const void* data, int data_size, void* digest);
|
srs_error_t openssl_HMACsha256(const void* key, int key_size, const void* data, int data_size, void* digest);
|
||||||
srs_error_t openssl_generate_key(char* public_key, int32_t size);
|
srs_error_t openssl_generate_key(char* public_key, int32_t size);
|
||||||
|
|
||||||
/**
|
// The DH wrapper.
|
||||||
* the DH wrapper.
|
|
||||||
*/
|
|
||||||
class SrsDH
|
class SrsDH
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -56,62 +54,48 @@ namespace _srs_internal
|
||||||
private:
|
private:
|
||||||
virtual void close();
|
virtual void close();
|
||||||
public:
|
public:
|
||||||
/**
|
// Initialize dh, generate the public and private key.
|
||||||
* initialize dh, generate the public and private key.
|
// @param ensure_128bytes_public_key whether ensure public key is 128bytes,
|
||||||
* @param ensure_128bytes_public_key whether ensure public key is 128bytes,
|
// sometimes openssl generate 127bytes public key.
|
||||||
* sometimes openssl generate 127bytes public key.
|
// default to false to donot ensure.
|
||||||
* default to false to donot ensure.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t initialize(bool ensure_128bytes_public_key = false);
|
virtual srs_error_t initialize(bool ensure_128bytes_public_key = false);
|
||||||
/**
|
// Copy the public key.
|
||||||
* copy the public key.
|
// @param pkey the bytes to copy the public key.
|
||||||
* @param pkey the bytes to copy the public key.
|
// @param pkey_size the max public key size, output the actual public key size.
|
||||||
* @param pkey_size the max public key size, output the actual public key size.
|
// user should never ignore this size.
|
||||||
* user should never ignore this size.
|
// @remark, when ensure_128bytes_public_key, the size always 128.
|
||||||
* @remark, when ensure_128bytes_public_key, the size always 128.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t copy_public_key(char* pkey, int32_t& pkey_size);
|
virtual srs_error_t copy_public_key(char* pkey, int32_t& pkey_size);
|
||||||
/**
|
// Generate and copy the shared key.
|
||||||
* generate and copy the shared key.
|
// Generate the shared key with peer public key.
|
||||||
* generate the shared key with peer public key.
|
// @param ppkey peer public key.
|
||||||
* @param ppkey peer public key.
|
// @param ppkey_size the size of ppkey.
|
||||||
* @param ppkey_size the size of ppkey.
|
// @param skey the computed shared key.
|
||||||
* @param skey the computed shared key.
|
// @param skey_size the max shared key size, output the actual shared key size.
|
||||||
* @param skey_size the max shared key size, output the actual shared key size.
|
// user should never ignore this size.
|
||||||
* user should never ignore this size.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t copy_shared_key(const char* ppkey, int32_t ppkey_size, char* skey, int32_t& skey_size);
|
virtual srs_error_t copy_shared_key(const char* ppkey, int32_t ppkey_size, char* skey, int32_t& skey_size);
|
||||||
private:
|
private:
|
||||||
virtual srs_error_t do_initialize();
|
virtual srs_error_t do_initialize();
|
||||||
};
|
};
|
||||||
/**
|
// The schema type.
|
||||||
* the schema type.
|
|
||||||
*/
|
|
||||||
enum srs_schema_type
|
enum srs_schema_type
|
||||||
{
|
{
|
||||||
srs_schema_invalid = 2,
|
srs_schema_invalid = 2,
|
||||||
|
|
||||||
/**
|
// The key-digest sequence
|
||||||
* key-digest sequence
|
|
||||||
*/
|
|
||||||
srs_schema0 = 0,
|
srs_schema0 = 0,
|
||||||
|
|
||||||
/**
|
// The digest-key sequence
|
||||||
* digest-key sequence
|
// @remark, FMS requires the schema1(digest-key), or connect failed.
|
||||||
* @remark, FMS requires the schema1(digest-key), or connect failed.
|
|
||||||
*/
|
|
||||||
//
|
//
|
||||||
srs_schema1 = 1,
|
srs_schema1 = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The 764bytes key structure
|
||||||
* 764bytes key structure
|
// random-data: (offset)bytes
|
||||||
* random-data: (offset)bytes
|
// key-data: 128bytes
|
||||||
* key-data: 128bytes
|
// random-data: (764-offset-128-4)bytes
|
||||||
* random-data: (764-offset-128-4)bytes
|
// offset: 4bytes
|
||||||
* offset: 4bytes
|
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||||
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
|
||||||
*/
|
|
||||||
class key_block
|
class key_block
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -132,24 +116,22 @@ namespace _srs_internal
|
||||||
key_block();
|
key_block();
|
||||||
virtual ~key_block();
|
virtual ~key_block();
|
||||||
public:
|
public:
|
||||||
// parse key block from c1s1.
|
// Parse key block from c1s1.
|
||||||
// if created, user must free it by srs_key_block_free
|
// if created, user must free it by srs_key_block_free
|
||||||
// @stream contains c1s1_key_bytes the key start bytes
|
// @stream contains c1s1_key_bytes the key start bytes
|
||||||
srs_error_t parse(SrsBuffer* stream);
|
srs_error_t parse(SrsBuffer* stream);
|
||||||
private:
|
private:
|
||||||
// calc the offset of key,
|
// Calculate the offset of key,
|
||||||
// the key->offset cannot be used as the offset of key.
|
// The key->offset cannot be used as the offset of key.
|
||||||
int calc_valid_offset();
|
int calc_valid_offset();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The 764bytes digest structure
|
||||||
* 764bytes digest structure
|
// offset: 4bytes
|
||||||
* offset: 4bytes
|
// random-data: (offset)bytes
|
||||||
* random-data: (offset)bytes
|
// digest-data: 32bytes
|
||||||
* digest-data: 32bytes
|
// random-data: (764-4-offset-32)bytes
|
||||||
* random-data: (764-4-offset-32)bytes
|
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||||
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
|
||||||
*/
|
|
||||||
class digest_block
|
class digest_block
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -170,23 +152,21 @@ namespace _srs_internal
|
||||||
digest_block();
|
digest_block();
|
||||||
virtual ~digest_block();
|
virtual ~digest_block();
|
||||||
public:
|
public:
|
||||||
// parse digest block from c1s1.
|
// Parse digest block from c1s1.
|
||||||
// if created, user must free it by srs_digest_block_free
|
// if created, user must free it by srs_digest_block_free
|
||||||
// @stream contains c1s1_digest_bytes the digest start bytes
|
// @stream contains c1s1_digest_bytes the digest start bytes
|
||||||
srs_error_t parse(SrsBuffer* stream);
|
srs_error_t parse(SrsBuffer* stream);
|
||||||
private:
|
private:
|
||||||
// calc the offset of digest,
|
// Calculate the offset of digest,
|
||||||
// the key->offset cannot be used as the offset of digest.
|
// The key->offset cannot be used as the offset of digest.
|
||||||
int calc_valid_offset();
|
int calc_valid_offset();
|
||||||
};
|
};
|
||||||
|
|
||||||
class c1s1;
|
class c1s1;
|
||||||
|
|
||||||
/**
|
// The c1s1 strategy, use schema0 or schema1.
|
||||||
* the c1s1 strategy, use schema0 or schema1.
|
// The template method class to defines common behaviors,
|
||||||
* the template method class to defines common behaviors,
|
// while the concrete class to implements in schema0 or schema1.
|
||||||
* while the concrete class to implements in schema0 or schema1.
|
|
||||||
*/
|
|
||||||
class c1s1_strategy
|
class c1s1_strategy
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -196,114 +176,82 @@ namespace _srs_internal
|
||||||
c1s1_strategy();
|
c1s1_strategy();
|
||||||
virtual ~c1s1_strategy();
|
virtual ~c1s1_strategy();
|
||||||
public:
|
public:
|
||||||
/**
|
// Get the scema.
|
||||||
* get the scema.
|
|
||||||
*/
|
|
||||||
virtual srs_schema_type schema() = 0;
|
virtual srs_schema_type schema() = 0;
|
||||||
/**
|
// Get the digest.
|
||||||
* get the digest.
|
|
||||||
*/
|
|
||||||
virtual char* get_digest();
|
virtual char* get_digest();
|
||||||
/**
|
// Get the key.
|
||||||
* get the key.
|
|
||||||
*/
|
|
||||||
virtual char* get_key();
|
virtual char* get_key();
|
||||||
/**
|
// Copy to bytes.
|
||||||
* copy to bytes.
|
// @param size must be 1536.
|
||||||
* @param size must be 1536.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t dump(c1s1* owner, char* _c1s1, int size);
|
virtual srs_error_t dump(c1s1* owner, char* _c1s1, int size);
|
||||||
/**
|
// For server: parse the c1s1, discovery the key and digest by schema.
|
||||||
* server: parse the c1s1, discovery the key and digest by schema.
|
// use the c1_validate_digest() to valid the digest of c1.
|
||||||
* use the c1_validate_digest() to valid the digest of c1.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t parse(char* _c1s1, int size) = 0;
|
virtual srs_error_t parse(char* _c1s1, int size) = 0;
|
||||||
public:
|
public:
|
||||||
/**
|
// For client: create and sign c1 by schema.
|
||||||
* client: create and sign c1 by schema.
|
// sign the c1, generate the digest.
|
||||||
* sign the c1, generate the digest.
|
// calc_c1_digest(c1, schema) {
|
||||||
* calc_c1_digest(c1, schema) {
|
// get c1s1-joined from c1 by specified schema
|
||||||
* get c1s1-joined from c1 by specified schema
|
// digest-data = HMACsha256(c1s1-joined, FPKey, 30)
|
||||||
* digest-data = HMACsha256(c1s1-joined, FPKey, 30)
|
// return digest-data;
|
||||||
* return digest-data;
|
// }
|
||||||
* }
|
// random fill 1536bytes c1 // also fill the c1-128bytes-key
|
||||||
* random fill 1536bytes c1 // also fill the c1-128bytes-key
|
// time = time() // c1[0-3]
|
||||||
* time = time() // c1[0-3]
|
// version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
|
||||||
* version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
|
// schema = choose schema0 or schema1
|
||||||
* schema = choose schema0 or schema1
|
// digest-data = calc_c1_digest(c1, schema)
|
||||||
* digest-data = calc_c1_digest(c1, schema)
|
// copy digest-data to c1
|
||||||
* copy digest-data to c1
|
|
||||||
*/
|
|
||||||
virtual srs_error_t c1_create(c1s1* owner);
|
virtual srs_error_t c1_create(c1s1* owner);
|
||||||
/**
|
// For server: validate the parsed c1 schema
|
||||||
* server: validate the parsed c1 schema
|
|
||||||
*/
|
|
||||||
virtual srs_error_t c1_validate_digest(c1s1* owner, bool& is_valid);
|
virtual srs_error_t c1_validate_digest(c1s1* owner, bool& is_valid);
|
||||||
/**
|
// For server: create and sign the s1 from c1.
|
||||||
* server: create and sign the s1 from c1.
|
// // decode c1 try schema0 then schema1
|
||||||
* // decode c1 try schema0 then schema1
|
// c1-digest-data = get-c1-digest-data(schema0)
|
||||||
* c1-digest-data = get-c1-digest-data(schema0)
|
// if c1-digest-data equals to calc_c1_digest(c1, schema0) {
|
||||||
* if c1-digest-data equals to calc_c1_digest(c1, schema0) {
|
// c1-key-data = get-c1-key-data(schema0)
|
||||||
* c1-key-data = get-c1-key-data(schema0)
|
// schema = schema0
|
||||||
* schema = schema0
|
// } else {
|
||||||
* } else {
|
// c1-digest-data = get-c1-digest-data(schema1)
|
||||||
* c1-digest-data = get-c1-digest-data(schema1)
|
// if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
|
||||||
* if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
|
// switch to simple handshake.
|
||||||
* switch to simple handshake.
|
// return
|
||||||
* return
|
// }
|
||||||
* }
|
// c1-key-data = get-c1-key-data(schema1)
|
||||||
* c1-key-data = get-c1-key-data(schema1)
|
// schema = schema1
|
||||||
* schema = schema1
|
// }
|
||||||
* }
|
//
|
||||||
*
|
// // Generate s1
|
||||||
* // generate s1
|
// random fill 1536bytes s1
|
||||||
* random fill 1536bytes s1
|
// time = time() // c1[0-3]
|
||||||
* time = time() // c1[0-3]
|
// version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
|
||||||
* version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
|
// s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
|
||||||
* s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
|
// get c1s1-joined by specified schema
|
||||||
* get c1s1-joined by specified schema
|
// s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
|
||||||
* s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
|
// copy s1-digest-data and s1-key-data to s1.
|
||||||
* copy s1-digest-data and s1-key-data to s1.
|
// @param c1, to get the peer_pub_key of client.
|
||||||
* @param c1, to get the peer_pub_key of client.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t s1_create(c1s1* owner, c1s1* c1);
|
virtual srs_error_t s1_create(c1s1* owner, c1s1* c1);
|
||||||
/**
|
// For server: validate the parsed s1 schema
|
||||||
* server: validate the parsed s1 schema
|
|
||||||
*/
|
|
||||||
virtual srs_error_t s1_validate_digest(c1s1* owner, bool& is_valid);
|
virtual srs_error_t s1_validate_digest(c1s1* owner, bool& is_valid);
|
||||||
public:
|
public:
|
||||||
/**
|
// Calculate the digest for c1
|
||||||
* calc the digest for c1
|
|
||||||
*/
|
|
||||||
virtual srs_error_t calc_c1_digest(c1s1* owner, char*& c1_digest);
|
virtual srs_error_t calc_c1_digest(c1s1* owner, char*& c1_digest);
|
||||||
/**
|
// Calculate the digest for s1
|
||||||
* calc the digest for s1
|
|
||||||
*/
|
|
||||||
virtual srs_error_t calc_s1_digest(c1s1* owner, char*& s1_digest);
|
virtual srs_error_t calc_s1_digest(c1s1* owner, char*& s1_digest);
|
||||||
/**
|
// Copy whole c1s1 to bytes.
|
||||||
* copy whole c1s1 to bytes.
|
// @param size must always be 1536 with digest, and 1504 without digest.
|
||||||
* @param size must always be 1536 with digest, and 1504 without digest.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest) = 0;
|
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest) = 0;
|
||||||
/**
|
// Copy time and version to stream.
|
||||||
* copy time and version to stream.
|
|
||||||
*/
|
|
||||||
virtual void copy_time_version(SrsBuffer* stream, c1s1* owner);
|
virtual void copy_time_version(SrsBuffer* stream, c1s1* owner);
|
||||||
/**
|
// Copy key to stream.
|
||||||
* copy key to stream.
|
|
||||||
*/
|
|
||||||
virtual void copy_key(SrsBuffer* stream);
|
virtual void copy_key(SrsBuffer* stream);
|
||||||
/**
|
// Copy digest to stream.
|
||||||
* copy digest to stream.
|
|
||||||
*/
|
|
||||||
virtual void copy_digest(SrsBuffer* stream, bool with_digest);
|
virtual void copy_digest(SrsBuffer* stream, bool with_digest);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The c1s1 schema0
|
||||||
* c1s1 schema0
|
// key: 764bytes
|
||||||
* key: 764bytes
|
// digest: 764bytes
|
||||||
* digest: 764bytes
|
|
||||||
*/
|
|
||||||
class c1s1_strategy_schema0 : public c1s1_strategy
|
class c1s1_strategy_schema0 : public c1s1_strategy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -316,11 +264,9 @@ namespace _srs_internal
|
||||||
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest);
|
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The c1s1 schema1
|
||||||
* c1s1 schema1
|
// digest: 764bytes
|
||||||
* digest: 764bytes
|
// key: 764bytes
|
||||||
* key: 764bytes
|
|
||||||
*/
|
|
||||||
class c1s1_strategy_schema1 : public c1s1_strategy
|
class c1s1_strategy_schema1 : public c1s1_strategy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -333,19 +279,17 @@ namespace _srs_internal
|
||||||
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest);
|
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The c1s1 schema0
|
||||||
* c1s1 schema0
|
// time: 4bytes
|
||||||
* time: 4bytes
|
// version: 4bytes
|
||||||
* version: 4bytes
|
// key: 764bytes
|
||||||
* key: 764bytes
|
// digest: 764bytes
|
||||||
* digest: 764bytes
|
// The c1s1 schema1
|
||||||
* c1s1 schema1
|
// time: 4bytes
|
||||||
* time: 4bytes
|
// version: 4bytes
|
||||||
* version: 4bytes
|
// digest: 764bytes
|
||||||
* digest: 764bytes
|
// key: 764bytes
|
||||||
* key: 764bytes
|
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||||
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
|
||||||
*/
|
|
||||||
class c1s1
|
class c1s1
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -359,92 +303,72 @@ namespace _srs_internal
|
||||||
c1s1();
|
c1s1();
|
||||||
virtual ~c1s1();
|
virtual ~c1s1();
|
||||||
public:
|
public:
|
||||||
/**
|
// Get the scema.
|
||||||
* get the scema.
|
|
||||||
*/
|
|
||||||
virtual srs_schema_type schema();
|
virtual srs_schema_type schema();
|
||||||
/**
|
// Get the digest key.
|
||||||
* get the digest key.
|
|
||||||
*/
|
|
||||||
virtual char* get_digest();
|
virtual char* get_digest();
|
||||||
/**
|
// Get the key.
|
||||||
* get the key.
|
|
||||||
*/
|
|
||||||
virtual char* get_key();
|
virtual char* get_key();
|
||||||
public:
|
public:
|
||||||
/**
|
// Copy to bytes.
|
||||||
* copy to bytes.
|
// @param size, must always be 1536.
|
||||||
* @param size, must always be 1536.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t dump(char* _c1s1, int size);
|
virtual srs_error_t dump(char* _c1s1, int size);
|
||||||
/**
|
// For server: parse the c1s1, discovery the key and digest by schema.
|
||||||
* server: parse the c1s1, discovery the key and digest by schema.
|
// @param size, must always be 1536.
|
||||||
* @param size, must always be 1536.
|
// use the c1_validate_digest() to valid the digest of c1.
|
||||||
* use the c1_validate_digest() to valid the digest of c1.
|
// use the s1_validate_digest() to valid the digest of s1.
|
||||||
* use the s1_validate_digest() to valid the digest of s1.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t parse(char* _c1s1, int size, srs_schema_type _schema);
|
virtual srs_error_t parse(char* _c1s1, int size, srs_schema_type _schema);
|
||||||
public:
|
public:
|
||||||
/**
|
// For client: create and sign c1 by schema.
|
||||||
* client: create and sign c1 by schema.
|
// sign the c1, generate the digest.
|
||||||
* sign the c1, generate the digest.
|
// calc_c1_digest(c1, schema) {
|
||||||
* calc_c1_digest(c1, schema) {
|
// get c1s1-joined from c1 by specified schema
|
||||||
* get c1s1-joined from c1 by specified schema
|
// digest-data = HMACsha256(c1s1-joined, FPKey, 30)
|
||||||
* digest-data = HMACsha256(c1s1-joined, FPKey, 30)
|
// return digest-data;
|
||||||
* return digest-data;
|
// }
|
||||||
* }
|
// random fill 1536bytes c1 // also fill the c1-128bytes-key
|
||||||
* random fill 1536bytes c1 // also fill the c1-128bytes-key
|
// time = time() // c1[0-3]
|
||||||
* time = time() // c1[0-3]
|
// version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
|
||||||
* version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
|
// schema = choose schema0 or schema1
|
||||||
* schema = choose schema0 or schema1
|
// digest-data = calc_c1_digest(c1, schema)
|
||||||
* digest-data = calc_c1_digest(c1, schema)
|
// copy digest-data to c1
|
||||||
* copy digest-data to c1
|
|
||||||
*/
|
|
||||||
virtual srs_error_t c1_create(srs_schema_type _schema);
|
virtual srs_error_t c1_create(srs_schema_type _schema);
|
||||||
/**
|
// For server: validate the parsed c1 schema
|
||||||
* server: validate the parsed c1 schema
|
|
||||||
*/
|
|
||||||
virtual srs_error_t c1_validate_digest(bool& is_valid);
|
virtual srs_error_t c1_validate_digest(bool& is_valid);
|
||||||
public:
|
public:
|
||||||
/**
|
// For server: create and sign the s1 from c1.
|
||||||
* server: create and sign the s1 from c1.
|
// // decode c1 try schema0 then schema1
|
||||||
* // decode c1 try schema0 then schema1
|
// c1-digest-data = get-c1-digest-data(schema0)
|
||||||
* c1-digest-data = get-c1-digest-data(schema0)
|
// if c1-digest-data equals to calc_c1_digest(c1, schema0) {
|
||||||
* if c1-digest-data equals to calc_c1_digest(c1, schema0) {
|
// c1-key-data = get-c1-key-data(schema0)
|
||||||
* c1-key-data = get-c1-key-data(schema0)
|
// schema = schema0
|
||||||
* schema = schema0
|
// } else {
|
||||||
* } else {
|
// c1-digest-data = get-c1-digest-data(schema1)
|
||||||
* c1-digest-data = get-c1-digest-data(schema1)
|
// if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
|
||||||
* if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
|
// switch to simple handshake.
|
||||||
* switch to simple handshake.
|
// return
|
||||||
* return
|
// }
|
||||||
* }
|
// c1-key-data = get-c1-key-data(schema1)
|
||||||
* c1-key-data = get-c1-key-data(schema1)
|
// schema = schema1
|
||||||
* schema = schema1
|
// }
|
||||||
* }
|
//
|
||||||
*
|
// // Generate s1
|
||||||
* // generate s1
|
// random fill 1536bytes s1
|
||||||
* random fill 1536bytes s1
|
// time = time() // c1[0-3]
|
||||||
* time = time() // c1[0-3]
|
// version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
|
||||||
* version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
|
// s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
|
||||||
* s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
|
// get c1s1-joined by specified schema
|
||||||
* get c1s1-joined by specified schema
|
// s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
|
||||||
* s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
|
// copy s1-digest-data and s1-key-data to s1.
|
||||||
* copy s1-digest-data and s1-key-data to s1.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t s1_create(c1s1* c1);
|
virtual srs_error_t s1_create(c1s1* c1);
|
||||||
/**
|
// For server: validate the parsed s1 schema
|
||||||
* server: validate the parsed s1 schema
|
|
||||||
*/
|
|
||||||
virtual srs_error_t s1_validate_digest(bool& is_valid);
|
virtual srs_error_t s1_validate_digest(bool& is_valid);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The c2s2 complex handshake structure.
|
||||||
* the c2s2 complex handshake structure.
|
// random-data: 1504bytes
|
||||||
* random-data: 1504bytes
|
// digest-data: 32bytes
|
||||||
* digest-data: 32bytes
|
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||||
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
|
||||||
*/
|
|
||||||
class c2s2
|
class c2s2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -454,85 +378,65 @@ namespace _srs_internal
|
||||||
c2s2();
|
c2s2();
|
||||||
virtual ~c2s2();
|
virtual ~c2s2();
|
||||||
public:
|
public:
|
||||||
/**
|
// Copy to bytes.
|
||||||
* copy to bytes.
|
// @param size, must always be 1536.
|
||||||
* @param size, must always be 1536.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t dump(char* _c2s2, int size);
|
virtual srs_error_t dump(char* _c2s2, int size);
|
||||||
/**
|
// Parse the c2s2
|
||||||
* parse the c2s2
|
// @param size, must always be 1536.
|
||||||
* @param size, must always be 1536.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t parse(char* _c2s2, int size);
|
virtual srs_error_t parse(char* _c2s2, int size);
|
||||||
public:
|
public:
|
||||||
/**
|
// Create c2.
|
||||||
* create c2.
|
// random fill c2s2 1536 bytes
|
||||||
* random fill c2s2 1536 bytes
|
//
|
||||||
*
|
// // client generate C2, or server valid C2
|
||||||
* // client generate C2, or server valid C2
|
// temp-key = HMACsha256(s1-digest, FPKey, 62)
|
||||||
* temp-key = HMACsha256(s1-digest, FPKey, 62)
|
// c2-digest-data = HMACsha256(c2-random-data, temp-key, 32)
|
||||||
* c2-digest-data = HMACsha256(c2-random-data, temp-key, 32)
|
|
||||||
*/
|
|
||||||
virtual srs_error_t c2_create(c1s1* s1);
|
virtual srs_error_t c2_create(c1s1* s1);
|
||||||
|
|
||||||
/**
|
// Validate the c2 from client.
|
||||||
* validate the c2 from client.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t c2_validate(c1s1* s1, bool& is_valid);
|
virtual srs_error_t c2_validate(c1s1* s1, bool& is_valid);
|
||||||
public:
|
public:
|
||||||
/**
|
// Create s2.
|
||||||
* create s2.
|
// random fill c2s2 1536 bytes
|
||||||
* random fill c2s2 1536 bytes
|
//
|
||||||
*
|
// For server generate S2, or client valid S2
|
||||||
* // server generate S2, or client valid S2
|
// temp-key = HMACsha256(c1-digest, FMSKey, 68)
|
||||||
* temp-key = HMACsha256(c1-digest, FMSKey, 68)
|
// s2-digest-data = HMACsha256(s2-random-data, temp-key, 32)
|
||||||
* s2-digest-data = HMACsha256(s2-random-data, temp-key, 32)
|
|
||||||
*/
|
|
||||||
virtual srs_error_t s2_create(c1s1* c1);
|
virtual srs_error_t s2_create(c1s1* c1);
|
||||||
|
|
||||||
/**
|
// Validate the s2 from server.
|
||||||
* validate the s2 from server.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t s2_validate(c1s1* c1, bool& is_valid);
|
virtual srs_error_t s2_validate(c1s1* c1, bool& is_valid);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Simple handshake.
|
||||||
* simple handshake.
|
// user can try complex handshake first,
|
||||||
* user can try complex handshake first,
|
// rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS
|
||||||
* rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS
|
|
||||||
*/
|
|
||||||
class SrsSimpleHandshake
|
class SrsSimpleHandshake
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsSimpleHandshake();
|
SrsSimpleHandshake();
|
||||||
virtual ~SrsSimpleHandshake();
|
virtual ~SrsSimpleHandshake();
|
||||||
public:
|
public:
|
||||||
/**
|
// Simple handshake.
|
||||||
* simple handshake.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
||||||
virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// Complex handshake,
|
||||||
* rtmp complex handshake,
|
// @see also crtmp(crtmpserver) or librtmp,
|
||||||
* @see also crtmp(crtmpserver) or librtmp,
|
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||||
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
|
||||||
*/
|
|
||||||
class SrsComplexHandshake
|
class SrsComplexHandshake
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsComplexHandshake();
|
SrsComplexHandshake();
|
||||||
virtual ~SrsComplexHandshake();
|
virtual ~SrsComplexHandshake();
|
||||||
public:
|
public:
|
||||||
/**
|
// Complex hanshake.
|
||||||
* complex hanshake.
|
// @return user must:
|
||||||
* @return user must:
|
// continue connect app if success,
|
||||||
* continue connect app if success,
|
// try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS,
|
||||||
* try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS,
|
// otherwise, disconnect
|
||||||
* otherwise, disconnect
|
|
||||||
*/
|
|
||||||
virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
||||||
virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,43 +28,31 @@
|
||||||
|
|
||||||
class SrsSharedPtrMessage;
|
class SrsSharedPtrMessage;
|
||||||
|
|
||||||
/**
|
// The class to auto free the shared ptr message array.
|
||||||
* the class to auto free the shared ptr message array.
|
// When need to get some messages, for instance, from Consumer queue,
|
||||||
* when need to get some messages, for instance, from Consumer queue,
|
// create a message array, whose msgs can used to accept the msgs,
|
||||||
* create a message array, whose msgs can used to accept the msgs,
|
// then send each message and set to NULL.
|
||||||
* then send each message and set to NULL.
|
//
|
||||||
*
|
// @remark: user must free all msgs in array, for the SRS2.0 protocol stack
|
||||||
* @remark: user must free all msgs in array, for the SRS2.0 protocol stack
|
// provides an api to send messages, @see send_and_free_messages
|
||||||
* provides an api to send messages, @see send_and_free_messages
|
|
||||||
*/
|
|
||||||
class SrsMessageArray
|
class SrsMessageArray
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
// When user already send all msgs, please set to NULL,
|
||||||
* when user already send all msgs, please set to NULL,
|
// for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg),
|
||||||
* for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg),
|
// where send(msg) will always send and free it.
|
||||||
* where send(msg) will always send and free it.
|
|
||||||
*/
|
|
||||||
SrsSharedPtrMessage** msgs;
|
SrsSharedPtrMessage** msgs;
|
||||||
int max;
|
int max;
|
||||||
public:
|
public:
|
||||||
/**
|
// Create msg array, initialize array to NULL ptrs.
|
||||||
* create msg array, initialize array to NULL ptrs.
|
|
||||||
*/
|
|
||||||
SrsMessageArray(int max_msgs);
|
SrsMessageArray(int max_msgs);
|
||||||
/**
|
// Free the msgs not sent out(not NULL).
|
||||||
* free the msgs not sent out(not NULL).
|
|
||||||
*/
|
|
||||||
virtual ~SrsMessageArray();
|
virtual ~SrsMessageArray();
|
||||||
public:
|
public:
|
||||||
/**
|
// Free specified count of messages.
|
||||||
* free specified count of messages.
|
|
||||||
*/
|
|
||||||
virtual void free(int count);
|
virtual void free(int count);
|
||||||
private:
|
private:
|
||||||
/**
|
// Zero initialize the message array.
|
||||||
* zero initialize the message array.
|
|
||||||
*/
|
|
||||||
virtual void zero(int count);
|
virtual void zero(int count);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,7 +38,7 @@ class SrsSimpleStream;
|
||||||
class SrsAudioFrame;
|
class SrsAudioFrame;
|
||||||
class ISrsProtocolReadWriter;
|
class ISrsProtocolReadWriter;
|
||||||
|
|
||||||
// rtsp specification
|
// From rtsp specification
|
||||||
// CR = <US-ASCII CR, carriage return (13)>
|
// CR = <US-ASCII CR, carriage return (13)>
|
||||||
#define SRS_RTSP_CR SRS_CONSTS_CR // 0x0D
|
#define SRS_RTSP_CR SRS_CONSTS_CR // 0x0D
|
||||||
// LF = <US-ASCII LF, linefeed (10)>
|
// LF = <US-ASCII LF, linefeed (10)>
|
||||||
|
@ -78,38 +78,28 @@ class ISrsProtocolReadWriter;
|
||||||
// RTSP-Version
|
// RTSP-Version
|
||||||
#define SRS_RTSP_VERSION "RTSP/1.0"
|
#define SRS_RTSP_VERSION "RTSP/1.0"
|
||||||
|
|
||||||
/**
|
// The rtsp sdp parse state.
|
||||||
* the rtsp sdp parse state.
|
|
||||||
*/
|
|
||||||
enum SrsRtspSdpState
|
enum SrsRtspSdpState
|
||||||
{
|
{
|
||||||
/**
|
// Other sdp properties.
|
||||||
* other sdp properties.
|
|
||||||
*/
|
|
||||||
SrsRtspSdpStateOthers,
|
SrsRtspSdpStateOthers,
|
||||||
/**
|
// Parse sdp audio state.
|
||||||
* parse sdp audio state.
|
|
||||||
*/
|
|
||||||
SrsRtspSdpStateAudio,
|
SrsRtspSdpStateAudio,
|
||||||
/**
|
// Parse sdp video state.
|
||||||
* parse sdp video state.
|
|
||||||
*/
|
|
||||||
SrsRtspSdpStateVideo,
|
SrsRtspSdpStateVideo,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57
|
||||||
* 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57
|
// The method token indicates the method to be performed on the resource
|
||||||
* The method token indicates the method to be performed on the resource
|
// identified by the Request-URI. The method is case-sensitive. New
|
||||||
* identified by the Request-URI. The method is case-sensitive. New
|
// methods may be defined in the future. Method names may not start with
|
||||||
* methods may be defined in the future. Method names may not start with
|
// a $ character (decimal 24) and must be a token. Methods are
|
||||||
* a $ character (decimal 24) and must be a token. Methods are
|
// summarized in Table 2.
|
||||||
* summarized in Table 2.
|
// Notes on Table 2: PAUSE is recommended, but not required in that a
|
||||||
* Notes on Table 2: PAUSE is recommended, but not required in that a
|
// fully functional server can be built that does not support this
|
||||||
* fully functional server can be built that does not support this
|
// method, for example, for live feeds. If a server does not support a
|
||||||
* method, for example, for live feeds. If a server does not support a
|
// particular method, it MUST return "501 Not Implemented" and a client
|
||||||
* particular method, it MUST return "501 Not Implemented" and a client
|
// SHOULD not try this method again for this server.
|
||||||
* SHOULD not try this method again for this server.
|
|
||||||
*/
|
|
||||||
enum SrsRtspMethod
|
enum SrsRtspMethod
|
||||||
{
|
{
|
||||||
SrsRtspMethodDescribe = 0x0001,
|
SrsRtspMethodDescribe = 0x0001,
|
||||||
|
@ -125,237 +115,187 @@ enum SrsRtspMethod
|
||||||
SrsRtspMethodTeardown = 0x0400,
|
SrsRtspMethodTeardown = 0x0400,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The state of rtsp token.
|
||||||
* the state of rtsp token.
|
|
||||||
*/
|
|
||||||
enum SrsRtspTokenState
|
enum SrsRtspTokenState
|
||||||
{
|
{
|
||||||
/**
|
// Parse token failed, default state.
|
||||||
* parse token failed, default state.
|
|
||||||
*/
|
|
||||||
SrsRtspTokenStateError = 100,
|
SrsRtspTokenStateError = 100,
|
||||||
/**
|
// When SP follow the token.
|
||||||
* when SP follow the token.
|
|
||||||
*/
|
|
||||||
SrsRtspTokenStateNormal = 101,
|
SrsRtspTokenStateNormal = 101,
|
||||||
/**
|
// When CRLF follow the token.
|
||||||
* when CRLF follow the token.
|
|
||||||
*/
|
|
||||||
SrsRtspTokenStateEOF = 102,
|
SrsRtspTokenStateEOF = 102,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The rtp packet.
|
||||||
* the rtp packet.
|
// 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12
|
||||||
* 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12
|
|
||||||
*/
|
|
||||||
class SrsRtpPacket
|
class SrsRtpPacket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
// The version (V): 2 bits
|
||||||
* version (V): 2 bits
|
// This field identifies the version of RTP. The version defined by this specification is two (2).
|
||||||
* This field identifies the version of RTP. The version defined by this specification is two (2).
|
// (The value 1 is used by the first draft version of RTP and the value 0 is used by the protocol
|
||||||
* (The value 1 is used by the first draft version of RTP and the value 0 is used by the protocol
|
// initially implemented in the \vat" audio tool.)
|
||||||
* initially implemented in the \vat" audio tool.)
|
|
||||||
*/
|
|
||||||
int8_t version; //2bits
|
int8_t version; //2bits
|
||||||
/**
|
// The padding (P): 1 bit
|
||||||
* padding (P): 1 bit
|
// If the padding bit is set, the packet contains one or more additional padding octets at the
|
||||||
* If the padding bit is set, the packet contains one or more additional padding octets at the
|
// end which are not part of the payload. The last octet of the padding contains a count of
|
||||||
* end which are not part of the payload. The last octet of the padding contains a count of
|
// how many padding octets should be ignored, including itself. Padding may be needed by
|
||||||
* how many padding octets should be ignored, including itself. Padding may be needed by
|
// some encryption algorithms with fixed block sizes or for carrying several RTP packets in a
|
||||||
* some encryption algorithms with fixed block sizes or for carrying several RTP packets in a
|
// lower-layer protocol data unit.
|
||||||
* lower-layer protocol data unit.
|
|
||||||
*/
|
|
||||||
int8_t padding; //1bit
|
int8_t padding; //1bit
|
||||||
/**
|
// The extension (X): 1 bit
|
||||||
* extension (X): 1 bit
|
// If the extension bit is set, the fixed header must be followed by exactly one header extension,
|
||||||
* If the extension bit is set, the fixed header must be followed by exactly one header extension,
|
// with a format defined in Section 5.3.1.
|
||||||
* with a format defined in Section 5.3.1.
|
|
||||||
*/
|
|
||||||
int8_t extension; //1bit
|
int8_t extension; //1bit
|
||||||
/**
|
// The CSRC count (CC): 4 bits
|
||||||
* CSRC count (CC): 4 bits
|
// The CSRC count contains the number of CSRC identifiers that follow the fixed header.
|
||||||
* The CSRC count contains the number of CSRC identifiers that follow the fixed header.
|
|
||||||
*/
|
|
||||||
int8_t csrc_count; //4bits
|
int8_t csrc_count; //4bits
|
||||||
/**
|
// The marker (M): 1 bit
|
||||||
* marker (M): 1 bit
|
// The interpretation of the marker is defined by a profile. It is intended to allow significant
|
||||||
* The interpretation of the marker is defined by a profile. It is intended to allow significant
|
// events such as frame boundaries to be marked in the packet stream. A profile may define
|
||||||
* events such as frame boundaries to be marked in the packet stream. A profile may define
|
// additional marker bits or specify that there is no marker bit by changing the number of bits
|
||||||
* additional marker bits or specify that there is no marker bit by changing the number of bits
|
// in the payload type field (see Section 5.3).
|
||||||
* in the payload type field (see Section 5.3).
|
|
||||||
*/
|
|
||||||
int8_t marker; //1bit
|
int8_t marker; //1bit
|
||||||
/**
|
// The payload type (PT): 7 bits
|
||||||
* payload type (PT): 7 bits
|
// This field identifies the format of the RTP payload and determines its interpretation by the
|
||||||
* This field identifies the format of the RTP payload and determines its interpretation by the
|
// application. A profile may specify a default static mapping of payload type codes to payload
|
||||||
* application. A profile may specify a default static mapping of payload type codes to payload
|
// formats. Additional payload type codes may be defined dynamically through non-RTP means
|
||||||
* formats. Additional payload type codes may be defined dynamically through non-RTP means
|
// (see Section 3). A set of default mappings for audio and video is specified in the companion
|
||||||
* (see Section 3). A set of default mappings for audio and video is specified in the companion
|
// RFC 3551 [1]. An RTP source may change the payload type during a session, but this field
|
||||||
* RFC 3551 [1]. An RTP source may change the payload type during a session, but this field
|
// should not be used for multiplexing separate media streams (see Section 5.2).
|
||||||
* should not be used for multiplexing separate media streams (see Section 5.2).
|
// A receiver must ignore packets with payload types that it does not understand.
|
||||||
* A receiver must ignore packets with payload types that it does not understand.
|
|
||||||
*/
|
|
||||||
int8_t payload_type; //7bits
|
int8_t payload_type; //7bits
|
||||||
/**
|
// The sequence number: 16 bits
|
||||||
* sequence number: 16 bits
|
// The sequence number increments by one for each RTP data packet sent, and may be used
|
||||||
* The sequence number increments by one for each RTP data packet sent, and may be used
|
// by the receiver to detect packet loss and to restore packet sequence. The initial value of the
|
||||||
* by the receiver to detect packet loss and to restore packet sequence. The initial value of the
|
// sequence number should be random (unpredictable) to make known-plaintext attacks on
|
||||||
* sequence number should be random (unpredictable) to make known-plaintext attacks on
|
// encryption more dicult, even if the source itself does not encrypt according to the method
|
||||||
* encryption more dicult, even if the source itself does not encrypt according to the method
|
// in Section 9.1, because the packets may flow through a translator that does. Techniques for
|
||||||
* in Section 9.1, because the packets may flow through a translator that does. Techniques for
|
// choosing unpredictable numbers are discussed in [17].
|
||||||
* choosing unpredictable numbers are discussed in [17].
|
|
||||||
*/
|
|
||||||
uint16_t sequence_number; //16bits
|
uint16_t sequence_number; //16bits
|
||||||
/**
|
// The timestamp: 32 bits
|
||||||
* timestamp: 32 bits
|
// The timestamp reflects the sampling instant of the first octet in the RTP data packet. The
|
||||||
* The timestamp reflects the sampling instant of the first octet in the RTP data packet. The
|
// sampling instant must be derived from a clock that increments monotonically and linearly
|
||||||
* sampling instant must be derived from a clock that increments monotonically and linearly
|
// in time to allow synchronization and jitter calculations (see Section 6.4.1). The resolution
|
||||||
* in time to allow synchronization and jitter calculations (see Section 6.4.1). The resolution
|
// of the clock must be sucient for the desired synchronization accuracy and for measuring
|
||||||
* of the clock must be sucient for the desired synchronization accuracy and for measuring
|
// packet arrival jitter (one tick per video frame is typically not sucient). The clock frequency
|
||||||
* packet arrival jitter (one tick per video frame is typically not sucient). The clock frequency
|
// is dependent on the format of data carried as payload and is specified statically in the profile
|
||||||
* is dependent on the format of data carried as payload and is specified statically in the profile
|
// or payload format specification that defines the format, or may be specified dynamically for
|
||||||
* or payload format specification that defines the format, or may be specified dynamically for
|
// payload formats defined through non-RTP means. If RTP packets are generated periodically,
|
||||||
* payload formats defined through non-RTP means. If RTP packets are generated periodically,
|
// The nominal sampling instant as determined from the sampling clock is to be used, not a
|
||||||
* the nominal sampling instant as determined from the sampling clock is to be used, not a
|
// reading of the system clock. As an example, for fixed-rate audio the timestamp clock would
|
||||||
* reading of the system clock. As an example, for fixed-rate audio the timestamp clock would
|
// likely increment by one for each sampling period. If an audio application reads blocks covering
|
||||||
* likely increment by one for each sampling period. If an audio application reads blocks covering
|
// 160 sampling periods from the input device, the timestamp would be increased by 160 for
|
||||||
* 160 sampling periods from the input device, the timestamp would be increased by 160 for
|
// each such block, regardless of whether the block is transmitted in a packet or dropped as
|
||||||
* each such block, regardless of whether the block is transmitted in a packet or dropped as
|
// silent.
|
||||||
* silent.
|
//
|
||||||
*
|
// The initial value of the timestamp should be random, as for the sequence number. Several
|
||||||
* The initial value of the timestamp should be random, as for the sequence number. Several
|
// consecutive RTP packets will have equal timestamps if they are (logically) generated at once,
|
||||||
* consecutive RTP packets will have equal timestamps if they are (logically) generated at once,
|
// e.g., belong to the same video frame. Consecutive RTP packets may contain timestamps that
|
||||||
* e.g., belong to the same video frame. Consecutive RTP packets may contain timestamps that
|
// are not monotonic if the data is not transmitted in the order it was sampled, as in the case
|
||||||
* are not monotonic if the data is not transmitted in the order it was sampled, as in the case
|
// of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted
|
||||||
* of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted
|
// will still be monotonic.)
|
||||||
* will still be monotonic.)
|
//
|
||||||
*
|
// RTP timestamps from different media streams may advance at different rates and usually
|
||||||
* RTP timestamps from different media streams may advance at different rates and usually
|
// have independent, random offsets. Therefore, although these timestamps are sucient to
|
||||||
* have independent, random offsets. Therefore, although these timestamps are sucient to
|
// reconstruct the timing of a single stream, directly comparing RTP timestamps from different
|
||||||
* reconstruct the timing of a single stream, directly comparing RTP timestamps from different
|
// media is not effective for synchronization. Instead, for each medium the RTP timestamp
|
||||||
* media is not effective for synchronization. Instead, for each medium the RTP timestamp
|
// is related to the sampling instant by pairing it with a timestamp from a reference clock
|
||||||
* is related to the sampling instant by pairing it with a timestamp from a reference clock
|
// (wallclock) that represents the time when the data corresponding to the RTP timestamp was
|
||||||
* (wallclock) that represents the time when the data corresponding to the RTP timestamp was
|
// sampled. The reference clock is shared by all media to be synchronized. The timestamp
|
||||||
* sampled. The reference clock is shared by all media to be synchronized. The timestamp
|
// pairs are not transmitted in every data packet, but at a lower rate in RTCP SR packets as
|
||||||
* pairs are not transmitted in every data packet, but at a lower rate in RTCP SR packets as
|
// described in Section 6.4.
|
||||||
* described in Section 6.4.
|
//
|
||||||
*
|
// The sampling instant is chosen as the point of reference for the RTP timestamp because it is
|
||||||
* The sampling instant is chosen as the point of reference for the RTP timestamp because it is
|
// known to the transmitting endpoint and has a common definition for all media, independent
|
||||||
* known to the transmitting endpoint and has a common definition for all media, independent
|
// of encoding delays or other processing. The purpose is to allow synchronized presentation of
|
||||||
* of encoding delays or other processing. The purpose is to allow synchronized presentation of
|
// all media sampled at the same time.
|
||||||
* all media sampled at the same time.
|
//
|
||||||
*
|
// Applications transmitting stored data rather than data sampled in real time typically use a
|
||||||
* Applications transmitting stored data rather than data sampled in real time typically use a
|
// virtual presentation timeline derived from wallclock time to determine when the next frame
|
||||||
* virtual presentation timeline derived from wallclock time to determine when the next frame
|
// or other unit of each medium in the stored data should be presented. In this case, the RTP
|
||||||
* or other unit of each medium in the stored data should be presented. In this case, the RTP
|
// timestamp would reflect the presentation time for each unit. That is, the RTP timestamp for
|
||||||
* timestamp would reflect the presentation time for each unit. That is, the RTP timestamp for
|
// each unit would be related to the wallclock time at which the unit becomes current on the
|
||||||
* each unit would be related to the wallclock time at which the unit becomes current on the
|
// virtual presentation timeline. Actual presentation occurs some time later as determined by
|
||||||
* virtual presentation timeline. Actual presentation occurs some time later as determined by
|
// The receiver.
|
||||||
* the receiver.
|
//
|
||||||
*
|
// An example describing live audio narration of prerecorded video illustrates the significance
|
||||||
* An example describing live audio narration of prerecorded video illustrates the significance
|
// of choosing the sampling instant as the reference point. In this scenario, the video would
|
||||||
* of choosing the sampling instant as the reference point. In this scenario, the video would
|
// be presented locally for the narrator to view and would be simultaneously transmitted using
|
||||||
* be presented locally for the narrator to view and would be simultaneously transmitted using
|
// RTP. The sampling instant" of a video frame transmitted in RTP would be established by
|
||||||
* RTP. The sampling instant" of a video frame transmitted in RTP would be established by
|
// referencing its timestamp to the wallclock time when that video frame was presented to the
|
||||||
* referencing its timestamp to the wallclock time when that video frame was presented to the
|
// narrator. The sampling instant for the audio RTP packets containing the narrator's speech
|
||||||
* narrator. The sampling instant for the audio RTP packets containing the narrator's speech
|
// would be established by referencing the same wallclock time when the audio was sampled.
|
||||||
* would be established by referencing the same wallclock time when the audio was sampled.
|
// The audio and video may even be transmitted by different hosts if the reference clocks on
|
||||||
* The audio and video may even be transmitted by different hosts if the reference clocks on
|
// The two hosts are synchronized by some means such as NTP. A receiver can then synchronize
|
||||||
* the two hosts are synchronized by some means such as NTP. A receiver can then synchronize
|
// presentation of the audio and video packets by relating their RTP timestamps using the
|
||||||
* presentation of the audio and video packets by relating their RTP timestamps using the
|
// timestamp pairs in RTCP SR packets.
|
||||||
* timestamp pairs in RTCP SR packets.
|
|
||||||
*/
|
|
||||||
uint32_t timestamp; //32bits
|
uint32_t timestamp; //32bits
|
||||||
/**
|
// The SSRC: 32 bits
|
||||||
* SSRC: 32 bits
|
// The SSRC field identifies the synchronization source. This identifier should be chosen
|
||||||
* The SSRC field identifies the synchronization source. This identifier should be chosen
|
// randomly, with the intent that no two synchronization sources within the same RTP session
|
||||||
* randomly, with the intent that no two synchronization sources within the same RTP session
|
// will have the same SSRC identifier. An example algorithm for generating a random identifier
|
||||||
* will have the same SSRC identifier. An example algorithm for generating a random identifier
|
// is presented in Appendix A.6. Although the probability of multiple sources choosing the same
|
||||||
* is presented in Appendix A.6. Although the probability of multiple sources choosing the same
|
// identifier is low, all RTP implementations must be prepared to detect and resolve collisions.
|
||||||
* identifier is low, all RTP implementations must be prepared to detect and resolve collisions.
|
// Section 8 describes the probability of collision along with a mechanism for resolving collisions
|
||||||
* Section 8 describes the probability of collision along with a mechanism for resolving collisions
|
// and detecting RTP-level forwarding loops based on the uniqueness of the SSRC identifier. If
|
||||||
* and detecting RTP-level forwarding loops based on the uniqueness of the SSRC identifier. If
|
// a source changes its source transport address, it must also choose a new SSRC identifier to
|
||||||
* a source changes its source transport address, it must also choose a new SSRC identifier to
|
// avoid being interpreted as a looped source (see Section 8.2).
|
||||||
* avoid being interpreted as a looped source (see Section 8.2).
|
|
||||||
*/
|
|
||||||
uint32_t ssrc; //32bits
|
uint32_t ssrc; //32bits
|
||||||
|
|
||||||
// the payload.
|
// The payload.
|
||||||
SrsSimpleStream* payload;
|
SrsSimpleStream* payload;
|
||||||
// whether transport in chunked payload.
|
// Whether transport in chunked payload.
|
||||||
bool chunked;
|
bool chunked;
|
||||||
// whether message is completed.
|
// Whether message is completed.
|
||||||
// normal message always completed.
|
// normal message always completed.
|
||||||
// while chunked completed when the last chunk arriaved.
|
// while chunked completed when the last chunk arriaved.
|
||||||
bool completed;
|
bool completed;
|
||||||
|
|
||||||
/**
|
// The audio samples, one rtp packets may contains multiple audio samples.
|
||||||
* the audio samples, one rtp packets may contains multiple audio samples.
|
|
||||||
*/
|
|
||||||
SrsAudioFrame* audio;
|
SrsAudioFrame* audio;
|
||||||
public:
|
public:
|
||||||
SrsRtpPacket();
|
SrsRtpPacket();
|
||||||
virtual ~SrsRtpPacket();
|
virtual ~SrsRtpPacket();
|
||||||
public:
|
public:
|
||||||
/**
|
// copy the header from src.
|
||||||
* copy the header from src.
|
|
||||||
*/
|
|
||||||
virtual void copy(SrsRtpPacket* src);
|
virtual void copy(SrsRtpPacket* src);
|
||||||
/**
|
// reap the src to this packet, reap the payload.
|
||||||
* reap the src to this packet, reap the payload.
|
|
||||||
*/
|
|
||||||
virtual void reap(SrsRtpPacket* src);
|
virtual void reap(SrsRtpPacket* src);
|
||||||
/**
|
// decode rtp packet from stream.
|
||||||
* decode rtp packet from stream.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t decode(SrsBuffer* stream);
|
virtual srs_error_t decode(SrsBuffer* stream);
|
||||||
private:
|
private:
|
||||||
virtual srs_error_t decode_97(SrsBuffer* stream);
|
virtual srs_error_t decode_97(SrsBuffer* stream);
|
||||||
virtual srs_error_t decode_96(SrsBuffer* stream);
|
virtual srs_error_t decode_96(SrsBuffer* stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159
|
||||||
* the sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159
|
// Appendix C: Use of SDP for RTSP Session Descriptions
|
||||||
* Appendix C: Use of SDP for RTSP Session Descriptions
|
// The Session Description Protocol (SDP, RFC 2327 [6]) may be used to
|
||||||
* The Session Description Protocol (SDP, RFC 2327 [6]) may be used to
|
// describe streams or presentations in RTSP.
|
||||||
* describe streams or presentations in RTSP.
|
|
||||||
*/
|
|
||||||
class SrsRtspSdp
|
class SrsRtspSdp
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsRtspSdpState state;
|
SrsRtspSdpState state;
|
||||||
public:
|
public:
|
||||||
/**
|
// The version of sdp.
|
||||||
* the version of sdp.
|
|
||||||
*/
|
|
||||||
std::string version;
|
std::string version;
|
||||||
/**
|
// The owner/creator of sdp.
|
||||||
* the owner/creator of sdp.
|
|
||||||
*/
|
|
||||||
std::string owner_username;
|
std::string owner_username;
|
||||||
std::string owner_session_id;
|
std::string owner_session_id;
|
||||||
std::string owner_session_version;
|
std::string owner_session_version;
|
||||||
std::string owner_network_type;
|
std::string owner_network_type;
|
||||||
std::string owner_address_type;
|
std::string owner_address_type;
|
||||||
std::string owner_address;
|
std::string owner_address;
|
||||||
/**
|
// The session name of sdp.
|
||||||
* the session name of sdp.
|
|
||||||
*/
|
|
||||||
std::string session_name;
|
std::string session_name;
|
||||||
/**
|
// The connection info of sdp.
|
||||||
* the connection info of sdp.
|
|
||||||
*/
|
|
||||||
std::string connection_network_type;
|
std::string connection_network_type;
|
||||||
std::string connection_address_type;
|
std::string connection_address_type;
|
||||||
std::string connection_address;
|
std::string connection_address;
|
||||||
/**
|
// The tool attribute of sdp.
|
||||||
* the tool attribute of sdp.
|
|
||||||
*/
|
|
||||||
std::string tool;
|
std::string tool;
|
||||||
/**
|
// The video attribute of sdp.
|
||||||
* the video attribute of sdp.
|
|
||||||
*/
|
|
||||||
std::string video_port;
|
std::string video_port;
|
||||||
std::string video_protocol;
|
std::string video_protocol;
|
||||||
std::string video_transport_format;
|
std::string video_transport_format;
|
||||||
|
@ -363,13 +303,11 @@ public:
|
||||||
std::string video_codec;
|
std::string video_codec;
|
||||||
std::string video_sample_rate;
|
std::string video_sample_rate;
|
||||||
std::string video_stream_id;
|
std::string video_stream_id;
|
||||||
// fmtp
|
// The fmtp
|
||||||
std::string video_packetization_mode;
|
std::string video_packetization_mode;
|
||||||
std::string video_sps; // sequence header: sps.
|
std::string video_sps; // sequence header: sps.
|
||||||
std::string video_pps; // sequence header: pps.
|
std::string video_pps; // sequence header: pps.
|
||||||
/**
|
// The audio attribute of sdp.
|
||||||
* the audio attribute of sdp.
|
|
||||||
*/
|
|
||||||
std::string audio_port;
|
std::string audio_port;
|
||||||
std::string audio_protocol;
|
std::string audio_protocol;
|
||||||
std::string audio_transport_format;
|
std::string audio_transport_format;
|
||||||
|
@ -378,7 +316,7 @@ public:
|
||||||
std::string audio_sample_rate;
|
std::string audio_sample_rate;
|
||||||
std::string audio_channel;
|
std::string audio_channel;
|
||||||
std::string audio_stream_id;
|
std::string audio_stream_id;
|
||||||
// fmtp
|
// The fmtp
|
||||||
std::string audio_profile_level_id;
|
std::string audio_profile_level_id;
|
||||||
std::string audio_mode;
|
std::string audio_mode;
|
||||||
std::string audio_size_length;
|
std::string audio_size_length;
|
||||||
|
@ -389,34 +327,24 @@ public:
|
||||||
SrsRtspSdp();
|
SrsRtspSdp();
|
||||||
virtual ~SrsRtspSdp();
|
virtual ~SrsRtspSdp();
|
||||||
public:
|
public:
|
||||||
/**
|
// Parse a line of token for sdp.
|
||||||
* parse a line of token for sdp.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t parse(std::string token);
|
virtual srs_error_t parse(std::string token);
|
||||||
private:
|
private:
|
||||||
/**
|
// generally, the fmtp is the sequence header for video or audio.
|
||||||
* generally, the fmtp is the sequence header for video or audio.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t parse_fmtp_attribute(std::string attr);
|
virtual srs_error_t parse_fmtp_attribute(std::string attr);
|
||||||
/**
|
// generally, the control is the stream info for video or audio.
|
||||||
* generally, the control is the stream info for video or audio.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t parse_control_attribute(std::string attr);
|
virtual srs_error_t parse_control_attribute(std::string attr);
|
||||||
/**
|
// decode the string by base64.
|
||||||
* decode the string by base64.
|
|
||||||
*/
|
|
||||||
virtual std::string base64_decode(std::string value);
|
virtual std::string base64_decode(std::string value);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The rtsp transport.
|
||||||
* the rtsp transport.
|
// 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115
|
||||||
* 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115
|
// This request header indicates which transport protocol is to be used
|
||||||
* This request header indicates which transport protocol is to be used
|
// and configures its parameters such as destination address,
|
||||||
* and configures its parameters such as destination address,
|
// compression, multicast time-to-live and destination port for a single
|
||||||
* compression, multicast time-to-live and destination port for a single
|
// stream. It sets those values not already determined by a presentation
|
||||||
* stream. It sets those values not already determined by a presentation
|
// description.
|
||||||
* description.
|
|
||||||
*/
|
|
||||||
class SrsRtspTransport
|
class SrsRtspTransport
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -431,7 +359,7 @@ public:
|
||||||
// Clients that are capable of handling both unicast and
|
// Clients that are capable of handling both unicast and
|
||||||
// multicast transmission MUST indicate such capability by
|
// multicast transmission MUST indicate such capability by
|
||||||
// including two full transport-specs with separate parameters
|
// including two full transport-specs with separate parameters
|
||||||
// for each.
|
// For each.
|
||||||
std::string cast_type;
|
std::string cast_type;
|
||||||
// The mode parameter indicates the methods to be supported for
|
// The mode parameter indicates the methods to be supported for
|
||||||
// this session. Valid values are PLAY and RECORD. If not
|
// this session. Valid values are PLAY and RECORD. If not
|
||||||
|
@ -449,79 +377,59 @@ public:
|
||||||
SrsRtspTransport();
|
SrsRtspTransport();
|
||||||
virtual ~SrsRtspTransport();
|
virtual ~SrsRtspTransport();
|
||||||
public:
|
public:
|
||||||
/**
|
// Parse a line of token for transport.
|
||||||
* parse a line of token for transport.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t parse(std::string attr);
|
virtual srs_error_t parse(std::string attr);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The rtsp request message.
|
||||||
* the rtsp request message.
|
// 6 Request, @see rfc2326-1998-rtsp.pdf, page 39
|
||||||
* 6 Request, @see rfc2326-1998-rtsp.pdf, page 39
|
// A request message from a client to a server or vice versa includes,
|
||||||
* A request message from a client to a server or vice versa includes,
|
// within the first line of that message, the method to be applied to
|
||||||
* within the first line of that message, the method to be applied to
|
// The resource, the identifier of the resource, and the protocol
|
||||||
* the resource, the identifier of the resource, and the protocol
|
// version in use.
|
||||||
* version in use.
|
// Request = Request-Line ; Section 6.1
|
||||||
* Request = Request-Line ; Section 6.1
|
// // ( general-header ; Section 5
|
||||||
* *( general-header ; Section 5
|
// | request-header ; Section 6.2
|
||||||
* | request-header ; Section 6.2
|
// | entity-header ) ; Section 8.1
|
||||||
* | entity-header ) ; Section 8.1
|
// CRLF
|
||||||
* CRLF
|
// [ message-body ] ; Section 4.3
|
||||||
* [ message-body ] ; Section 4.3
|
|
||||||
*/
|
|
||||||
class SrsRtspRequest
|
class SrsRtspRequest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
// 6.1 Request Line
|
||||||
* 6.1 Request Line
|
// Request-Line = Method SP Request-URI SP RTSP-Version CRLF
|
||||||
* Request-Line = Method SP Request-URI SP RTSP-Version CRLF
|
|
||||||
*/
|
|
||||||
std::string method;
|
std::string method;
|
||||||
std::string uri;
|
std::string uri;
|
||||||
std::string version;
|
std::string version;
|
||||||
/**
|
// 12.17 CSeq
|
||||||
* 12.17 CSeq
|
// The CSeq field specifies the sequence number for an RTSP requestresponse
|
||||||
* The CSeq field specifies the sequence number for an RTSP requestresponse
|
// pair. This field MUST be present in all requests and
|
||||||
* pair. This field MUST be present in all requests and
|
// responses. For every RTSP request containing the given sequence
|
||||||
* responses. For every RTSP request containing the given sequence
|
// number, there will be a corresponding response having the same
|
||||||
* number, there will be a corresponding response having the same
|
// number. Any retransmitted request must contain the same sequence
|
||||||
* number. Any retransmitted request must contain the same sequence
|
// number as the original (i.e. the sequence number is not incremented
|
||||||
* number as the original (i.e. the sequence number is not incremented
|
// For retransmissions of the same request).
|
||||||
* for retransmissions of the same request).
|
|
||||||
*/
|
|
||||||
long seq;
|
long seq;
|
||||||
/**
|
// 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99
|
||||||
* 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99
|
// See [H14.18]. Note that the content types suitable for RTSP are
|
||||||
* See [H14.18]. Note that the content types suitable for RTSP are
|
// likely to be restricted in practice to presentation descriptions and
|
||||||
* likely to be restricted in practice to presentation descriptions and
|
// parameter-value types.
|
||||||
* parameter-value types.
|
|
||||||
*/
|
|
||||||
std::string content_type;
|
std::string content_type;
|
||||||
/**
|
// 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99
|
||||||
* 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99
|
// This field contains the length of the content of the method (i.e.
|
||||||
* This field contains the length of the content of the method (i.e.
|
// after the double CRLF following the last header). Unlike HTTP, it
|
||||||
* after the double CRLF following the last header). Unlike HTTP, it
|
// MUST be included in all messages that carry content beyond the header
|
||||||
* MUST be included in all messages that carry content beyond the header
|
// portion of the message. If it is missing, a default value of zero is
|
||||||
* portion of the message. If it is missing, a default value of zero is
|
// assumed. It is interpreted according to [H14.14].
|
||||||
* assumed. It is interpreted according to [H14.14].
|
|
||||||
*/
|
|
||||||
long content_length;
|
long content_length;
|
||||||
/**
|
// The session id.
|
||||||
* the session id.
|
|
||||||
*/
|
|
||||||
std::string session;
|
std::string session;
|
||||||
|
|
||||||
/**
|
// The sdp in announce, NULL for no sdp.
|
||||||
* the sdp in announce, NULL for no sdp.
|
|
||||||
*/
|
|
||||||
SrsRtspSdp* sdp;
|
SrsRtspSdp* sdp;
|
||||||
/**
|
// The transport in setup, NULL for no transport.
|
||||||
* the transport in setup, NULL for no transport.
|
|
||||||
*/
|
|
||||||
SrsRtspTransport* transport;
|
SrsRtspTransport* transport;
|
||||||
/**
|
// For setup message, parse the stream id from uri.
|
||||||
* for setup message, parse the stream id from uri.
|
|
||||||
*/
|
|
||||||
int stream_id;
|
int stream_id;
|
||||||
public:
|
public:
|
||||||
SrsRtspRequest();
|
SrsRtspRequest();
|
||||||
|
@ -533,79 +441,63 @@ public:
|
||||||
virtual bool is_record();
|
virtual bool is_record();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The rtsp response message.
|
||||||
* the rtsp response message.
|
// 7 Response, @see rfc2326-1998-rtsp.pdf, page 43
|
||||||
* 7 Response, @see rfc2326-1998-rtsp.pdf, page 43
|
// [H6] applies except that HTTP-Version is replaced by RTSP-Version.
|
||||||
* [H6] applies except that HTTP-Version is replaced by RTSP-Version.
|
// Also, RTSP defines additional status codes and does not define some
|
||||||
* Also, RTSP defines additional status codes and does not define some
|
// HTTP codes. The valid response codes and the methods they can be used
|
||||||
* HTTP codes. The valid response codes and the methods they can be used
|
// with are defined in Table 1.
|
||||||
* with are defined in Table 1.
|
// After receiving and interpreting a request message, the recipient
|
||||||
* After receiving and interpreting a request message, the recipient
|
// responds with an RTSP response message.
|
||||||
* responds with an RTSP response message.
|
// Response = Status-Line ; Section 7.1
|
||||||
* Response = Status-Line ; Section 7.1
|
// // ( general-header ; Section 5
|
||||||
* *( general-header ; Section 5
|
// | response-header ; Section 7.1.2
|
||||||
* | response-header ; Section 7.1.2
|
// | entity-header ) ; Section 8.1
|
||||||
* | entity-header ) ; Section 8.1
|
// CRLF
|
||||||
* CRLF
|
// [ message-body ] ; Section 4.3
|
||||||
* [ message-body ] ; Section 4.3
|
|
||||||
*/
|
|
||||||
class SrsRtspResponse
|
class SrsRtspResponse
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
// 7.1 Status-Line
|
||||||
* 7.1 Status-Line
|
// The first line of a Response message is the Status-Line, consisting
|
||||||
* The first line of a Response message is the Status-Line, consisting
|
// of the protocol version followed by a numeric status code, and the
|
||||||
* of the protocol version followed by a numeric status code, and the
|
// textual phrase associated with the status code, with each element
|
||||||
* textual phrase associated with the status code, with each element
|
// separated by SP characters. No CR or LF is allowed except in the
|
||||||
* separated by SP characters. No CR or LF is allowed except in the
|
// final CRLF sequence.
|
||||||
* final CRLF sequence.
|
// Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
|
||||||
* Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
|
|
||||||
*/
|
|
||||||
// @see about the version of rtsp, see SRS_RTSP_VERSION
|
// @see about the version of rtsp, see SRS_RTSP_VERSION
|
||||||
// @see about the status of rtsp, see SRS_CONSTS_RTSP_OK
|
// @see about the status of rtsp, see SRS_CONSTS_RTSP_OK
|
||||||
int status;
|
int status;
|
||||||
/**
|
// 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99
|
||||||
* 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99
|
// The CSeq field specifies the sequence number for an RTSP requestresponse
|
||||||
* The CSeq field specifies the sequence number for an RTSP requestresponse
|
// pair. This field MUST be present in all requests and
|
||||||
* pair. This field MUST be present in all requests and
|
// responses. For every RTSP request containing the given sequence
|
||||||
* responses. For every RTSP request containing the given sequence
|
// number, there will be a corresponding response having the same
|
||||||
* number, there will be a corresponding response having the same
|
// number. Any retransmitted request must contain the same sequence
|
||||||
* number. Any retransmitted request must contain the same sequence
|
// number as the original (i.e. the sequence number is not incremented
|
||||||
* number as the original (i.e. the sequence number is not incremented
|
// For retransmissions of the same request).
|
||||||
* for retransmissions of the same request).
|
|
||||||
*/
|
|
||||||
long seq;
|
long seq;
|
||||||
/**
|
// The session id.
|
||||||
* the session id.
|
|
||||||
*/
|
|
||||||
std::string session;
|
std::string session;
|
||||||
public:
|
public:
|
||||||
SrsRtspResponse(int cseq);
|
SrsRtspResponse(int cseq);
|
||||||
virtual ~SrsRtspResponse();
|
virtual ~SrsRtspResponse();
|
||||||
public:
|
public:
|
||||||
/**
|
// Encode message to string.
|
||||||
* encode message to string.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t encode(std::stringstream& ss);
|
virtual srs_error_t encode(std::stringstream& ss);
|
||||||
protected:
|
protected:
|
||||||
/**
|
// Sub classes override this to encode the headers.
|
||||||
* sub classes override this to encode the headers.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t encode_header(std::stringstream& ss);
|
virtual srs_error_t encode_header(std::stringstream& ss);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59
|
||||||
* 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59
|
// The behavior is equivalent to that described in [H9.2]. An OPTIONS
|
||||||
* The behavior is equivalent to that described in [H9.2]. An OPTIONS
|
// request may be issued at any time, e.g., if the client is about to
|
||||||
* request may be issued at any time, e.g., if the client is about to
|
// try a nonstandard request. It does not influence server state.
|
||||||
* try a nonstandard request. It does not influence server state.
|
|
||||||
*/
|
|
||||||
class SrsRtspOptionsResponse : public SrsRtspResponse
|
class SrsRtspOptionsResponse : public SrsRtspResponse
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
// Join of SrsRtspMethod
|
||||||
* join of SrsRtspMethod
|
|
||||||
*/
|
|
||||||
SrsRtspMethod methods;
|
SrsRtspMethod methods;
|
||||||
public:
|
public:
|
||||||
SrsRtspOptionsResponse(int cseq);
|
SrsRtspOptionsResponse(int cseq);
|
||||||
|
@ -614,28 +506,26 @@ protected:
|
||||||
virtual srs_error_t encode_header(std::stringstream& ss);
|
virtual srs_error_t encode_header(std::stringstream& ss);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65
|
||||||
* 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65
|
// The SETUP request for a URI specifies the transport mechanism to be
|
||||||
* The SETUP request for a URI specifies the transport mechanism to be
|
// used for the streamed media. A client can issue a SETUP request for a
|
||||||
* used for the streamed media. A client can issue a SETUP request for a
|
// stream that is already playing to change transport parameters, which
|
||||||
* stream that is already playing to change transport parameters, which
|
// a server MAY allow. If it does not allow this, it MUST respond with
|
||||||
* a server MAY allow. If it does not allow this, it MUST respond with
|
// error "455 Method Not Valid In This State". For the benefit of any
|
||||||
* error "455 Method Not Valid In This State". For the benefit of any
|
// intervening firewalls, a client must indicate the transport
|
||||||
* intervening firewalls, a client must indicate the transport
|
// parameters even if it has no influence over these parameters, for
|
||||||
* parameters even if it has no influence over these parameters, for
|
// example, where the server advertises a fixed multicast address.
|
||||||
* example, where the server advertises a fixed multicast address.
|
|
||||||
*/
|
|
||||||
class SrsRtspSetupResponse : public SrsRtspResponse
|
class SrsRtspSetupResponse : public SrsRtspResponse
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// the client specified port.
|
// The client specified port.
|
||||||
int client_port_min;
|
int client_port_min;
|
||||||
int client_port_max;
|
int client_port_max;
|
||||||
// client will use the port in:
|
// The client will use the port in:
|
||||||
// [local_port_min, local_port_max)
|
// [local_port_min, local_port_max)
|
||||||
int local_port_min;
|
int local_port_min;
|
||||||
int local_port_max;
|
int local_port_max;
|
||||||
// session.
|
// The session.
|
||||||
std::string session;
|
std::string session;
|
||||||
public:
|
public:
|
||||||
SrsRtspSetupResponse(int cseq);
|
SrsRtspSetupResponse(int cseq);
|
||||||
|
@ -644,65 +534,45 @@ protected:
|
||||||
virtual srs_error_t encode_header(std::stringstream& ss);
|
virtual srs_error_t encode_header(std::stringstream& ss);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// The rtsp protocol stack to parse the rtsp packets.
|
||||||
* the rtsp protocol stack to parse the rtsp packets.
|
|
||||||
*/
|
|
||||||
class SrsRtspStack
|
class SrsRtspStack
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/**
|
// The cached bytes buffer.
|
||||||
* cached bytes buffer.
|
|
||||||
*/
|
|
||||||
SrsSimpleStream* buf;
|
SrsSimpleStream* buf;
|
||||||
/**
|
// The underlayer socket object, send/recv bytes.
|
||||||
* underlayer socket object, send/recv bytes.
|
|
||||||
*/
|
|
||||||
ISrsProtocolReadWriter* skt;
|
ISrsProtocolReadWriter* skt;
|
||||||
public:
|
public:
|
||||||
SrsRtspStack(ISrsProtocolReadWriter* s);
|
SrsRtspStack(ISrsProtocolReadWriter* s);
|
||||||
virtual ~SrsRtspStack();
|
virtual ~SrsRtspStack();
|
||||||
public:
|
public:
|
||||||
/**
|
// Recv rtsp message from underlayer io.
|
||||||
* recv rtsp message from underlayer io.
|
// @param preq the output rtsp request message, which user must free it.
|
||||||
* @param preq the output rtsp request message, which user must free it.
|
// @return an int error code.
|
||||||
* @return an int error code.
|
// ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
|
||||||
* ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t recv_message(SrsRtspRequest** preq);
|
virtual srs_error_t recv_message(SrsRtspRequest** preq);
|
||||||
/**
|
// Send rtsp message over underlayer io.
|
||||||
* send rtsp message over underlayer io.
|
// @param res the rtsp response message, which user should never free it.
|
||||||
* @param res the rtsp response message, which user should never free it.
|
// @return an int error code.
|
||||||
* @return an int error code.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t send_message(SrsRtspResponse* res);
|
virtual srs_error_t send_message(SrsRtspResponse* res);
|
||||||
private:
|
private:
|
||||||
/**
|
// Recv the rtsp message.
|
||||||
* recv the rtsp message.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t do_recv_message(SrsRtspRequest* req);
|
virtual srs_error_t do_recv_message(SrsRtspRequest* req);
|
||||||
/**
|
// Read a normal token from io, error when token state is not normal.
|
||||||
* read a normal token from io, error when token state is not normal.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t recv_token_normal(std::string& token);
|
virtual srs_error_t recv_token_normal(std::string& token);
|
||||||
/**
|
// Read a normal token from io, error when token state is not eof.
|
||||||
* read a normal token from io, error when token state is not eof.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t recv_token_eof(std::string& token);
|
virtual srs_error_t recv_token_eof(std::string& token);
|
||||||
/**
|
// Read the token util got eof, for example, to read the response status Reason-Phrase
|
||||||
* read the token util got eof, for example, to read the response status Reason-Phrase
|
// @param pconsumed, output the token parsed length. NULL to ignore.
|
||||||
* @param pconsumed, output the token parsed length. NULL to ignore.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t recv_token_util_eof(std::string& token, int* pconsumed = NULL);
|
virtual srs_error_t recv_token_util_eof(std::string& token, int* pconsumed = NULL);
|
||||||
/**
|
// Read a token from io, split by SP, endswith CRLF:
|
||||||
* read a token from io, split by SP, endswith CRLF:
|
// token1 SP token2 SP ... tokenN CRLF
|
||||||
* token1 SP token2 SP ... tokenN CRLF
|
// @param token, output the read token.
|
||||||
* @param token, output the read token.
|
// @param state, output the token parse state.
|
||||||
* @param state, output the token parse state.
|
// @param normal_ch, the char to indicates the normal token.
|
||||||
* @param normal_ch, the char to indicates the normal token.
|
// the SP use to indicates the normal token, @see SRS_RTSP_SP
|
||||||
* the SP use to indicates the normal token, @see SRS_RTSP_SP
|
// the 0x00 use to ignore normal token flag. @see recv_token_util_eof
|
||||||
* the 0x00 use to ignore normal token flag. @see recv_token_util_eof
|
// @param pconsumed, output the token parsed length. NULL to ignore.
|
||||||
* @param pconsumed, output the token parsed length. NULL to ignore.
|
|
||||||
*/
|
|
||||||
virtual srs_error_t recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch = SRS_RTSP_SP, int* pconsumed = NULL);
|
virtual srs_error_t recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch = SRS_RTSP_SP, int* pconsumed = NULL);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue