mirror of
https://github.com/ossrs/srs.git
synced 2025-02-14 20:31:56 +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>
|
||||
|
||||
// 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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue