1
0
Fork 0
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:
winlin 2019-04-23 08:06:50 +08:00
parent 35fe05d62c
commit 8bc77387ff
7 changed files with 1328 additions and 2117 deletions

View file

@ -26,7 +26,7 @@
#include <srs_core.hpp>
// default http listen port.
// Default http listen port.
#define SRS_DEFAULT_HTTP_PORT 80
#if !defined(SRS_EXPORT_LIBRTMP)
@ -35,7 +35,7 @@
#include <string>
#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
#include <sys/uio.h>
#endif
@ -46,7 +46,7 @@ class ISrsHttpMessage;
class SrsHttpMuxEntry;
class ISrsHttpResponseWriter;
// http specification
// From http specification
// CR = <US-ASCII CR, carriage return (13)>
#define SRS_HTTP_CR SRS_CONSTS_CR // 0x0D
// LF = <US-ASCII LF, linefeed (10)>
@ -65,10 +65,10 @@ class ISrsHttpResponseWriter;
// @see ISrsHttpMessage._http_ts_send_buffer
#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
// for http parser macros
// For http parser macros
#define SRS_CONSTS_HTTP_OPTIONS HTTP_OPTIONS
#define SRS_CONSTS_HTTP_GET HTTP_GET
#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, 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);
// bodyAllowedForStatus reports whether a given response status code
// It reports whether a given response status code
// permits a body. See RFC2616, section 4.4.
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".
extern std::string srs_go_http_detect(char* data, int size);
// state of message
// The state of HTTP message
enum SrsHttpParseState {
SrsHttpParseStateInit = 0,
SrsHttpParseStateStart,
@ -121,27 +121,17 @@ public:
// with CanonicalHeaderKey.
virtual std::string get(std::string key);
public:
/**
* get the content length. -1 if not set.
*/
// Get the content length. -1 if not set.
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);
public:
/**
* get the content type. empty string if not set.
*/
// Get the content type. empty string if not set.
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);
public:
/**
* write all headers to string stream.
*/
// write all headers to string stream.
virtual void write(std::stringstream& ss);
};
@ -176,9 +166,9 @@ public:
ISrsHttpResponseWriter();
virtual ~ISrsHttpResponseWriter();
public:
// when chunked mode,
// When chunked mode,
// 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.
virtual srs_error_t final_request() = 0;
@ -191,13 +181,11 @@ public:
// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
// 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
// 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.
virtual srs_error_t write(char* data, int size) = 0;
/**
* for the HTTP FLV, to writev to improve performance.
* @see https://github.com/ossrs/srs/issues/405
*/
// for the HTTP FLV, to writev to improve performance.
// @see https://github.com/ossrs/srs/issues/405
virtual srs_error_t writev(const iovec* iov, int iovcnt, ssize_t* pnwrite) = 0;
// WriteHeader sends an HTTP response header with status code.
@ -209,32 +197,26 @@ public:
virtual void write_header(int code) = 0;
};
/**
* the reader interface for http response.
*/
// The reader interface for http response.
class ISrsHttpResponseReader
{
public:
ISrsHttpResponseReader();
virtual ~ISrsHttpResponseReader();
public:
/**
* whether response read EOF.
*/
// Whether response read EOF.
virtual bool eof() = 0;
/**
* read from the response body.
* @param data, the buffer to read data buffer to.
* @param nb_data, the max size of data buffer.
* @param nb_read, the actual read size of bytes. NULL to ignore.
* @remark when eof(), return error.
* @remark for some server, the content-length not specified and not chunked,
* which is actually the infinite chunked encoding, which after http header
* 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
* or by chunked), because the sdk never know whether there is no data or
* infinite chunked.
*/
// Read from the response body.
// @param data, the buffer to read data buffer to.
// @param nb_data, the max size of data buffer.
// @param nb_read, the actual read size of bytes. NULL to ignore.
// @remark when eof(), return error.
// @remark for some server, the content-length not specified and not chunked,
// which is actually the infinite chunked encoding, which after http header
// 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
// or by chunked), because the sdk never know whether there is no data or
// infinite chunked.
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
// and then return. Returning signals that the request is finished
// and that the HTTP server can move on to the next request on
// the connection.
// The connection.
class ISrsHttpHandler
{
public:
@ -300,33 +282,25 @@ public:
public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
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_flv_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
virtual srs_error_t serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
protected:
/**
* when access flv file with x.flv?start=xxx
*/
// 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);
/**
* when access mp4 file with x.mp4?range=start-end
* @param start the start offset in bytes.
* @param end the end offset in bytes. -1 to end of file.
* @remark response data in [start, end].
*/
// When access mp4 file with x.mp4?range=start-end
// @param start the start offset in bytes.
// @param end the end offset in bytes. -1 to end of file.
// @remark response data in [start, end].
virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end);
protected:
/**
* copy the fs to response writer in size bytes.
*/
// Copy the fs to response writer in size bytes.
virtual srs_error_t copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int size);
};
// the mux entry for server mux.
// the matcher info, for example, the pattern and handler.
// The mux entry for server mux.
// The matcher info, for example, the pattern and handler.
class SrsHttpMuxEntry
{
public:
@ -339,26 +313,20 @@ public:
virtual ~SrsHttpMuxEntry();
};
/**
* the hijacker for http pattern match.
*/
// The hijacker for http pattern match.
class ISrsHttpMatchHijacker
{
public:
ISrsHttpMatchHijacker();
virtual ~ISrsHttpMatchHijacker();
public:
/**
* when match the request failed, no handler to process request.
* @param request the http request message to match the handler.
* @param ph the already matched handler, hijack can rewrite it.
*/
// When match the request failed, no handler to process request.
// @param request the http request message to match the handler.
// @param ph the already matched handler, hijack can rewrite it.
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
{
public:
@ -383,7 +351,7 @@ public:
// "/images/" 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 may optionally begin with a host name, restricting matches to
@ -398,29 +366,25 @@ public:
class SrsHttpServeMux : public ISrsHttpServeMux
{
private:
// the pattern handler, to handle the http request.
// The pattern handler, to handle the http request.
std::map<std::string, SrsHttpMuxEntry*> entries;
// the vhost handler.
// when find the handler to process the request,
// The vhost handler.
// When find the handler to process the request,
// append the matched vhost when pattern not starts with /,
// for example, for pattern /live/livestream.flv of vhost ossrs.net,
// the path will rewrite to ossrs.net/live/livestream.flv
// For example, for pattern /live/livestream.flv of vhost ossrs.net,
// The path will rewrite to ossrs.net/live/livestream.flv
std::map<std::string, ISrsHttpHandler*> vhosts;
// 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.
std::vector<ISrsHttpMatchHijacker*> hijackers;
public:
SrsHttpServeMux();
virtual ~SrsHttpServeMux();
public:
/**
* initialize the http serve mux.
*/
// Initialize the http serve mux.
virtual srs_error_t initialize();
/**
* hijack the http match.
*/
// hijack the http match.
virtual void hijack(ISrsHttpMatchHijacker* h);
virtual void unhijack(ISrsHttpMatchHijacker* h);
public:
@ -437,10 +401,8 @@ private:
virtual bool path_match(std::string pattern, std::string path);
};
/**
* The filter http mux, directly serve the http CORS requests,
* while proxy to the worker mux for services.
*/
// The filter http mux, directly serve the http CORS requests,
// while proxy to the worker mux for services.
class SrsHttpCorsMux : public ISrsHttpServeMux
{
private:
@ -457,7 +419,7 @@ public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
};
// for http header.
// For http header.
typedef std::pair<std::string, std::string> SrsHttpHeaderField;
// 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.
// For example:
// 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:
// ISrsHttpMessage* r = ...;
// 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.
class ISrsHttpMessage
{
private:
/**
* use a buffer to read and send ts file.
*/
// Use a buffer to read and send ts file.
// TODO: FIXME: remove it.
char* _http_ts_send_buffer;
public:
ISrsHttpMessage();
virtual ~ISrsHttpMessage();
public:
/**
* the http request level cache.
*/
// The http request level cache.
virtual char* http_ts_send_buffer();
public:
virtual uint8_t method() = 0;
virtual uint16_t status_code() = 0;
/**
* method helpers.
*/
// Method helpers.
virtual std::string method_str() = 0;
virtual bool is_http_get() = 0;
virtual bool is_http_put() = 0;
@ -508,94 +464,74 @@ public:
virtual bool is_http_delete() = 0;
virtual bool is_http_options() = 0;
public:
/**
* whether should keep the connection alive.
*/
// Whether should keep the connection alive.
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;
/**
* the url maybe the path.
*/
// The url maybe the path.
virtual std::string url() = 0;
virtual std::string host() = 0;
virtual std::string path() = 0;
virtual std::string query() = 0;
virtual std::string ext() = 0;
/**
* get the RESTful id,
* for example, pattern is /api/v1/streams, path is /api/v1/streams/100,
* then the rest id is 100.
* @param pattern the handler pattern which will serve the request.
* @return the REST id; -1 if not matched.
*/
// Get the RESTful id,
// for example, pattern is /api/v1/streams, path is /api/v1/streams/100,
// then the rest id is 100.
// @param pattern the handler pattern which will serve the request.
// @return the REST id; -1 if not matched.
virtual int parse_rest_id(std::string pattern) = 0;
public:
/**
* the left all data is chunked body, the infinite chunked mode,
* which is chunked encoding without chunked header.
* @remark error when message is in chunked or content-length specified.
*/
// The left all data is chunked body, the infinite chunked mode,
// which is chunked encoding without chunked header.
// @remark error when message is in chunked or content-length specified.
virtual srs_error_t enter_infinite_chunked() = 0;
/**
* read body to string.
* @remark for small http body.
*/
// Read body to string.
// @remark for small http body.
virtual srs_error_t body_read_all(std::string& body) = 0;
/**
* get the body reader, to read one by one.
* @remark when body is very large, or chunked, use this.
*/
// Get the body reader, to read one by one.
// @remark when body is very large, or chunked, use this.
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;
public:
/**
* get the param in query string,
* for instance, query is "start=100&end=200",
* then query_get("start") is "100", and query_get("end") is "200"
*/
// Get the param in query string,
// for instance, query is "start=100&end=200",
// then query_get("start") is "100", and query_get("end") is "200"
virtual std::string query_get(std::string key) = 0;
/**
* get the headers.
*/
// Get the headers.
virtual int request_header_count() = 0;
virtual std::string request_header_key_at(int index) = 0;
virtual std::string request_header_value_at(int index) = 0;
public:
/**
* whether the current request is JSONP,
* which has a "callback=xxx" in QueryString.
*/
// Whether the current request is JSONP,
// which has a "callback=xxx" in QueryString.
virtual bool is_jsonp() = 0;
};
#endif
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* 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.
*/
// 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
//Copyright Joyent, Inc. and other Node contributors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// The SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// 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
#define http_parser_h
#ifdef __cplusplus
@ -621,9 +557,8 @@ extern "C" {
#include <stdint.h>
#endif
/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
* faster
*/
// Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
// faster
#ifndef HTTP_PARSER_STRICT
# define HTTP_PARSER_STRICT 1
#endif
@ -636,19 +571,18 @@ extern "C" {
typedef struct http_parser_settings http_parser_settings;
/* Callbacks should return non-zero to indicate an error. The parser will
* then halt execution.
*
* The one exception is on_headers_complete. In a HTTP_RESPONSE parser
* 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
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
* chunked' headers that indicate the presence of a body.
*
* 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"
* each providing just a few characters more data.
*/
// Callbacks should return non-zero to indicate an error. The parser will
// then halt execution.
//
// The one exception is on_headers_complete. In a HTTP_RESPONSE parser
// 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
// HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
// chunked' headers that indicate the presence of a body.
//
// 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"
// each providing just a few characters more data.
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
typedef int (*http_cb) (http_parser*);
@ -709,10 +643,8 @@ extern "C" {
};
/* Map for errno-related constants
*
* The provided argument should be a macro that takes 2 arguments.
*/
// Map for errno-related constants
// The provided argument should be a macro that takes 2 arguments.
#define HTTP_ERRNO_MAP(XX) \
/* No error */ \
XX(OK, "success") \
@ -785,11 +717,10 @@ extern "C" {
unsigned char method; /* requests only */
unsigned char http_errno : 7;
/* 1 = Upgrade header was present and the parser has exited because of that.
* 0 = No upgrade header present.
* Should be checked when http_parser_execute() returns in addition to
* error checking.
*/
// 1 = Upgrade header was present and the parser has exited because of that.
// 0 = No upgrade header present.
// Should be checked when http_parser_execute() returns in addition to
// error checking.
unsigned char upgrade : 1;
/** PUBLIC **/
@ -821,13 +752,11 @@ extern "C" {
};
/* Result structure for http_parser_parse_url().
*
* 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
* because we probably have padding left over), we convert any port to
* a uint16_t.
*/
// Result structure for http_parser_parse_url().
// 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
// because we probably have padding left over), we convert any port to
// a uint16_t.
struct http_parser_url {
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
uint16_t port; /* Converted UF_PORT string */
@ -848,12 +777,11 @@ extern "C" {
size_t len);
/* If http_should_keep_alive() in the on_headers_complete or
* on_message_complete callback returns 0, then this should be
* the last message on the connection.
* If you are the server, respond with the "Connection: close" header.
* If you are the client, close the connection.
*/
// If http_should_keep_alive() in the on_headers_complete or
// on_message_complete callback returns 0, then this should be
// The last message on the connection.
// If you are the server, respond with the "Connection: close" header.
// If you are the client, close the connection.
int http_should_keep_alive(const http_parser *parser);
/* Returns a string version of the HTTP method. */
@ -881,9 +809,7 @@ extern "C" {
#endif
#endif
/**
* used to resolve the http uri.
*/
// Used to resolve the http uri.
class SrsHttpUri
{
private:
@ -897,9 +823,7 @@ public:
SrsHttpUri();
virtual ~SrsHttpUri();
public:
/**
* initialize the http uri.
*/
// Initialize the http uri.
virtual srs_error_t initialize(std::string _url);
public:
virtual std::string get_url();
@ -909,10 +833,8 @@ public:
virtual std::string get_path();
virtual std::string get_query();
private:
/**
* get the parsed url field.
* @return return empty string if not set.
*/
// Get the parsed url field.
// @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);
};

View file

@ -32,7 +32,7 @@
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// json decode
// JSON decode
// 1. SrsJsonAny: read any from str:char*
// SrsJsonAny* any = NULL;
// if ((any = SrsJsonAny::loads(str)) == NULL) {
@ -45,7 +45,7 @@
// 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:
char marker;
// donot directly create this object,
// instead, for examle, use SrsJsonAny::str() to create a concreated one.
// Don't directly create this object,
// please use SrsJsonAny::str() to create a concreated one.
protected:
SrsJsonAny();
public:
@ -74,35 +74,23 @@ public:
virtual bool is_array();
virtual bool is_null();
public:
/**
* get the string of any when is_string() indicates true.
* user must ensure the type is a string, or assert failed.
*/
// Get the string of any when is_string() indicates true.
// user must ensure the type is a string, or assert failed.
virtual std::string to_str();
/**
* get the boolean of any when is_boolean() indicates true.
* user must ensure the type is a boolean, or assert failed.
*/
// Get the boolean of any when is_boolean() indicates true.
// user must ensure the type is a boolean, or assert failed.
virtual bool to_boolean();
/**
* get the integer of any when is_integer() indicates true.
* user must ensure the type is a integer, or assert failed.
*/
// Get the integer of any when is_integer() indicates true.
// user must ensure the type is a integer, or assert failed.
virtual int64_t to_integer();
/**
* get the number of any when is_number() indicates true.
* user must ensure the type is a number, or assert failed.
*/
// Get the number of any when is_number() indicates true.
// user must ensure the type is a number, or assert failed.
virtual double to_number();
/**
* get the object of any when is_object() indicates true.
* user must ensure the type is a object, or assert failed.
*/
// Get the object of any when is_object() indicates true.
// user must ensure the type is a object, or assert failed.
virtual SrsJsonObject* to_object();
/**
* get the ecma array of any when is_ecma_array() indicates true.
* user must ensure the type is a ecma array, or assert failed.
*/
// Get the ecma array of any when is_ecma_array() indicates true.
// user must ensure the type is a ecma array, or assert failed.
virtual SrsJsonArray* to_array();
public:
virtual std::string dumps();
@ -117,10 +105,8 @@ public:
static SrsJsonObject* object();
static SrsJsonArray* array();
public:
/**
* read json tree from string.
* @return json object. NULL if error.
*/
// Read json tree from string.
// @return json object. NULL if error.
static SrsJsonAny* loads(const std::string& str);
};
@ -130,7 +116,7 @@ private:
typedef std::pair<std::string, SrsJsonAny*> SrsJsonObjectPropertyType;
std::vector<SrsJsonObjectPropertyType> properties;
private:
// use SrsJsonAny::object() to create it.
// Use SrsJsonAny::object() to create it.
friend class SrsJsonAny;
SrsJsonObject();
public:
@ -161,7 +147,7 @@ private:
std::vector<SrsJsonAny*> properties;
private:
// use SrsJsonAny::array() to create it.
// Use SrsJsonAny::array() to create it.
friend class SrsJsonAny;
SrsJsonArray();
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

View file

@ -32,61 +32,45 @@
class SrsBuffer;
/**
* the raw h.264 stream, in annexb.
*/
// The raw h.264 stream, in annexb.
class SrsRawH264Stream
{
public:
SrsRawH264Stream();
virtual ~SrsRawH264Stream();
public:
/**
* demux the stream in annexb format.
* @param stream the input stream bytes.
* @param pframe the output h.264 frame in stream. user should never free it.
* @param pnb_frame the output h.264 frame size.
*/
// Demux the stream in annexb format.
// @param stream the input stream bytes.
// @param pframe the output h.264 frame in stream. user should never free it.
// @param pnb_frame the output h.264 frame size.
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_pps(char* frame, int nb_frame);
/**
* demux the sps or pps to string.
* @param sps/pps output the sps/pps.
*/
// Demux the sps or pps to string.
// @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 pps_demux(char* frame, int nb_frame, std::string& pps);
public:
/**
* h264 raw data to h264 packet, without flv payload header.
* mux the sps/pps to flv sequence header packet.
* @param sh output the sequence header.
*/
// The h264 raw data to h264 packet, without flv payload header.
// Mux the sps/pps to flv sequence header packet.
// @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);
/**
* h264 raw data to h264 packet, without flv payload header.
* mux the ibp to flv ibp packet.
* @param ibp output the packet.
* @param frame_type output the frame type.
*/
// The h264 raw data to h264 packet, without flv payload header.
// Mux the ibp to flv ibp packet.
// @param ibp output the packet.
// @param frame_type output the frame type.
virtual srs_error_t mux_ipb_frame(char* frame, int nb_frame, std::string& ibp);
/**
* mux the avc video packet to flv video packet.
* @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame.
* @param avc_packet_type, SrsVideoAvcFrameTraitSequenceHeader or SrsVideoAvcFrameTraitNALU.
* @param video the h.264 raw data.
* @param flv output the muxed flv packet.
* @param nb_flv output the muxed flv size.
*/
// Mux the avc video packet to flv video packet.
// @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame.
// @param avc_packet_type, SrsVideoAvcFrameTraitSequenceHeader or SrsVideoAvcFrameTraitNALU.
// @param video the h.264 raw data.
// @param flv output the muxed flv packet.
// @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);
};
/**
* the header of adts sample.
*/
// The header of adts sample.
struct SrsRawAacStreamCodec
{
int8_t protection_absent;
@ -103,37 +87,29 @@ struct SrsRawAacStreamCodec
int8_t aac_packet_type;
};
/**
* the raw aac stream, in adts.
*/
// The raw aac stream, in adts.
class SrsRawAacStream
{
public:
SrsRawAacStream();
virtual ~SrsRawAacStream();
public:
/**
* demux the stream in adts format.
* @param stream the input stream bytes.
* @param pframe the output aac frame in stream. user should never free it.
* @param pnb_frame the output aac frame size.
* @param codec the output codec info.
*/
// Demux the stream in adts format.
// @param stream the input stream bytes.
// @param pframe the output aac frame in stream. user should never free it.
// @param pnb_frame the output aac frame size.
// @param codec the output codec info.
virtual srs_error_t adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec);
/**
* aac raw data to aac packet, without flv payload header.
* mux the aac specific config to flv sequence header packet.
* @param sh output the sequence header.
*/
// Mux aac raw data to aac packet, without flv payload header.
// Mux the aac specific config to flv sequence header packet.
// @param sh output the sequence header.
virtual srs_error_t mux_sequence_header(SrsRawAacStreamCodec* codec, std::string& sh);
/**
* mux the aac audio packet to flv audio packet.
* @param frame the aac raw data.
* @param nb_frame the count of aac frame.
* @param codec the codec info of aac.
* @param flv output the muxed flv packet.
* @param nb_flv output the muxed flv size.
*/
// Mux the aac audio packet to flv audio packet.
// @param frame the aac raw data.
// @param nb_frame the count of aac frame.
// @param codec the codec info of aac.
// @param flv output the muxed flv packet.
// @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);
};

View file

@ -31,21 +31,19 @@ class SrsComplexHandshake;
class SrsHandshakeBytes;
class SrsBuffer;
// for openssl.
// For openssl.
#include <openssl/hmac.h>
namespace _srs_internal
{
// the digest key generate size.
// The digest key generate size.
#define SRS_OpensslHashSize 512
extern uint8_t SrsGenuineFMSKey[];
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_generate_key(char* public_key, int32_t size);
/**
* the DH wrapper.
*/
// The DH wrapper.
class SrsDH
{
private:
@ -56,62 +54,48 @@ namespace _srs_internal
private:
virtual void close();
public:
/**
* initialize dh, generate the public and private key.
* @param ensure_128bytes_public_key whether ensure public key is 128bytes,
* sometimes openssl generate 127bytes public key.
* default to false to donot ensure.
*/
// Initialize dh, generate the public and private key.
// @param ensure_128bytes_public_key whether ensure public key is 128bytes,
// sometimes openssl generate 127bytes public key.
// default to false to donot ensure.
virtual srs_error_t initialize(bool ensure_128bytes_public_key = false);
/**
* 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.
* user should never ignore this size.
* @remark, when ensure_128bytes_public_key, the size always 128.
*/
// 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.
// user should never ignore this size.
// @remark, when ensure_128bytes_public_key, the size always 128.
virtual srs_error_t copy_public_key(char* pkey, int32_t& pkey_size);
/**
* generate and copy the shared key.
* generate the shared key with peer public key.
* @param ppkey peer public key.
* @param ppkey_size the size of ppkey.
* @param skey the computed shared key.
* @param skey_size the max shared key size, output the actual shared key size.
* user should never ignore this size.
*/
// Generate and copy the shared key.
// Generate the shared key with peer public key.
// @param ppkey peer public key.
// @param ppkey_size the size of ppkey.
// @param skey the computed shared key.
// @param skey_size the max shared key size, output the actual shared key 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);
private:
virtual srs_error_t do_initialize();
};
/**
* the schema type.
*/
// The schema type.
enum srs_schema_type
{
srs_schema_invalid = 2,
/**
* key-digest sequence
*/
// The key-digest sequence
srs_schema0 = 0,
/**
* digest-key sequence
* @remark, FMS requires the schema1(digest-key), or connect failed.
*/
// The digest-key sequence
// @remark, FMS requires the schema1(digest-key), or connect failed.
//
srs_schema1 = 1,
};
/**
* 764bytes key structure
* random-data: (offset)bytes
* key-data: 128bytes
* random-data: (764-offset-128-4)bytes
* offset: 4bytes
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
*/
// The 764bytes key structure
// random-data: (offset)bytes
// key-data: 128bytes
// random-data: (764-offset-128-4)bytes
// offset: 4bytes
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
class key_block
{
public:
@ -132,24 +116,22 @@ namespace _srs_internal
key_block();
virtual ~key_block();
public:
// parse key block from c1s1.
// Parse key block from c1s1.
// if created, user must free it by srs_key_block_free
// @stream contains c1s1_key_bytes the key start bytes
srs_error_t parse(SrsBuffer* stream);
private:
// calc the offset of key,
// the key->offset cannot be used as the offset of key.
// Calculate the offset of key,
// The key->offset cannot be used as the offset of key.
int calc_valid_offset();
};
/**
* 764bytes digest structure
* offset: 4bytes
* random-data: (offset)bytes
* digest-data: 32bytes
* random-data: (764-4-offset-32)bytes
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
*/
// The 764bytes digest structure
// offset: 4bytes
// random-data: (offset)bytes
// digest-data: 32bytes
// random-data: (764-4-offset-32)bytes
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
class digest_block
{
public:
@ -170,23 +152,21 @@ namespace _srs_internal
digest_block();
virtual ~digest_block();
public:
// parse digest block from c1s1.
// Parse digest block from c1s1.
// if created, user must free it by srs_digest_block_free
// @stream contains c1s1_digest_bytes the digest start bytes
srs_error_t parse(SrsBuffer* stream);
private:
// calc the offset of digest,
// the key->offset cannot be used as the offset of digest.
// Calculate the offset of digest,
// The key->offset cannot be used as the offset of digest.
int calc_valid_offset();
};
class c1s1;
/**
* the c1s1 strategy, use schema0 or schema1.
* the template method class to defines common behaviors,
* while the concrete class to implements in schema0 or schema1.
*/
// The c1s1 strategy, use schema0 or schema1.
// The template method class to defines common behaviors,
// while the concrete class to implements in schema0 or schema1.
class c1s1_strategy
{
protected:
@ -196,114 +176,82 @@ namespace _srs_internal
c1s1_strategy();
virtual ~c1s1_strategy();
public:
/**
* get the scema.
*/
// Get the scema.
virtual srs_schema_type schema() = 0;
/**
* get the digest.
*/
// Get the digest.
virtual char* get_digest();
/**
* get the key.
*/
// Get the key.
virtual char* get_key();
/**
* copy to bytes.
* @param size must be 1536.
*/
// Copy to bytes.
// @param size must be 1536.
virtual srs_error_t dump(c1s1* owner, char* _c1s1, int size);
/**
* server: parse the c1s1, discovery the key and digest by schema.
* use the c1_validate_digest() to valid the digest of c1.
*/
// For server: parse the c1s1, discovery the key and digest by schema.
// use the c1_validate_digest() to valid the digest of c1.
virtual srs_error_t parse(char* _c1s1, int size) = 0;
public:
/**
* client: create and sign c1 by schema.
* sign the c1, generate the digest.
* calc_c1_digest(c1, schema) {
* get c1s1-joined from c1 by specified schema
* digest-data = HMACsha256(c1s1-joined, FPKey, 30)
* return digest-data;
* }
* random fill 1536bytes c1 // also fill the c1-128bytes-key
* time = time() // c1[0-3]
* version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
* schema = choose schema0 or schema1
* digest-data = calc_c1_digest(c1, schema)
* copy digest-data to c1
*/
// For client: create and sign c1 by schema.
// sign the c1, generate the digest.
// calc_c1_digest(c1, schema) {
// get c1s1-joined from c1 by specified schema
// digest-data = HMACsha256(c1s1-joined, FPKey, 30)
// return digest-data;
// }
// random fill 1536bytes c1 // also fill the c1-128bytes-key
// time = time() // c1[0-3]
// version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
// schema = choose schema0 or schema1
// digest-data = calc_c1_digest(c1, schema)
// copy digest-data to c1
virtual srs_error_t c1_create(c1s1* owner);
/**
* server: validate the parsed c1 schema
*/
// For server: validate the parsed c1 schema
virtual srs_error_t c1_validate_digest(c1s1* owner, bool& is_valid);
/**
* server: create and sign the s1 from c1.
* // decode c1 try schema0 then schema1
* c1-digest-data = get-c1-digest-data(schema0)
* if c1-digest-data equals to calc_c1_digest(c1, schema0) {
* c1-key-data = get-c1-key-data(schema0)
* schema = schema0
* } else {
* c1-digest-data = get-c1-digest-data(schema1)
* if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
* switch to simple handshake.
* return
* }
* c1-key-data = get-c1-key-data(schema1)
* schema = schema1
* }
*
* // generate s1
* random fill 1536bytes s1
* time = time() // c1[0-3]
* version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
* s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
* get c1s1-joined by specified schema
* s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
* copy s1-digest-data and s1-key-data to s1.
* @param c1, to get the peer_pub_key of client.
*/
// For server: create and sign the s1 from c1.
// // decode c1 try schema0 then schema1
// c1-digest-data = get-c1-digest-data(schema0)
// if c1-digest-data equals to calc_c1_digest(c1, schema0) {
// c1-key-data = get-c1-key-data(schema0)
// schema = schema0
// } else {
// c1-digest-data = get-c1-digest-data(schema1)
// if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
// switch to simple handshake.
// return
// }
// c1-key-data = get-c1-key-data(schema1)
// schema = schema1
// }
//
// // Generate s1
// random fill 1536bytes s1
// time = time() // c1[0-3]
// version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
// s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
// get c1s1-joined by specified schema
// s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
// copy s1-digest-data and s1-key-data to s1.
// @param c1, to get the peer_pub_key of client.
virtual srs_error_t s1_create(c1s1* owner, c1s1* c1);
/**
* server: validate the parsed s1 schema
*/
// For server: validate the parsed s1 schema
virtual srs_error_t s1_validate_digest(c1s1* owner, bool& is_valid);
public:
/**
* calc the digest for c1
*/
// Calculate the digest for c1
virtual srs_error_t calc_c1_digest(c1s1* owner, char*& c1_digest);
/**
* calc the digest for s1
*/
// Calculate the digest for s1
virtual srs_error_t calc_s1_digest(c1s1* owner, char*& s1_digest);
/**
* copy whole c1s1 to bytes.
* @param size must always be 1536 with digest, and 1504 without digest.
*/
// Copy whole c1s1 to bytes.
// @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;
/**
* copy time and version to stream.
*/
// Copy time and version to stream.
virtual void copy_time_version(SrsBuffer* stream, c1s1* owner);
/**
* copy key to stream.
*/
// Copy key to stream.
virtual void copy_key(SrsBuffer* stream);
/**
* copy digest to stream.
*/
// Copy digest to stream.
virtual void copy_digest(SrsBuffer* stream, bool with_digest);
};
/**
* c1s1 schema0
* key: 764bytes
* digest: 764bytes
*/
// The c1s1 schema0
// key: 764bytes
// digest: 764bytes
class c1s1_strategy_schema0 : public c1s1_strategy
{
public:
@ -316,11 +264,9 @@ namespace _srs_internal
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest);
};
/**
* c1s1 schema1
* digest: 764bytes
* key: 764bytes
*/
// The c1s1 schema1
// digest: 764bytes
// key: 764bytes
class c1s1_strategy_schema1 : public c1s1_strategy
{
public:
@ -333,19 +279,17 @@ namespace _srs_internal
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest);
};
/**
* c1s1 schema0
* time: 4bytes
* version: 4bytes
* key: 764bytes
* digest: 764bytes
* c1s1 schema1
* time: 4bytes
* version: 4bytes
* digest: 764bytes
* key: 764bytes
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
*/
// The c1s1 schema0
// time: 4bytes
// version: 4bytes
// key: 764bytes
// digest: 764bytes
// The c1s1 schema1
// time: 4bytes
// version: 4bytes
// digest: 764bytes
// key: 764bytes
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
class c1s1
{
public:
@ -359,92 +303,72 @@ namespace _srs_internal
c1s1();
virtual ~c1s1();
public:
/**
* get the scema.
*/
// Get the scema.
virtual srs_schema_type schema();
/**
* get the digest key.
*/
// Get the digest key.
virtual char* get_digest();
/**
* get the key.
*/
// Get the key.
virtual char* get_key();
public:
/**
* copy to bytes.
* @param size, must always be 1536.
*/
// Copy to bytes.
// @param size, must always be 1536.
virtual srs_error_t dump(char* _c1s1, int size);
/**
* server: parse the c1s1, discovery the key and digest by schema.
* @param size, must always be 1536.
* use the c1_validate_digest() to valid the digest of c1.
* use the s1_validate_digest() to valid the digest of s1.
*/
// For server: parse the c1s1, discovery the key and digest by schema.
// @param size, must always be 1536.
// use the c1_validate_digest() to valid the digest of c1.
// use the s1_validate_digest() to valid the digest of s1.
virtual srs_error_t parse(char* _c1s1, int size, srs_schema_type _schema);
public:
/**
* client: create and sign c1 by schema.
* sign the c1, generate the digest.
* calc_c1_digest(c1, schema) {
* get c1s1-joined from c1 by specified schema
* digest-data = HMACsha256(c1s1-joined, FPKey, 30)
* return digest-data;
* }
* random fill 1536bytes c1 // also fill the c1-128bytes-key
* time = time() // c1[0-3]
* version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
* schema = choose schema0 or schema1
* digest-data = calc_c1_digest(c1, schema)
* copy digest-data to c1
*/
// For client: create and sign c1 by schema.
// sign the c1, generate the digest.
// calc_c1_digest(c1, schema) {
// get c1s1-joined from c1 by specified schema
// digest-data = HMACsha256(c1s1-joined, FPKey, 30)
// return digest-data;
// }
// random fill 1536bytes c1 // also fill the c1-128bytes-key
// time = time() // c1[0-3]
// version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
// schema = choose schema0 or schema1
// digest-data = calc_c1_digest(c1, schema)
// copy digest-data to c1
virtual srs_error_t c1_create(srs_schema_type _schema);
/**
* server: validate the parsed c1 schema
*/
// For server: validate the parsed c1 schema
virtual srs_error_t c1_validate_digest(bool& is_valid);
public:
/**
* server: create and sign the s1 from c1.
* // decode c1 try schema0 then schema1
* c1-digest-data = get-c1-digest-data(schema0)
* if c1-digest-data equals to calc_c1_digest(c1, schema0) {
* c1-key-data = get-c1-key-data(schema0)
* schema = schema0
* } else {
* c1-digest-data = get-c1-digest-data(schema1)
* if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
* switch to simple handshake.
* return
* }
* c1-key-data = get-c1-key-data(schema1)
* schema = schema1
* }
*
* // generate s1
* random fill 1536bytes s1
* time = time() // c1[0-3]
* version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
* s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
* get c1s1-joined by specified schema
* s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
* copy s1-digest-data and s1-key-data to s1.
*/
// For server: create and sign the s1 from c1.
// // decode c1 try schema0 then schema1
// c1-digest-data = get-c1-digest-data(schema0)
// if c1-digest-data equals to calc_c1_digest(c1, schema0) {
// c1-key-data = get-c1-key-data(schema0)
// schema = schema0
// } else {
// c1-digest-data = get-c1-digest-data(schema1)
// if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
// switch to simple handshake.
// return
// }
// c1-key-data = get-c1-key-data(schema1)
// schema = schema1
// }
//
// // Generate s1
// random fill 1536bytes s1
// time = time() // c1[0-3]
// version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
// s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
// get c1s1-joined by specified schema
// s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
// copy s1-digest-data and s1-key-data to s1.
virtual srs_error_t s1_create(c1s1* c1);
/**
* server: validate the parsed s1 schema
*/
// For server: validate the parsed s1 schema
virtual srs_error_t s1_validate_digest(bool& is_valid);
};
/**
* the c2s2 complex handshake structure.
* random-data: 1504bytes
* digest-data: 32bytes
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
*/
// The c2s2 complex handshake structure.
// random-data: 1504bytes
// digest-data: 32bytes
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
class c2s2
{
public:
@ -454,85 +378,65 @@ namespace _srs_internal
c2s2();
virtual ~c2s2();
public:
/**
* copy to bytes.
* @param size, must always be 1536.
*/
// Copy to bytes.
// @param size, must always be 1536.
virtual srs_error_t dump(char* _c2s2, int size);
/**
* parse the c2s2
* @param size, must always be 1536.
*/
// Parse the c2s2
// @param size, must always be 1536.
virtual srs_error_t parse(char* _c2s2, int size);
public:
/**
* create c2.
* random fill c2s2 1536 bytes
*
* // client generate C2, or server valid C2
* temp-key = HMACsha256(s1-digest, FPKey, 62)
* c2-digest-data = HMACsha256(c2-random-data, temp-key, 32)
*/
// Create c2.
// random fill c2s2 1536 bytes
//
// // client generate C2, or server valid C2
// temp-key = HMACsha256(s1-digest, FPKey, 62)
// c2-digest-data = HMACsha256(c2-random-data, temp-key, 32)
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);
public:
/**
* create s2.
* random fill c2s2 1536 bytes
*
* // server generate S2, or client valid S2
* temp-key = HMACsha256(c1-digest, FMSKey, 68)
* s2-digest-data = HMACsha256(s2-random-data, temp-key, 32)
*/
// Create s2.
// random fill c2s2 1536 bytes
//
// For server generate S2, or client valid S2
// temp-key = HMACsha256(c1-digest, FMSKey, 68)
// s2-digest-data = HMACsha256(s2-random-data, temp-key, 32)
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);
};
}
/**
* simple handshake.
* user can try complex handshake first,
* rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS
*/
// Simple handshake.
// user can try complex handshake first,
// rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS
class SrsSimpleHandshake
{
public:
SrsSimpleHandshake();
virtual ~SrsSimpleHandshake();
public:
/**
* simple handshake.
*/
// Simple handshake.
virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
};
/**
* rtmp complex handshake,
* @see also crtmp(crtmpserver) or librtmp,
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
*/
// Complex handshake,
// @see also crtmp(crtmpserver) or librtmp,
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
class SrsComplexHandshake
{
public:
SrsComplexHandshake();
virtual ~SrsComplexHandshake();
public:
/**
* complex hanshake.
* @return user must:
* continue connect app if success,
* try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS,
* otherwise, disconnect
*/
// Complex hanshake.
// @return user must:
// continue connect app if success,
// try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS,
// otherwise, disconnect
virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
};

View file

@ -28,43 +28,31 @@
class SrsSharedPtrMessage;
/**
* the class to auto free the shared ptr message array.
* when need to get some messages, for instance, from Consumer queue,
* create a message array, whose msgs can used to accept the msgs,
* then send each message and set to NULL.
*
* @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
*/
// The class to auto free the shared ptr message array.
// When need to get some messages, for instance, from Consumer queue,
// create a message array, whose msgs can used to accept the msgs,
// then send each message and set to NULL.
//
// @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
class SrsMessageArray
{
public:
/**
* when user already send all msgs, please set to NULL,
* for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg),
* where send(msg) will always send and free it.
*/
// When user already send all msgs, please set to NULL,
// for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg),
// where send(msg) will always send and free it.
SrsSharedPtrMessage** msgs;
int max;
public:
/**
* create msg array, initialize array to NULL ptrs.
*/
// Create msg array, initialize array to NULL ptrs.
SrsMessageArray(int max_msgs);
/**
* free the msgs not sent out(not NULL).
*/
// Free the msgs not sent out(not NULL).
virtual ~SrsMessageArray();
public:
/**
* free specified count of messages.
*/
// Free specified count of messages.
virtual void free(int count);
private:
/**
* zero initialize the message array.
*/
// Zero initialize the message array.
virtual void zero(int count);
};

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@ class SrsSimpleStream;
class SrsAudioFrame;
class ISrsProtocolReadWriter;
// rtsp specification
// From rtsp specification
// CR = <US-ASCII CR, carriage return (13)>
#define SRS_RTSP_CR SRS_CONSTS_CR // 0x0D
// LF = <US-ASCII LF, linefeed (10)>
@ -78,38 +78,28 @@ class ISrsProtocolReadWriter;
// RTSP-Version
#define SRS_RTSP_VERSION "RTSP/1.0"
/**
* the rtsp sdp parse state.
*/
// The rtsp sdp parse state.
enum SrsRtspSdpState
{
/**
* other sdp properties.
*/
// Other sdp properties.
SrsRtspSdpStateOthers,
/**
* parse sdp audio state.
*/
// Parse sdp audio state.
SrsRtspSdpStateAudio,
/**
* parse sdp video state.
*/
// Parse sdp video state.
SrsRtspSdpStateVideo,
};
/**
* 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57
* The method token indicates the method to be performed on the resource
* identified by the Request-URI. The method is case-sensitive. New
* methods may be defined in the future. Method names may not start with
* a $ character (decimal 24) and must be a token. Methods are
* summarized in Table 2.
* Notes on Table 2: PAUSE is recommended, but not required in that a
* fully functional server can be built that does not support this
* method, for example, for live feeds. If a server does not support a
* particular method, it MUST return "501 Not Implemented" and a client
* SHOULD not try this method again for this server.
*/
// 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57
// The method token indicates the method to be performed on the resource
// identified by the Request-URI. The method is case-sensitive. New
// methods may be defined in the future. Method names may not start with
// a $ character (decimal 24) and must be a token. Methods are
// summarized in Table 2.
// Notes on Table 2: PAUSE is recommended, but not required in that a
// fully functional server can be built that does not support this
// method, for example, for live feeds. If a server does not support a
// particular method, it MUST return "501 Not Implemented" and a client
// SHOULD not try this method again for this server.
enum SrsRtspMethod
{
SrsRtspMethodDescribe = 0x0001,
@ -125,237 +115,187 @@ enum SrsRtspMethod
SrsRtspMethodTeardown = 0x0400,
};
/**
* the state of rtsp token.
*/
// The state of rtsp token.
enum SrsRtspTokenState
{
/**
* parse token failed, default state.
*/
// Parse token failed, default state.
SrsRtspTokenStateError = 100,
/**
* when SP follow the token.
*/
// When SP follow the token.
SrsRtspTokenStateNormal = 101,
/**
* when CRLF follow the token.
*/
// When CRLF follow the token.
SrsRtspTokenStateEOF = 102,
};
/**
* the rtp packet.
* 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12
*/
// The rtp packet.
// 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12
class SrsRtpPacket
{
public:
/**
* version (V): 2 bits
* 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
* initially implemented in the \vat" audio tool.)
*/
// The version (V): 2 bits
// 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
// initially implemented in the \vat" audio tool.)
int8_t version; //2bits
/**
* padding (P): 1 bit
* 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
* 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
* lower-layer protocol data unit.
*/
// The padding (P): 1 bit
// 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
// 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
// lower-layer protocol data unit.
int8_t padding; //1bit
/**
* extension (X): 1 bit
* 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.
*/
// The extension (X): 1 bit
// 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.
int8_t extension; //1bit
/**
* CSRC count (CC): 4 bits
* The CSRC count contains the number of CSRC identifiers that follow the fixed header.
*/
// The CSRC count (CC): 4 bits
// The CSRC count contains the number of CSRC identifiers that follow the fixed header.
int8_t csrc_count; //4bits
/**
* marker (M): 1 bit
* 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
* 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).
*/
// The marker (M): 1 bit
// 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
// 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).
int8_t marker; //1bit
/**
* payload type (PT): 7 bits
* 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
* 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
* 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).
* A receiver must ignore packets with payload types that it does not understand.
*/
// The payload type (PT): 7 bits
// 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
// 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
// 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).
// A receiver must ignore packets with payload types that it does not understand.
int8_t payload_type; //7bits
/**
* sequence number: 16 bits
* 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
* 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
* in Section 9.1, because the packets may flow through a translator that does. Techniques for
* choosing unpredictable numbers are discussed in [17].
*/
// The sequence number: 16 bits
// 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
// 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
// in Section 9.1, because the packets may flow through a translator that does. Techniques for
// choosing unpredictable numbers are discussed in [17].
uint16_t sequence_number; //16bits
/**
* timestamp: 32 bits
* 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
* 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
* 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
* 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,
* 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
* 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
* each such block, regardless of whether the block is transmitted in a packet or dropped as
* silent.
*
* 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,
* 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
* of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted
* will still be monotonic.)
*
* RTP timestamps from different media streams may advance at different rates and usually
* have independent, random offsets. Therefore, although these timestamps are sucient to
* 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
* 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
* 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
* described in Section 6.4.
*
* 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
* of encoding delays or other processing. The purpose is to allow synchronized presentation of
* all media sampled at the same time.
*
* 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
* 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
* 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
* the receiver.
*
* 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
* 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
* 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
* 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 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
* timestamp pairs in RTCP SR packets.
*/
// The timestamp: 32 bits
// 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
// 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
// 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
// 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,
// 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
// 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
// each such block, regardless of whether the block is transmitted in a packet or dropped as
// silent.
//
// 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,
// 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
// of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted
// will still be monotonic.)
//
// RTP timestamps from different media streams may advance at different rates and usually
// have independent, random offsets. Therefore, although these timestamps are sucient to
// 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
// 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
// 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
// described in Section 6.4.
//
// 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
// of encoding delays or other processing. The purpose is to allow synchronized presentation of
// all media sampled at the same time.
//
// 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
// 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
// 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
// The receiver.
//
// 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
// 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
// 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
// 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 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
// timestamp pairs in RTCP SR packets.
uint32_t timestamp; //32bits
/**
* SSRC: 32 bits
* 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
* 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
* 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
* 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
* avoid being interpreted as a looped source (see Section 8.2).
*/
// The SSRC: 32 bits
// 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
// 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
// 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
// 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
// avoid being interpreted as a looped source (see Section 8.2).
uint32_t ssrc; //32bits
// the payload.
// The payload.
SrsSimpleStream* payload;
// whether transport in chunked payload.
// Whether transport in chunked payload.
bool chunked;
// whether message is completed.
// Whether message is completed.
// normal message always completed.
// while chunked completed when the last chunk arriaved.
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;
public:
SrsRtpPacket();
virtual ~SrsRtpPacket();
public:
/**
* copy the header from src.
*/
// copy the header from 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);
/**
* decode rtp packet from stream.
*/
// decode rtp packet from stream.
virtual srs_error_t decode(SrsBuffer* stream);
private:
virtual srs_error_t decode_97(SrsBuffer* stream);
virtual srs_error_t decode_96(SrsBuffer* stream);
};
/**
* the sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159
* Appendix C: Use of SDP for RTSP Session Descriptions
* The Session Description Protocol (SDP, RFC 2327 [6]) may be used to
* describe streams or presentations in RTSP.
*/
// The sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159
// Appendix C: Use of SDP for RTSP Session Descriptions
// The Session Description Protocol (SDP, RFC 2327 [6]) may be used to
// describe streams or presentations in RTSP.
class SrsRtspSdp
{
private:
SrsRtspSdpState state;
public:
/**
* the version of sdp.
*/
// The version of sdp.
std::string version;
/**
* the owner/creator of sdp.
*/
// The owner/creator of sdp.
std::string owner_username;
std::string owner_session_id;
std::string owner_session_version;
std::string owner_network_type;
std::string owner_address_type;
std::string owner_address;
/**
* the session name of sdp.
*/
// The session name of sdp.
std::string session_name;
/**
* the connection info of sdp.
*/
// The connection info of sdp.
std::string connection_network_type;
std::string connection_address_type;
std::string connection_address;
/**
* the tool attribute of sdp.
*/
// The tool attribute of sdp.
std::string tool;
/**
* the video attribute of sdp.
*/
// The video attribute of sdp.
std::string video_port;
std::string video_protocol;
std::string video_transport_format;
@ -363,13 +303,11 @@ public:
std::string video_codec;
std::string video_sample_rate;
std::string video_stream_id;
// fmtp
// The fmtp
std::string video_packetization_mode;
std::string video_sps; // sequence header: sps.
std::string video_pps; // sequence header: pps.
/**
* the audio attribute of sdp.
*/
// The audio attribute of sdp.
std::string audio_port;
std::string audio_protocol;
std::string audio_transport_format;
@ -378,7 +316,7 @@ public:
std::string audio_sample_rate;
std::string audio_channel;
std::string audio_stream_id;
// fmtp
// The fmtp
std::string audio_profile_level_id;
std::string audio_mode;
std::string audio_size_length;
@ -389,34 +327,24 @@ public:
SrsRtspSdp();
virtual ~SrsRtspSdp();
public:
/**
* parse a line of token for sdp.
*/
// Parse a line of token for sdp.
virtual srs_error_t parse(std::string token);
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);
/**
* 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);
/**
* decode the string by base64.
*/
// decode the string by base64.
virtual std::string base64_decode(std::string value);
};
/**
* the rtsp transport.
* 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115
* This request header indicates which transport protocol is to be used
* and configures its parameters such as destination address,
* compression, multicast time-to-live and destination port for a single
* stream. It sets those values not already determined by a presentation
* description.
*/
// The rtsp transport.
// 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115
// This request header indicates which transport protocol is to be used
// and configures its parameters such as destination address,
// compression, multicast time-to-live and destination port for a single
// stream. It sets those values not already determined by a presentation
// description.
class SrsRtspTransport
{
public:
@ -431,7 +359,7 @@ public:
// Clients that are capable of handling both unicast and
// multicast transmission MUST indicate such capability by
// including two full transport-specs with separate parameters
// for each.
// For each.
std::string cast_type;
// The mode parameter indicates the methods to be supported for
// this session. Valid values are PLAY and RECORD. If not
@ -449,79 +377,59 @@ public:
SrsRtspTransport();
virtual ~SrsRtspTransport();
public:
/**
* parse a line of token for transport.
*/
// Parse a line of token for transport.
virtual srs_error_t parse(std::string attr);
};
/**
* the rtsp request message.
* 6 Request, @see rfc2326-1998-rtsp.pdf, page 39
* 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
* the resource, the identifier of the resource, and the protocol
* version in use.
* Request = Request-Line ; Section 6.1
* *( general-header ; Section 5
* | request-header ; Section 6.2
* | entity-header ) ; Section 8.1
* CRLF
* [ message-body ] ; Section 4.3
*/
// The rtsp request message.
// 6 Request, @see rfc2326-1998-rtsp.pdf, page 39
// 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
// The resource, the identifier of the resource, and the protocol
// version in use.
// Request = Request-Line ; Section 6.1
// // ( general-header ; Section 5
// | request-header ; Section 6.2
// | entity-header ) ; Section 8.1
// CRLF
// [ message-body ] ; Section 4.3
class SrsRtspRequest
{
public:
/**
* 6.1 Request Line
* Request-Line = Method SP Request-URI SP RTSP-Version CRLF
*/
// 6.1 Request Line
// Request-Line = Method SP Request-URI SP RTSP-Version CRLF
std::string method;
std::string uri;
std::string version;
/**
* 12.17 CSeq
* The CSeq field specifies the sequence number for an RTSP requestresponse
* pair. This field MUST be present in all requests and
* responses. For every RTSP request containing the given sequence
* number, there will be a corresponding response having the same
* number. Any retransmitted request must contain the same sequence
* number as the original (i.e. the sequence number is not incremented
* for retransmissions of the same request).
*/
// 12.17 CSeq
// The CSeq field specifies the sequence number for an RTSP requestresponse
// pair. This field MUST be present in all requests and
// responses. For every RTSP request containing the given sequence
// number, there will be a corresponding response having the same
// number. Any retransmitted request must contain the same sequence
// number as the original (i.e. the sequence number is not incremented
// For retransmissions of the same request).
long seq;
/**
* 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99
* See [H14.18]. Note that the content types suitable for RTSP are
* likely to be restricted in practice to presentation descriptions and
* parameter-value types.
*/
// 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99
// See [H14.18]. Note that the content types suitable for RTSP are
// likely to be restricted in practice to presentation descriptions and
// parameter-value types.
std::string content_type;
/**
* 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99
* This field contains the length of the content of the method (i.e.
* after the double CRLF following the last header). Unlike HTTP, it
* 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
* assumed. It is interpreted according to [H14.14].
*/
// 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99
// This field contains the length of the content of the method (i.e.
// after the double CRLF following the last header). Unlike HTTP, it
// 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
// assumed. It is interpreted according to [H14.14].
long content_length;
/**
* the session id.
*/
// The session id.
std::string session;
/**
* the sdp in announce, NULL for no sdp.
*/
// The sdp in announce, NULL for no sdp.
SrsRtspSdp* sdp;
/**
* the transport in setup, NULL for no transport.
*/
// The transport in setup, NULL for no transport.
SrsRtspTransport* transport;
/**
* for setup message, parse the stream id from uri.
*/
// For setup message, parse the stream id from uri.
int stream_id;
public:
SrsRtspRequest();
@ -533,79 +441,63 @@ public:
virtual bool is_record();
};
/**
* the rtsp response message.
* 7 Response, @see rfc2326-1998-rtsp.pdf, page 43
* [H6] applies except that HTTP-Version is replaced by RTSP-Version.
* Also, RTSP defines additional status codes and does not define some
* HTTP codes. The valid response codes and the methods they can be used
* with are defined in Table 1.
* After receiving and interpreting a request message, the recipient
* responds with an RTSP response message.
* Response = Status-Line ; Section 7.1
* *( general-header ; Section 5
* | response-header ; Section 7.1.2
* | entity-header ) ; Section 8.1
* CRLF
* [ message-body ] ; Section 4.3
*/
// The rtsp response message.
// 7 Response, @see rfc2326-1998-rtsp.pdf, page 43
// [H6] applies except that HTTP-Version is replaced by RTSP-Version.
// Also, RTSP defines additional status codes and does not define some
// HTTP codes. The valid response codes and the methods they can be used
// with are defined in Table 1.
// After receiving and interpreting a request message, the recipient
// responds with an RTSP response message.
// Response = Status-Line ; Section 7.1
// // ( general-header ; Section 5
// | response-header ; Section 7.1.2
// | entity-header ) ; Section 8.1
// CRLF
// [ message-body ] ; Section 4.3
class SrsRtspResponse
{
public:
/**
* 7.1 Status-Line
* The first line of a Response message is the Status-Line, consisting
* of the protocol version followed by a numeric status code, and the
* textual phrase associated with the status code, with each element
* separated by SP characters. No CR or LF is allowed except in the
* final CRLF sequence.
* Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
*/
// 7.1 Status-Line
// The first line of a Response message is the Status-Line, consisting
// of the protocol version followed by a numeric status code, and the
// textual phrase associated with the status code, with each element
// separated by SP characters. No CR or LF is allowed except in the
// final CRLF sequence.
// Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
// @see about the version of rtsp, see SRS_RTSP_VERSION
// @see about the status of rtsp, see SRS_CONSTS_RTSP_OK
int status;
/**
* 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99
* The CSeq field specifies the sequence number for an RTSP requestresponse
* pair. This field MUST be present in all requests and
* responses. For every RTSP request containing the given sequence
* number, there will be a corresponding response having the same
* number. Any retransmitted request must contain the same sequence
* number as the original (i.e. the sequence number is not incremented
* for retransmissions of the same request).
*/
// 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99
// The CSeq field specifies the sequence number for an RTSP requestresponse
// pair. This field MUST be present in all requests and
// responses. For every RTSP request containing the given sequence
// number, there will be a corresponding response having the same
// number. Any retransmitted request must contain the same sequence
// number as the original (i.e. the sequence number is not incremented
// For retransmissions of the same request).
long seq;
/**
* the session id.
*/
// The session id.
std::string session;
public:
SrsRtspResponse(int cseq);
virtual ~SrsRtspResponse();
public:
/**
* encode message to string.
*/
// Encode message to string.
virtual srs_error_t encode(std::stringstream& ss);
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);
};
/**
* 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59
* 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
* try a nonstandard request. It does not influence server state.
*/
// 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59
// 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
// try a nonstandard request. It does not influence server state.
class SrsRtspOptionsResponse : public SrsRtspResponse
{
public:
/**
* join of SrsRtspMethod
*/
// Join of SrsRtspMethod
SrsRtspMethod methods;
public:
SrsRtspOptionsResponse(int cseq);
@ -614,28 +506,26 @@ protected:
virtual srs_error_t encode_header(std::stringstream& ss);
};
/**
* 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65
* 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
* stream that is already playing to change transport parameters, which
* 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
* intervening firewalls, a client must indicate the transport
* parameters even if it has no influence over these parameters, for
* example, where the server advertises a fixed multicast address.
*/
// 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65
// 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
// stream that is already playing to change transport parameters, which
// 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
// intervening firewalls, a client must indicate the transport
// parameters even if it has no influence over these parameters, for
// example, where the server advertises a fixed multicast address.
class SrsRtspSetupResponse : public SrsRtspResponse
{
public:
// the client specified port.
// The client specified port.
int client_port_min;
int client_port_max;
// client will use the port in:
// The client will use the port in:
// [local_port_min, local_port_max)
int local_port_min;
int local_port_max;
// session.
// The session.
std::string session;
public:
SrsRtspSetupResponse(int cseq);
@ -644,65 +534,45 @@ protected:
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
{
private:
/**
* cached bytes buffer.
*/
// The cached bytes buffer.
SrsSimpleStream* buf;
/**
* underlayer socket object, send/recv bytes.
*/
// The underlayer socket object, send/recv bytes.
ISrsProtocolReadWriter* skt;
public:
SrsRtspStack(ISrsProtocolReadWriter* s);
virtual ~SrsRtspStack();
public:
/**
* recv rtsp message from underlayer io.
* @param preq the output rtsp request message, which user must free it.
* @return an int error code.
* ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
*/
// Recv rtsp message from underlayer io.
// @param preq the output rtsp request message, which user must free it.
// @return an int error code.
// ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
virtual srs_error_t recv_message(SrsRtspRequest** preq);
/**
* send rtsp message over underlayer io.
* @param res the rtsp response message, which user should never free it.
* @return an int error code.
*/
// Send rtsp message over underlayer io.
// @param res the rtsp response message, which user should never free it.
// @return an int error code.
virtual srs_error_t send_message(SrsRtspResponse* res);
private:
/**
* recv the rtsp message.
*/
// Recv the rtsp message.
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);
/**
* 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);
/**
* 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.
*/
// 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.
virtual srs_error_t recv_token_util_eof(std::string& token, int* pconsumed = NULL);
/**
* read a token from io, split by SP, endswith CRLF:
* token1 SP token2 SP ... tokenN CRLF
* @param token, output the read token.
* @param state, output the token parse state.
* @param normal_ch, the char to indicates the normal token.
* 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
* @param pconsumed, output the token parsed length. NULL to ignore.
*/
// Read a token from io, split by SP, endswith CRLF:
// token1 SP token2 SP ... tokenN CRLF
// @param token, output the read token.
// @param state, output the token parse state.
// @param normal_ch, the char to indicates the normal token.
// 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
// @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);
};