1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00

Refine typo in protocol.

This commit is contained in:
winlin 2019-04-23 08:06:50 +08:00
parent 35fe05d62c
commit 8bc77387ff
7 changed files with 1328 additions and 2117 deletions

View file

@ -26,7 +26,7 @@
#include <srs_core.hpp> #include <srs_core.hpp>
// default http listen port. // Default http listen port.
#define SRS_DEFAULT_HTTP_PORT 80 #define SRS_DEFAULT_HTTP_PORT 80
#if !defined(SRS_EXPORT_LIBRTMP) #if !defined(SRS_EXPORT_LIBRTMP)
@ -35,7 +35,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 // For srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32 #ifndef _WIN32
#include <sys/uio.h> #include <sys/uio.h>
#endif #endif
@ -46,7 +46,7 @@ class ISrsHttpMessage;
class SrsHttpMuxEntry; class SrsHttpMuxEntry;
class ISrsHttpResponseWriter; class ISrsHttpResponseWriter;
// http specification // From http specification
// CR = <US-ASCII CR, carriage return (13)> // CR = <US-ASCII CR, carriage return (13)>
#define SRS_HTTP_CR SRS_CONSTS_CR // 0x0D #define SRS_HTTP_CR SRS_CONSTS_CR // 0x0D
// LF = <US-ASCII LF, linefeed (10)> // LF = <US-ASCII LF, linefeed (10)>
@ -65,10 +65,10 @@ class ISrsHttpResponseWriter;
// @see ISrsHttpMessage._http_ts_send_buffer // @see ISrsHttpMessage._http_ts_send_buffer
#define SRS_HTTP_TS_SEND_BUFFER_SIZE 4096 #define SRS_HTTP_TS_SEND_BUFFER_SIZE 4096
// for ead all of http body, read each time. // For ead all of http body, read each time.
#define SRS_HTTP_READ_CACHE_BYTES 4096 #define SRS_HTTP_READ_CACHE_BYTES 4096
// for http parser macros // For http parser macros
#define SRS_CONSTS_HTTP_OPTIONS HTTP_OPTIONS #define SRS_CONSTS_HTTP_OPTIONS HTTP_OPTIONS
#define SRS_CONSTS_HTTP_GET HTTP_GET #define SRS_CONSTS_HTTP_GET HTTP_GET
#define SRS_CONSTS_HTTP_POST HTTP_POST #define SRS_CONSTS_HTTP_POST HTTP_POST
@ -80,10 +80,10 @@ class ISrsHttpResponseWriter;
extern srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code); extern srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code);
extern srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code, std::string error); extern srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code, std::string error);
// get the status text of code. // Get the status text of code.
extern std::string srs_generate_http_status_text(int status); extern std::string srs_generate_http_status_text(int status);
// bodyAllowedForStatus reports whether a given response status code // It reports whether a given response status code
// permits a body. See RFC2616, section 4.4. // permits a body. See RFC2616, section 4.4.
extern bool srs_go_http_body_allowd(int status); extern bool srs_go_http_body_allowd(int status);
@ -95,7 +95,7 @@ extern bool srs_go_http_body_allowd(int status);
// returns "application/octet-stream". // returns "application/octet-stream".
extern std::string srs_go_http_detect(char* data, int size); extern std::string srs_go_http_detect(char* data, int size);
// state of message // The state of HTTP message
enum SrsHttpParseState { enum SrsHttpParseState {
SrsHttpParseStateInit = 0, SrsHttpParseStateInit = 0,
SrsHttpParseStateStart, SrsHttpParseStateStart,
@ -121,27 +121,17 @@ public:
// with CanonicalHeaderKey. // with CanonicalHeaderKey.
virtual std::string get(std::string key); virtual std::string get(std::string key);
public: public:
/** // Get the content length. -1 if not set.
* get the content length. -1 if not set.
*/
virtual int64_t content_length(); virtual int64_t content_length();
/** // set the content length by header "Content-Length"
* set the content length by header "Content-Length"
*/
virtual void set_content_length(int64_t size); virtual void set_content_length(int64_t size);
public: public:
/** // Get the content type. empty string if not set.
* get the content type. empty string if not set.
*/
virtual std::string content_type(); virtual std::string content_type();
/** // set the content type by header "Content-Type"
* set the content type by header "Content-Type"
*/
virtual void set_content_type(std::string ct); virtual void set_content_type(std::string ct);
public: public:
/** // write all headers to string stream.
* write all headers to string stream.
*/
virtual void write(std::stringstream& ss); virtual void write(std::stringstream& ss);
}; };
@ -176,9 +166,9 @@ public:
ISrsHttpResponseWriter(); ISrsHttpResponseWriter();
virtual ~ISrsHttpResponseWriter(); virtual ~ISrsHttpResponseWriter();
public: public:
// when chunked mode, // When chunked mode,
// final the request to complete the chunked encoding. // final the request to complete the chunked encoding.
// for no-chunked mode, // For no-chunked mode,
// final to send request, for example, content-length is 0. // final to send request, for example, content-length is 0.
virtual srs_error_t final_request() = 0; virtual srs_error_t final_request() = 0;
@ -191,13 +181,11 @@ public:
// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK) // If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
// before writing the data. If the Header does not contain a // before writing the data. If the Header does not contain a
// Content-Type line, Write adds a Content-Type set to the result of passing // Content-Type line, Write adds a Content-Type set to the result of passing
// the initial 512 bytes of written data to DetectContentType. // The initial 512 bytes of written data to DetectContentType.
// @param data, the data to send. NULL to flush header only. // @param data, the data to send. NULL to flush header only.
virtual srs_error_t write(char* data, int size) = 0; virtual srs_error_t write(char* data, int size) = 0;
/** // for the HTTP FLV, to writev to improve performance.
* for the HTTP FLV, to writev to improve performance. // @see https://github.com/ossrs/srs/issues/405
* @see https://github.com/ossrs/srs/issues/405
*/
virtual srs_error_t writev(const iovec* iov, int iovcnt, ssize_t* pnwrite) = 0; virtual srs_error_t writev(const iovec* iov, int iovcnt, ssize_t* pnwrite) = 0;
// WriteHeader sends an HTTP response header with status code. // WriteHeader sends an HTTP response header with status code.
@ -209,32 +197,26 @@ public:
virtual void write_header(int code) = 0; virtual void write_header(int code) = 0;
}; };
/** // The reader interface for http response.
* the reader interface for http response.
*/
class ISrsHttpResponseReader class ISrsHttpResponseReader
{ {
public: public:
ISrsHttpResponseReader(); ISrsHttpResponseReader();
virtual ~ISrsHttpResponseReader(); virtual ~ISrsHttpResponseReader();
public: public:
/** // Whether response read EOF.
* whether response read EOF.
*/
virtual bool eof() = 0; virtual bool eof() = 0;
/** // Read from the response body.
* read from the response body. // @param data, the buffer to read data buffer to.
* @param data, the buffer to read data buffer to. // @param nb_data, the max size of data buffer.
* @param nb_data, the max size of data buffer. // @param nb_read, the actual read size of bytes. NULL to ignore.
* @param nb_read, the actual read size of bytes. NULL to ignore. // @remark when eof(), return error.
* @remark when eof(), return error. // @remark for some server, the content-length not specified and not chunked,
* @remark for some server, the content-length not specified and not chunked, // which is actually the infinite chunked encoding, which after http header
* which is actually the infinite chunked encoding, which after http header // is http response data, it's ok for browser. that is,
* is http response data, it's ok for browser. that is, // when user call this read, please ensure there is data to read(by content-length
* when user call this read, please ensure there is data to read(by content-length // or by chunked), because the sdk never know whether there is no data or
* or by chunked), because the sdk never know whether there is no data or // infinite chunked.
* infinite chunked.
*/
virtual srs_error_t read(char* data, int nb_data, int* nb_read) = 0; virtual srs_error_t read(char* data, int nb_data, int* nb_read) = 0;
}; };
@ -245,7 +227,7 @@ public:
// ServeHTTP should write reply headers and data to the ResponseWriter // ServeHTTP should write reply headers and data to the ResponseWriter
// and then return. Returning signals that the request is finished // and then return. Returning signals that the request is finished
// and that the HTTP server can move on to the next request on // and that the HTTP server can move on to the next request on
// the connection. // The connection.
class ISrsHttpHandler class ISrsHttpHandler
{ {
public: public:
@ -300,33 +282,25 @@ public:
public: public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
private: private:
/** // Serve the file by specified path
* serve the file by specified path
*/
virtual srs_error_t serve_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath); virtual srs_error_t serve_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
virtual srs_error_t serve_flv_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath); virtual srs_error_t serve_flv_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
virtual srs_error_t serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath); virtual srs_error_t serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
protected: protected:
/** // When access flv file with x.flv?start=xxx
* when access flv file with x.flv?start=xxx
*/
virtual srs_error_t serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int offset); virtual srs_error_t serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int offset);
/** // When access mp4 file with x.mp4?range=start-end
* when access mp4 file with x.mp4?range=start-end // @param start the start offset in bytes.
* @param start the start offset in bytes. // @param end the end offset in bytes. -1 to end of file.
* @param end the end offset in bytes. -1 to end of file. // @remark response data in [start, end].
* @remark response data in [start, end].
*/
virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end); virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end);
protected: protected:
/** // Copy the fs to response writer in size bytes.
* copy the fs to response writer in size bytes.
*/
virtual srs_error_t copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int size); virtual srs_error_t copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int size);
}; };
// the mux entry for server mux. // The mux entry for server mux.
// the matcher info, for example, the pattern and handler. // The matcher info, for example, the pattern and handler.
class SrsHttpMuxEntry class SrsHttpMuxEntry
{ {
public: public:
@ -339,26 +313,20 @@ public:
virtual ~SrsHttpMuxEntry(); virtual ~SrsHttpMuxEntry();
}; };
/** // The hijacker for http pattern match.
* the hijacker for http pattern match.
*/
class ISrsHttpMatchHijacker class ISrsHttpMatchHijacker
{ {
public: public:
ISrsHttpMatchHijacker(); ISrsHttpMatchHijacker();
virtual ~ISrsHttpMatchHijacker(); virtual ~ISrsHttpMatchHijacker();
public: public:
/** // When match the request failed, no handler to process request.
* when match the request failed, no handler to process request. // @param request the http request message to match the handler.
* @param request the http request message to match the handler. // @param ph the already matched handler, hijack can rewrite it.
* @param ph the already matched handler, hijack can rewrite it.
*/
virtual srs_error_t hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) = 0; virtual srs_error_t hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) = 0;
}; };
/** // The server mux, all http server should implements it.
* the server mux, all http server should implements it.
*/
class ISrsHttpServeMux class ISrsHttpServeMux
{ {
public: public:
@ -383,7 +351,7 @@ public:
// "/images/" subtree. // "/images/" subtree.
// //
// Note that since a pattern ending in a slash names a rooted subtree, // Note that since a pattern ending in a slash names a rooted subtree,
// the pattern "/" matches all paths not matched by other registered // The pattern "/" matches all paths not matched by other registered
// patterns, not just the URL with Path == "/". // patterns, not just the URL with Path == "/".
// //
// Patterns may optionally begin with a host name, restricting matches to // Patterns may optionally begin with a host name, restricting matches to
@ -398,29 +366,25 @@ public:
class SrsHttpServeMux : public ISrsHttpServeMux class SrsHttpServeMux : public ISrsHttpServeMux
{ {
private: private:
// the pattern handler, to handle the http request. // The pattern handler, to handle the http request.
std::map<std::string, SrsHttpMuxEntry*> entries; std::map<std::string, SrsHttpMuxEntry*> entries;
// the vhost handler. // The vhost handler.
// when find the handler to process the request, // When find the handler to process the request,
// append the matched vhost when pattern not starts with /, // append the matched vhost when pattern not starts with /,
// for example, for pattern /live/livestream.flv of vhost ossrs.net, // For example, for pattern /live/livestream.flv of vhost ossrs.net,
// the path will rewrite to ossrs.net/live/livestream.flv // The path will rewrite to ossrs.net/live/livestream.flv
std::map<std::string, ISrsHttpHandler*> vhosts; std::map<std::string, ISrsHttpHandler*> vhosts;
// all hijackers for http match. // all hijackers for http match.
// for example, the hstrs(http stream trigger rtmp source) // For example, the hstrs(http stream trigger rtmp source)
// can hijack and install handler when request incoming and no handler. // can hijack and install handler when request incoming and no handler.
std::vector<ISrsHttpMatchHijacker*> hijackers; std::vector<ISrsHttpMatchHijacker*> hijackers;
public: public:
SrsHttpServeMux(); SrsHttpServeMux();
virtual ~SrsHttpServeMux(); virtual ~SrsHttpServeMux();
public: public:
/** // Initialize the http serve mux.
* initialize the http serve mux.
*/
virtual srs_error_t initialize(); virtual srs_error_t initialize();
/** // hijack the http match.
* hijack the http match.
*/
virtual void hijack(ISrsHttpMatchHijacker* h); virtual void hijack(ISrsHttpMatchHijacker* h);
virtual void unhijack(ISrsHttpMatchHijacker* h); virtual void unhijack(ISrsHttpMatchHijacker* h);
public: public:
@ -437,10 +401,8 @@ private:
virtual bool path_match(std::string pattern, std::string path); virtual bool path_match(std::string pattern, std::string path);
}; };
/** // The filter http mux, directly serve the http CORS requests,
* The filter http mux, directly serve the http CORS requests, // while proxy to the worker mux for services.
* while proxy to the worker mux for services.
*/
class SrsHttpCorsMux : public ISrsHttpServeMux class SrsHttpCorsMux : public ISrsHttpServeMux
{ {
private: private:
@ -457,7 +419,7 @@ public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
}; };
// for http header. // For http header.
typedef std::pair<std::string, std::string> SrsHttpHeaderField; typedef std::pair<std::string, std::string> SrsHttpHeaderField;
// A Request represents an HTTP request received by a server // A Request represents an HTTP request received by a server
@ -473,34 +435,28 @@ typedef std::pair<std::string, std::string> SrsHttpHeaderField;
// 3. no body or user not confirmed infinite chunked. // 3. no body or user not confirmed infinite chunked.
// For example: // For example:
// ISrsHttpMessage* r = ...; // ISrsHttpMessage* r = ...;
// while (!r->eof()) r->read(); // read in mode 1 or 3. // while (!r->eof()) r->read(); // Read in mode 1 or 3.
// For some server, we can confirm the body is infinite chunked: // For some server, we can confirm the body is infinite chunked:
// ISrsHttpMessage* r = ...; // ISrsHttpMessage* r = ...;
// r->enter_infinite_chunked(); // r->enter_infinite_chunked();
// while (!r->eof()) r->read(); // read in mode 2 // while (!r->eof()) r->read(); // Read in mode 2
// @rmark for mode 2, the infinite chunked, all left data is body. // @rmark for mode 2, the infinite chunked, all left data is body.
class ISrsHttpMessage class ISrsHttpMessage
{ {
private: private:
/** // Use a buffer to read and send ts file.
* use a buffer to read and send ts file.
*/
// TODO: FIXME: remove it. // TODO: FIXME: remove it.
char* _http_ts_send_buffer; char* _http_ts_send_buffer;
public: public:
ISrsHttpMessage(); ISrsHttpMessage();
virtual ~ISrsHttpMessage(); virtual ~ISrsHttpMessage();
public: public:
/** // The http request level cache.
* the http request level cache.
*/
virtual char* http_ts_send_buffer(); virtual char* http_ts_send_buffer();
public: public:
virtual uint8_t method() = 0; virtual uint8_t method() = 0;
virtual uint16_t status_code() = 0; virtual uint16_t status_code() = 0;
/** // Method helpers.
* method helpers.
*/
virtual std::string method_str() = 0; virtual std::string method_str() = 0;
virtual bool is_http_get() = 0; virtual bool is_http_get() = 0;
virtual bool is_http_put() = 0; virtual bool is_http_put() = 0;
@ -508,94 +464,74 @@ public:
virtual bool is_http_delete() = 0; virtual bool is_http_delete() = 0;
virtual bool is_http_options() = 0; virtual bool is_http_options() = 0;
public: public:
/** // Whether should keep the connection alive.
* whether should keep the connection alive.
*/
virtual bool is_keep_alive() = 0; virtual bool is_keep_alive() = 0;
/** // The uri contains the host and path.
* the uri contains the host and path.
*/
virtual std::string uri() = 0; virtual std::string uri() = 0;
/** // The url maybe the path.
* the url maybe the path.
*/
virtual std::string url() = 0; virtual std::string url() = 0;
virtual std::string host() = 0; virtual std::string host() = 0;
virtual std::string path() = 0; virtual std::string path() = 0;
virtual std::string query() = 0; virtual std::string query() = 0;
virtual std::string ext() = 0; virtual std::string ext() = 0;
/** // Get the RESTful id,
* get the RESTful id, // for example, pattern is /api/v1/streams, path is /api/v1/streams/100,
* for example, pattern is /api/v1/streams, path is /api/v1/streams/100, // then the rest id is 100.
* then the rest id is 100. // @param pattern the handler pattern which will serve the request.
* @param pattern the handler pattern which will serve the request. // @return the REST id; -1 if not matched.
* @return the REST id; -1 if not matched.
*/
virtual int parse_rest_id(std::string pattern) = 0; virtual int parse_rest_id(std::string pattern) = 0;
public: public:
/** // The left all data is chunked body, the infinite chunked mode,
* the left all data is chunked body, the infinite chunked mode, // which is chunked encoding without chunked header.
* which is chunked encoding without chunked header. // @remark error when message is in chunked or content-length specified.
* @remark error when message is in chunked or content-length specified.
*/
virtual srs_error_t enter_infinite_chunked() = 0; virtual srs_error_t enter_infinite_chunked() = 0;
/** // Read body to string.
* read body to string. // @remark for small http body.
* @remark for small http body.
*/
virtual srs_error_t body_read_all(std::string& body) = 0; virtual srs_error_t body_read_all(std::string& body) = 0;
/** // Get the body reader, to read one by one.
* get the body reader, to read one by one. // @remark when body is very large, or chunked, use this.
* @remark when body is very large, or chunked, use this.
*/
virtual ISrsHttpResponseReader* body_reader() = 0; virtual ISrsHttpResponseReader* body_reader() = 0;
/** // The content length, -1 for chunked or not set.
* the content length, -1 for chunked or not set.
*/
virtual int64_t content_length() = 0; virtual int64_t content_length() = 0;
public: public:
/** // Get the param in query string,
* get the param in query string, // for instance, query is "start=100&end=200",
* for instance, query is "start=100&end=200", // then query_get("start") is "100", and query_get("end") is "200"
* then query_get("start") is "100", and query_get("end") is "200"
*/
virtual std::string query_get(std::string key) = 0; virtual std::string query_get(std::string key) = 0;
/** // Get the headers.
* get the headers.
*/
virtual int request_header_count() = 0; virtual int request_header_count() = 0;
virtual std::string request_header_key_at(int index) = 0; virtual std::string request_header_key_at(int index) = 0;
virtual std::string request_header_value_at(int index) = 0; virtual std::string request_header_value_at(int index) = 0;
public: public:
/** // Whether the current request is JSONP,
* whether the current request is JSONP, // which has a "callback=xxx" in QueryString.
* which has a "callback=xxx" in QueryString.
*/
virtual bool is_jsonp() = 0; virtual bool is_jsonp() = 0;
}; };
#endif #endif
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. // The http-parser is license under MIT at https://github.com/nodejs/http-parser/blob/master/LICENSE-MIT
* // Version: 2.1 from https://github.com/nodejs/http-parser/releases/tag/v2.1
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to //Copyright Joyent, Inc. and other Node contributors. All rights reserved.
* deal in the Software without restriction, including without limitation the //
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // Permission is hereby granted, free of charge, to any person obtaining a copy
* sell copies of the Software, and to permit persons to whom the Software is // of this software and associated documentation files (the "Software"), to
* furnished to do so, subject to the following conditions: // deal in the Software without restriction, including without limitation the
* // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* The above copyright notice and this permission notice shall be included in // sell copies of the Software, and to permit persons to whom the Software is
* all copies or substantial portions of the Software. // furnished to do so, subject to the following conditions:
* //
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // The above copyright notice and this permission notice shall be included in
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // all copies or substantial portions of the Software.
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE //
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // The SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* IN THE SOFTWARE. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*/ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
#ifndef http_parser_h #ifndef http_parser_h
#define http_parser_h #define http_parser_h
#ifdef __cplusplus #ifdef __cplusplus
@ -621,9 +557,8 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#endif #endif
/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run // Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
* faster // faster
*/
#ifndef HTTP_PARSER_STRICT #ifndef HTTP_PARSER_STRICT
# define HTTP_PARSER_STRICT 1 # define HTTP_PARSER_STRICT 1
#endif #endif
@ -636,19 +571,18 @@ extern "C" {
typedef struct http_parser_settings http_parser_settings; typedef struct http_parser_settings http_parser_settings;
/* Callbacks should return non-zero to indicate an error. The parser will // Callbacks should return non-zero to indicate an error. The parser will
* then halt execution. // then halt execution.
* //
* The one exception is on_headers_complete. In a HTTP_RESPONSE parser // The one exception is on_headers_complete. In a HTTP_RESPONSE parser
* returning '1' from on_headers_complete will tell the parser that it // returning '1' from on_headers_complete will tell the parser that it
* should not expect a body. This is used when receiving a response to a // should not expect a body. This is used when receiving a response to a
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: // HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
* chunked' headers that indicate the presence of a body. // chunked' headers that indicate the presence of a body.
* //
* http_data_cb does not return data chunks. It will be call arbitrarally // http_data_cb does not return data chunks. It will be call arbitrarally
* many times for each string. E.G. you might get 10 callbacks for "on_url" // many times for each string. E.G. you might get 10 callbacks for "on_url"
* each providing just a few characters more data. // each providing just a few characters more data.
*/
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
typedef int (*http_cb) (http_parser*); typedef int (*http_cb) (http_parser*);
@ -709,10 +643,8 @@ extern "C" {
}; };
/* Map for errno-related constants // Map for errno-related constants
* // The provided argument should be a macro that takes 2 arguments.
* The provided argument should be a macro that takes 2 arguments.
*/
#define HTTP_ERRNO_MAP(XX) \ #define HTTP_ERRNO_MAP(XX) \
/* No error */ \ /* No error */ \
XX(OK, "success") \ XX(OK, "success") \
@ -785,11 +717,10 @@ extern "C" {
unsigned char method; /* requests only */ unsigned char method; /* requests only */
unsigned char http_errno : 7; unsigned char http_errno : 7;
/* 1 = Upgrade header was present and the parser has exited because of that. // 1 = Upgrade header was present and the parser has exited because of that.
* 0 = No upgrade header present. // 0 = No upgrade header present.
* Should be checked when http_parser_execute() returns in addition to // Should be checked when http_parser_execute() returns in addition to
* error checking. // error checking.
*/
unsigned char upgrade : 1; unsigned char upgrade : 1;
/** PUBLIC **/ /** PUBLIC **/
@ -821,13 +752,11 @@ extern "C" {
}; };
/* Result structure for http_parser_parse_url(). // Result structure for http_parser_parse_url().
* // Callers should index into field_data[] with UF_* values iff field_set
* Callers should index into field_data[] with UF_* values iff field_set // has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
* has the relevant (1 << UF_*) bit set. As a courtesy to clients (and // because we probably have padding left over), we convert any port to
* because we probably have padding left over), we convert any port to // a uint16_t.
* a uint16_t.
*/
struct http_parser_url { struct http_parser_url {
uint16_t field_set; /* Bitmask of (1 << UF_*) values */ uint16_t field_set; /* Bitmask of (1 << UF_*) values */
uint16_t port; /* Converted UF_PORT string */ uint16_t port; /* Converted UF_PORT string */
@ -848,12 +777,11 @@ extern "C" {
size_t len); size_t len);
/* If http_should_keep_alive() in the on_headers_complete or // If http_should_keep_alive() in the on_headers_complete or
* on_message_complete callback returns 0, then this should be // on_message_complete callback returns 0, then this should be
* the last message on the connection. // The last message on the connection.
* If you are the server, respond with the "Connection: close" header. // If you are the server, respond with the "Connection: close" header.
* If you are the client, close the connection. // If you are the client, close the connection.
*/
int http_should_keep_alive(const http_parser *parser); int http_should_keep_alive(const http_parser *parser);
/* Returns a string version of the HTTP method. */ /* Returns a string version of the HTTP method. */
@ -881,9 +809,7 @@ extern "C" {
#endif #endif
#endif #endif
/** // Used to resolve the http uri.
* used to resolve the http uri.
*/
class SrsHttpUri class SrsHttpUri
{ {
private: private:
@ -897,9 +823,7 @@ public:
SrsHttpUri(); SrsHttpUri();
virtual ~SrsHttpUri(); virtual ~SrsHttpUri();
public: public:
/** // Initialize the http uri.
* initialize the http uri.
*/
virtual srs_error_t initialize(std::string _url); virtual srs_error_t initialize(std::string _url);
public: public:
virtual std::string get_url(); virtual std::string get_url();
@ -909,10 +833,8 @@ public:
virtual std::string get_path(); virtual std::string get_path();
virtual std::string get_query(); virtual std::string get_query();
private: private:
/** // Get the parsed url field.
* get the parsed url field. // @return return empty string if not set.
* @return return empty string if not set.
*/
virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field); virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field);
}; };

View file

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

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@ class SrsSimpleStream;
class SrsAudioFrame; class SrsAudioFrame;
class ISrsProtocolReadWriter; class ISrsProtocolReadWriter;
// rtsp specification // From rtsp specification
// CR = <US-ASCII CR, carriage return (13)> // CR = <US-ASCII CR, carriage return (13)>
#define SRS_RTSP_CR SRS_CONSTS_CR // 0x0D #define SRS_RTSP_CR SRS_CONSTS_CR // 0x0D
// LF = <US-ASCII LF, linefeed (10)> // LF = <US-ASCII LF, linefeed (10)>
@ -78,38 +78,28 @@ class ISrsProtocolReadWriter;
// RTSP-Version // RTSP-Version
#define SRS_RTSP_VERSION "RTSP/1.0" #define SRS_RTSP_VERSION "RTSP/1.0"
/** // The rtsp sdp parse state.
* the rtsp sdp parse state.
*/
enum SrsRtspSdpState enum SrsRtspSdpState
{ {
/** // Other sdp properties.
* other sdp properties.
*/
SrsRtspSdpStateOthers, SrsRtspSdpStateOthers,
/** // Parse sdp audio state.
* parse sdp audio state.
*/
SrsRtspSdpStateAudio, SrsRtspSdpStateAudio,
/** // Parse sdp video state.
* parse sdp video state.
*/
SrsRtspSdpStateVideo, SrsRtspSdpStateVideo,
}; };
/** // 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57
* 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57 // The method token indicates the method to be performed on the resource
* The method token indicates the method to be performed on the resource // identified by the Request-URI. The method is case-sensitive. New
* identified by the Request-URI. The method is case-sensitive. New // methods may be defined in the future. Method names may not start with
* methods may be defined in the future. Method names may not start with // a $ character (decimal 24) and must be a token. Methods are
* a $ character (decimal 24) and must be a token. Methods are // summarized in Table 2.
* summarized in Table 2. // Notes on Table 2: PAUSE is recommended, but not required in that a
* Notes on Table 2: PAUSE is recommended, but not required in that a // fully functional server can be built that does not support this
* fully functional server can be built that does not support this // method, for example, for live feeds. If a server does not support a
* method, for example, for live feeds. If a server does not support a // particular method, it MUST return "501 Not Implemented" and a client
* particular method, it MUST return "501 Not Implemented" and a client // SHOULD not try this method again for this server.
* SHOULD not try this method again for this server.
*/
enum SrsRtspMethod enum SrsRtspMethod
{ {
SrsRtspMethodDescribe = 0x0001, SrsRtspMethodDescribe = 0x0001,
@ -125,237 +115,187 @@ enum SrsRtspMethod
SrsRtspMethodTeardown = 0x0400, SrsRtspMethodTeardown = 0x0400,
}; };
/** // The state of rtsp token.
* the state of rtsp token.
*/
enum SrsRtspTokenState enum SrsRtspTokenState
{ {
/** // Parse token failed, default state.
* parse token failed, default state.
*/
SrsRtspTokenStateError = 100, SrsRtspTokenStateError = 100,
/** // When SP follow the token.
* when SP follow the token.
*/
SrsRtspTokenStateNormal = 101, SrsRtspTokenStateNormal = 101,
/** // When CRLF follow the token.
* when CRLF follow the token.
*/
SrsRtspTokenStateEOF = 102, SrsRtspTokenStateEOF = 102,
}; };
/** // The rtp packet.
* the rtp packet. // 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12
* 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12
*/
class SrsRtpPacket class SrsRtpPacket
{ {
public: public:
/** // The version (V): 2 bits
* version (V): 2 bits // This field identifies the version of RTP. The version defined by this specification is two (2).
* This field identifies the version of RTP. The version defined by this specification is two (2). // (The value 1 is used by the first draft version of RTP and the value 0 is used by the protocol
* (The value 1 is used by the first draft version of RTP and the value 0 is used by the protocol // initially implemented in the \vat" audio tool.)
* initially implemented in the \vat" audio tool.)
*/
int8_t version; //2bits int8_t version; //2bits
/** // The padding (P): 1 bit
* padding (P): 1 bit // If the padding bit is set, the packet contains one or more additional padding octets at the
* If the padding bit is set, the packet contains one or more additional padding octets at the // end which are not part of the payload. The last octet of the padding contains a count of
* end which are not part of the payload. The last octet of the padding contains a count of // how many padding octets should be ignored, including itself. Padding may be needed by
* how many padding octets should be ignored, including itself. Padding may be needed by // some encryption algorithms with fixed block sizes or for carrying several RTP packets in a
* some encryption algorithms with fixed block sizes or for carrying several RTP packets in a // lower-layer protocol data unit.
* lower-layer protocol data unit.
*/
int8_t padding; //1bit int8_t padding; //1bit
/** // The extension (X): 1 bit
* extension (X): 1 bit // If the extension bit is set, the fixed header must be followed by exactly one header extension,
* If the extension bit is set, the fixed header must be followed by exactly one header extension, // with a format defined in Section 5.3.1.
* with a format defined in Section 5.3.1.
*/
int8_t extension; //1bit int8_t extension; //1bit
/** // The CSRC count (CC): 4 bits
* CSRC count (CC): 4 bits // The CSRC count contains the number of CSRC identifiers that follow the fixed header.
* The CSRC count contains the number of CSRC identifiers that follow the fixed header.
*/
int8_t csrc_count; //4bits int8_t csrc_count; //4bits
/** // The marker (M): 1 bit
* marker (M): 1 bit // The interpretation of the marker is defined by a profile. It is intended to allow significant
* The interpretation of the marker is defined by a profile. It is intended to allow significant // events such as frame boundaries to be marked in the packet stream. A profile may define
* events such as frame boundaries to be marked in the packet stream. A profile may define // additional marker bits or specify that there is no marker bit by changing the number of bits
* additional marker bits or specify that there is no marker bit by changing the number of bits // in the payload type field (see Section 5.3).
* in the payload type field (see Section 5.3).
*/
int8_t marker; //1bit int8_t marker; //1bit
/** // The payload type (PT): 7 bits
* payload type (PT): 7 bits // This field identifies the format of the RTP payload and determines its interpretation by the
* This field identifies the format of the RTP payload and determines its interpretation by the // application. A profile may specify a default static mapping of payload type codes to payload
* application. A profile may specify a default static mapping of payload type codes to payload // formats. Additional payload type codes may be defined dynamically through non-RTP means
* formats. Additional payload type codes may be defined dynamically through non-RTP means // (see Section 3). A set of default mappings for audio and video is specified in the companion
* (see Section 3). A set of default mappings for audio and video is specified in the companion // RFC 3551 [1]. An RTP source may change the payload type during a session, but this field
* RFC 3551 [1]. An RTP source may change the payload type during a session, but this field // should not be used for multiplexing separate media streams (see Section 5.2).
* should not be used for multiplexing separate media streams (see Section 5.2). // A receiver must ignore packets with payload types that it does not understand.
* A receiver must ignore packets with payload types that it does not understand.
*/
int8_t payload_type; //7bits int8_t payload_type; //7bits
/** // The sequence number: 16 bits
* sequence number: 16 bits // The sequence number increments by one for each RTP data packet sent, and may be used
* The sequence number increments by one for each RTP data packet sent, and may be used // by the receiver to detect packet loss and to restore packet sequence. The initial value of the
* by the receiver to detect packet loss and to restore packet sequence. The initial value of the // sequence number should be random (unpredictable) to make known-plaintext attacks on
* sequence number should be random (unpredictable) to make known-plaintext attacks on // encryption more dicult, even if the source itself does not encrypt according to the method
* encryption more dicult, even if the source itself does not encrypt according to the method // in Section 9.1, because the packets may flow through a translator that does. Techniques for
* in Section 9.1, because the packets may flow through a translator that does. Techniques for // choosing unpredictable numbers are discussed in [17].
* choosing unpredictable numbers are discussed in [17].
*/
uint16_t sequence_number; //16bits uint16_t sequence_number; //16bits
/** // The timestamp: 32 bits
* timestamp: 32 bits // The timestamp reflects the sampling instant of the first octet in the RTP data packet. The
* The timestamp reflects the sampling instant of the first octet in the RTP data packet. The // sampling instant must be derived from a clock that increments monotonically and linearly
* sampling instant must be derived from a clock that increments monotonically and linearly // in time to allow synchronization and jitter calculations (see Section 6.4.1). The resolution
* in time to allow synchronization and jitter calculations (see Section 6.4.1). The resolution // of the clock must be sucient for the desired synchronization accuracy and for measuring
* of the clock must be sucient for the desired synchronization accuracy and for measuring // packet arrival jitter (one tick per video frame is typically not sucient). The clock frequency
* packet arrival jitter (one tick per video frame is typically not sucient). The clock frequency // is dependent on the format of data carried as payload and is specified statically in the profile
* is dependent on the format of data carried as payload and is specified statically in the profile // or payload format specification that defines the format, or may be specified dynamically for
* or payload format specification that defines the format, or may be specified dynamically for // payload formats defined through non-RTP means. If RTP packets are generated periodically,
* payload formats defined through non-RTP means. If RTP packets are generated periodically, // The nominal sampling instant as determined from the sampling clock is to be used, not a
* the nominal sampling instant as determined from the sampling clock is to be used, not a // reading of the system clock. As an example, for fixed-rate audio the timestamp clock would
* reading of the system clock. As an example, for fixed-rate audio the timestamp clock would // likely increment by one for each sampling period. If an audio application reads blocks covering
* likely increment by one for each sampling period. If an audio application reads blocks covering // 160 sampling periods from the input device, the timestamp would be increased by 160 for
* 160 sampling periods from the input device, the timestamp would be increased by 160 for // each such block, regardless of whether the block is transmitted in a packet or dropped as
* each such block, regardless of whether the block is transmitted in a packet or dropped as // silent.
* silent. //
* // The initial value of the timestamp should be random, as for the sequence number. Several
* The initial value of the timestamp should be random, as for the sequence number. Several // consecutive RTP packets will have equal timestamps if they are (logically) generated at once,
* consecutive RTP packets will have equal timestamps if they are (logically) generated at once, // e.g., belong to the same video frame. Consecutive RTP packets may contain timestamps that
* e.g., belong to the same video frame. Consecutive RTP packets may contain timestamps that // are not monotonic if the data is not transmitted in the order it was sampled, as in the case
* are not monotonic if the data is not transmitted in the order it was sampled, as in the case // of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted
* of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted // will still be monotonic.)
* will still be monotonic.) //
* // RTP timestamps from different media streams may advance at different rates and usually
* RTP timestamps from different media streams may advance at different rates and usually // have independent, random offsets. Therefore, although these timestamps are sucient to
* have independent, random offsets. Therefore, although these timestamps are sucient to // reconstruct the timing of a single stream, directly comparing RTP timestamps from different
* reconstruct the timing of a single stream, directly comparing RTP timestamps from different // media is not effective for synchronization. Instead, for each medium the RTP timestamp
* media is not effective for synchronization. Instead, for each medium the RTP timestamp // is related to the sampling instant by pairing it with a timestamp from a reference clock
* is related to the sampling instant by pairing it with a timestamp from a reference clock // (wallclock) that represents the time when the data corresponding to the RTP timestamp was
* (wallclock) that represents the time when the data corresponding to the RTP timestamp was // sampled. The reference clock is shared by all media to be synchronized. The timestamp
* sampled. The reference clock is shared by all media to be synchronized. The timestamp // pairs are not transmitted in every data packet, but at a lower rate in RTCP SR packets as
* pairs are not transmitted in every data packet, but at a lower rate in RTCP SR packets as // described in Section 6.4.
* described in Section 6.4. //
* // The sampling instant is chosen as the point of reference for the RTP timestamp because it is
* The sampling instant is chosen as the point of reference for the RTP timestamp because it is // known to the transmitting endpoint and has a common definition for all media, independent
* known to the transmitting endpoint and has a common definition for all media, independent // of encoding delays or other processing. The purpose is to allow synchronized presentation of
* of encoding delays or other processing. The purpose is to allow synchronized presentation of // all media sampled at the same time.
* all media sampled at the same time. //
* // Applications transmitting stored data rather than data sampled in real time typically use a
* Applications transmitting stored data rather than data sampled in real time typically use a // virtual presentation timeline derived from wallclock time to determine when the next frame
* virtual presentation timeline derived from wallclock time to determine when the next frame // or other unit of each medium in the stored data should be presented. In this case, the RTP
* or other unit of each medium in the stored data should be presented. In this case, the RTP // timestamp would reflect the presentation time for each unit. That is, the RTP timestamp for
* timestamp would reflect the presentation time for each unit. That is, the RTP timestamp for // each unit would be related to the wallclock time at which the unit becomes current on the
* each unit would be related to the wallclock time at which the unit becomes current on the // virtual presentation timeline. Actual presentation occurs some time later as determined by
* virtual presentation timeline. Actual presentation occurs some time later as determined by // The receiver.
* the receiver. //
* // An example describing live audio narration of prerecorded video illustrates the significance
* An example describing live audio narration of prerecorded video illustrates the significance // of choosing the sampling instant as the reference point. In this scenario, the video would
* of choosing the sampling instant as the reference point. In this scenario, the video would // be presented locally for the narrator to view and would be simultaneously transmitted using
* be presented locally for the narrator to view and would be simultaneously transmitted using // RTP. The sampling instant" of a video frame transmitted in RTP would be established by
* RTP. The sampling instant" of a video frame transmitted in RTP would be established by // referencing its timestamp to the wallclock time when that video frame was presented to the
* referencing its timestamp to the wallclock time when that video frame was presented to the // narrator. The sampling instant for the audio RTP packets containing the narrator's speech
* narrator. The sampling instant for the audio RTP packets containing the narrator's speech // would be established by referencing the same wallclock time when the audio was sampled.
* would be established by referencing the same wallclock time when the audio was sampled. // The audio and video may even be transmitted by different hosts if the reference clocks on
* The audio and video may even be transmitted by different hosts if the reference clocks on // The two hosts are synchronized by some means such as NTP. A receiver can then synchronize
* the two hosts are synchronized by some means such as NTP. A receiver can then synchronize // presentation of the audio and video packets by relating their RTP timestamps using the
* presentation of the audio and video packets by relating their RTP timestamps using the // timestamp pairs in RTCP SR packets.
* timestamp pairs in RTCP SR packets.
*/
uint32_t timestamp; //32bits uint32_t timestamp; //32bits
/** // The SSRC: 32 bits
* SSRC: 32 bits // The SSRC field identifies the synchronization source. This identifier should be chosen
* The SSRC field identifies the synchronization source. This identifier should be chosen // randomly, with the intent that no two synchronization sources within the same RTP session
* randomly, with the intent that no two synchronization sources within the same RTP session // will have the same SSRC identifier. An example algorithm for generating a random identifier
* will have the same SSRC identifier. An example algorithm for generating a random identifier // is presented in Appendix A.6. Although the probability of multiple sources choosing the same
* is presented in Appendix A.6. Although the probability of multiple sources choosing the same // identifier is low, all RTP implementations must be prepared to detect and resolve collisions.
* identifier is low, all RTP implementations must be prepared to detect and resolve collisions. // Section 8 describes the probability of collision along with a mechanism for resolving collisions
* Section 8 describes the probability of collision along with a mechanism for resolving collisions // and detecting RTP-level forwarding loops based on the uniqueness of the SSRC identifier. If
* and detecting RTP-level forwarding loops based on the uniqueness of the SSRC identifier. If // a source changes its source transport address, it must also choose a new SSRC identifier to
* a source changes its source transport address, it must also choose a new SSRC identifier to // avoid being interpreted as a looped source (see Section 8.2).
* avoid being interpreted as a looped source (see Section 8.2).
*/
uint32_t ssrc; //32bits uint32_t ssrc; //32bits
// the payload. // The payload.
SrsSimpleStream* payload; SrsSimpleStream* payload;
// whether transport in chunked payload. // Whether transport in chunked payload.
bool chunked; bool chunked;
// whether message is completed. // Whether message is completed.
// normal message always completed. // normal message always completed.
// while chunked completed when the last chunk arriaved. // while chunked completed when the last chunk arriaved.
bool completed; bool completed;
/** // The audio samples, one rtp packets may contains multiple audio samples.
* the audio samples, one rtp packets may contains multiple audio samples.
*/
SrsAudioFrame* audio; SrsAudioFrame* audio;
public: public:
SrsRtpPacket(); SrsRtpPacket();
virtual ~SrsRtpPacket(); virtual ~SrsRtpPacket();
public: public:
/** // copy the header from src.
* copy the header from src.
*/
virtual void copy(SrsRtpPacket* src); virtual void copy(SrsRtpPacket* src);
/** // reap the src to this packet, reap the payload.
* reap the src to this packet, reap the payload.
*/
virtual void reap(SrsRtpPacket* src); virtual void reap(SrsRtpPacket* src);
/** // decode rtp packet from stream.
* decode rtp packet from stream.
*/
virtual srs_error_t decode(SrsBuffer* stream); virtual srs_error_t decode(SrsBuffer* stream);
private: private:
virtual srs_error_t decode_97(SrsBuffer* stream); virtual srs_error_t decode_97(SrsBuffer* stream);
virtual srs_error_t decode_96(SrsBuffer* stream); virtual srs_error_t decode_96(SrsBuffer* stream);
}; };
/** // The sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159
* the sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159 // Appendix C: Use of SDP for RTSP Session Descriptions
* Appendix C: Use of SDP for RTSP Session Descriptions // The Session Description Protocol (SDP, RFC 2327 [6]) may be used to
* The Session Description Protocol (SDP, RFC 2327 [6]) may be used to // describe streams or presentations in RTSP.
* describe streams or presentations in RTSP.
*/
class SrsRtspSdp class SrsRtspSdp
{ {
private: private:
SrsRtspSdpState state; SrsRtspSdpState state;
public: public:
/** // The version of sdp.
* the version of sdp.
*/
std::string version; std::string version;
/** // The owner/creator of sdp.
* the owner/creator of sdp.
*/
std::string owner_username; std::string owner_username;
std::string owner_session_id; std::string owner_session_id;
std::string owner_session_version; std::string owner_session_version;
std::string owner_network_type; std::string owner_network_type;
std::string owner_address_type; std::string owner_address_type;
std::string owner_address; std::string owner_address;
/** // The session name of sdp.
* the session name of sdp.
*/
std::string session_name; std::string session_name;
/** // The connection info of sdp.
* the connection info of sdp.
*/
std::string connection_network_type; std::string connection_network_type;
std::string connection_address_type; std::string connection_address_type;
std::string connection_address; std::string connection_address;
/** // The tool attribute of sdp.
* the tool attribute of sdp.
*/
std::string tool; std::string tool;
/** // The video attribute of sdp.
* the video attribute of sdp.
*/
std::string video_port; std::string video_port;
std::string video_protocol; std::string video_protocol;
std::string video_transport_format; std::string video_transport_format;
@ -363,13 +303,11 @@ public:
std::string video_codec; std::string video_codec;
std::string video_sample_rate; std::string video_sample_rate;
std::string video_stream_id; std::string video_stream_id;
// fmtp // The fmtp
std::string video_packetization_mode; std::string video_packetization_mode;
std::string video_sps; // sequence header: sps. std::string video_sps; // sequence header: sps.
std::string video_pps; // sequence header: pps. std::string video_pps; // sequence header: pps.
/** // The audio attribute of sdp.
* the audio attribute of sdp.
*/
std::string audio_port; std::string audio_port;
std::string audio_protocol; std::string audio_protocol;
std::string audio_transport_format; std::string audio_transport_format;
@ -378,7 +316,7 @@ public:
std::string audio_sample_rate; std::string audio_sample_rate;
std::string audio_channel; std::string audio_channel;
std::string audio_stream_id; std::string audio_stream_id;
// fmtp // The fmtp
std::string audio_profile_level_id; std::string audio_profile_level_id;
std::string audio_mode; std::string audio_mode;
std::string audio_size_length; std::string audio_size_length;
@ -389,34 +327,24 @@ public:
SrsRtspSdp(); SrsRtspSdp();
virtual ~SrsRtspSdp(); virtual ~SrsRtspSdp();
public: public:
/** // Parse a line of token for sdp.
* parse a line of token for sdp.
*/
virtual srs_error_t parse(std::string token); virtual srs_error_t parse(std::string token);
private: private:
/** // generally, the fmtp is the sequence header for video or audio.
* generally, the fmtp is the sequence header for video or audio.
*/
virtual srs_error_t parse_fmtp_attribute(std::string attr); virtual srs_error_t parse_fmtp_attribute(std::string attr);
/** // generally, the control is the stream info for video or audio.
* generally, the control is the stream info for video or audio.
*/
virtual srs_error_t parse_control_attribute(std::string attr); virtual srs_error_t parse_control_attribute(std::string attr);
/** // decode the string by base64.
* decode the string by base64.
*/
virtual std::string base64_decode(std::string value); virtual std::string base64_decode(std::string value);
}; };
/** // The rtsp transport.
* the rtsp transport. // 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115
* 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115 // This request header indicates which transport protocol is to be used
* This request header indicates which transport protocol is to be used // and configures its parameters such as destination address,
* and configures its parameters such as destination address, // compression, multicast time-to-live and destination port for a single
* compression, multicast time-to-live and destination port for a single // stream. It sets those values not already determined by a presentation
* stream. It sets those values not already determined by a presentation // description.
* description.
*/
class SrsRtspTransport class SrsRtspTransport
{ {
public: public:
@ -431,7 +359,7 @@ public:
// Clients that are capable of handling both unicast and // Clients that are capable of handling both unicast and
// multicast transmission MUST indicate such capability by // multicast transmission MUST indicate such capability by
// including two full transport-specs with separate parameters // including two full transport-specs with separate parameters
// for each. // For each.
std::string cast_type; std::string cast_type;
// The mode parameter indicates the methods to be supported for // The mode parameter indicates the methods to be supported for
// this session. Valid values are PLAY and RECORD. If not // this session. Valid values are PLAY and RECORD. If not
@ -449,79 +377,59 @@ public:
SrsRtspTransport(); SrsRtspTransport();
virtual ~SrsRtspTransport(); virtual ~SrsRtspTransport();
public: public:
/** // Parse a line of token for transport.
* parse a line of token for transport.
*/
virtual srs_error_t parse(std::string attr); virtual srs_error_t parse(std::string attr);
}; };
/** // The rtsp request message.
* the rtsp request message. // 6 Request, @see rfc2326-1998-rtsp.pdf, page 39
* 6 Request, @see rfc2326-1998-rtsp.pdf, page 39 // A request message from a client to a server or vice versa includes,
* A request message from a client to a server or vice versa includes, // within the first line of that message, the method to be applied to
* within the first line of that message, the method to be applied to // The resource, the identifier of the resource, and the protocol
* the resource, the identifier of the resource, and the protocol // version in use.
* version in use. // Request = Request-Line ; Section 6.1
* Request = Request-Line ; Section 6.1 // // ( general-header ; Section 5
* *( general-header ; Section 5 // | request-header ; Section 6.2
* | request-header ; Section 6.2 // | entity-header ) ; Section 8.1
* | entity-header ) ; Section 8.1 // CRLF
* CRLF // [ message-body ] ; Section 4.3
* [ message-body ] ; Section 4.3
*/
class SrsRtspRequest class SrsRtspRequest
{ {
public: public:
/** // 6.1 Request Line
* 6.1 Request Line // Request-Line = Method SP Request-URI SP RTSP-Version CRLF
* Request-Line = Method SP Request-URI SP RTSP-Version CRLF
*/
std::string method; std::string method;
std::string uri; std::string uri;
std::string version; std::string version;
/** // 12.17 CSeq
* 12.17 CSeq // The CSeq field specifies the sequence number for an RTSP requestresponse
* The CSeq field specifies the sequence number for an RTSP requestresponse // pair. This field MUST be present in all requests and
* pair. This field MUST be present in all requests and // responses. For every RTSP request containing the given sequence
* responses. For every RTSP request containing the given sequence // number, there will be a corresponding response having the same
* number, there will be a corresponding response having the same // number. Any retransmitted request must contain the same sequence
* number. Any retransmitted request must contain the same sequence // number as the original (i.e. the sequence number is not incremented
* number as the original (i.e. the sequence number is not incremented // For retransmissions of the same request).
* for retransmissions of the same request).
*/
long seq; long seq;
/** // 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99
* 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99 // See [H14.18]. Note that the content types suitable for RTSP are
* See [H14.18]. Note that the content types suitable for RTSP are // likely to be restricted in practice to presentation descriptions and
* likely to be restricted in practice to presentation descriptions and // parameter-value types.
* parameter-value types.
*/
std::string content_type; std::string content_type;
/** // 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99
* 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99 // This field contains the length of the content of the method (i.e.
* This field contains the length of the content of the method (i.e. // after the double CRLF following the last header). Unlike HTTP, it
* after the double CRLF following the last header). Unlike HTTP, it // MUST be included in all messages that carry content beyond the header
* MUST be included in all messages that carry content beyond the header // portion of the message. If it is missing, a default value of zero is
* portion of the message. If it is missing, a default value of zero is // assumed. It is interpreted according to [H14.14].
* assumed. It is interpreted according to [H14.14].
*/
long content_length; long content_length;
/** // The session id.
* the session id.
*/
std::string session; std::string session;
/** // The sdp in announce, NULL for no sdp.
* the sdp in announce, NULL for no sdp.
*/
SrsRtspSdp* sdp; SrsRtspSdp* sdp;
/** // The transport in setup, NULL for no transport.
* the transport in setup, NULL for no transport.
*/
SrsRtspTransport* transport; SrsRtspTransport* transport;
/** // For setup message, parse the stream id from uri.
* for setup message, parse the stream id from uri.
*/
int stream_id; int stream_id;
public: public:
SrsRtspRequest(); SrsRtspRequest();
@ -533,79 +441,63 @@ public:
virtual bool is_record(); virtual bool is_record();
}; };
/** // The rtsp response message.
* the rtsp response message. // 7 Response, @see rfc2326-1998-rtsp.pdf, page 43
* 7 Response, @see rfc2326-1998-rtsp.pdf, page 43 // [H6] applies except that HTTP-Version is replaced by RTSP-Version.
* [H6] applies except that HTTP-Version is replaced by RTSP-Version. // Also, RTSP defines additional status codes and does not define some
* Also, RTSP defines additional status codes and does not define some // HTTP codes. The valid response codes and the methods they can be used
* HTTP codes. The valid response codes and the methods they can be used // with are defined in Table 1.
* with are defined in Table 1. // After receiving and interpreting a request message, the recipient
* After receiving and interpreting a request message, the recipient // responds with an RTSP response message.
* responds with an RTSP response message. // Response = Status-Line ; Section 7.1
* Response = Status-Line ; Section 7.1 // // ( general-header ; Section 5
* *( general-header ; Section 5 // | response-header ; Section 7.1.2
* | response-header ; Section 7.1.2 // | entity-header ) ; Section 8.1
* | entity-header ) ; Section 8.1 // CRLF
* CRLF // [ message-body ] ; Section 4.3
* [ message-body ] ; Section 4.3
*/
class SrsRtspResponse class SrsRtspResponse
{ {
public: public:
/** // 7.1 Status-Line
* 7.1 Status-Line // The first line of a Response message is the Status-Line, consisting
* The first line of a Response message is the Status-Line, consisting // of the protocol version followed by a numeric status code, and the
* of the protocol version followed by a numeric status code, and the // textual phrase associated with the status code, with each element
* textual phrase associated with the status code, with each element // separated by SP characters. No CR or LF is allowed except in the
* separated by SP characters. No CR or LF is allowed except in the // final CRLF sequence.
* final CRLF sequence. // Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
* Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
*/
// @see about the version of rtsp, see SRS_RTSP_VERSION // @see about the version of rtsp, see SRS_RTSP_VERSION
// @see about the status of rtsp, see SRS_CONSTS_RTSP_OK // @see about the status of rtsp, see SRS_CONSTS_RTSP_OK
int status; int status;
/** // 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99
* 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99 // The CSeq field specifies the sequence number for an RTSP requestresponse
* The CSeq field specifies the sequence number for an RTSP requestresponse // pair. This field MUST be present in all requests and
* pair. This field MUST be present in all requests and // responses. For every RTSP request containing the given sequence
* responses. For every RTSP request containing the given sequence // number, there will be a corresponding response having the same
* number, there will be a corresponding response having the same // number. Any retransmitted request must contain the same sequence
* number. Any retransmitted request must contain the same sequence // number as the original (i.e. the sequence number is not incremented
* number as the original (i.e. the sequence number is not incremented // For retransmissions of the same request).
* for retransmissions of the same request).
*/
long seq; long seq;
/** // The session id.
* the session id.
*/
std::string session; std::string session;
public: public:
SrsRtspResponse(int cseq); SrsRtspResponse(int cseq);
virtual ~SrsRtspResponse(); virtual ~SrsRtspResponse();
public: public:
/** // Encode message to string.
* encode message to string.
*/
virtual srs_error_t encode(std::stringstream& ss); virtual srs_error_t encode(std::stringstream& ss);
protected: protected:
/** // Sub classes override this to encode the headers.
* sub classes override this to encode the headers.
*/
virtual srs_error_t encode_header(std::stringstream& ss); virtual srs_error_t encode_header(std::stringstream& ss);
}; };
/** // 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59
* 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59 // The behavior is equivalent to that described in [H9.2]. An OPTIONS
* The behavior is equivalent to that described in [H9.2]. An OPTIONS // request may be issued at any time, e.g., if the client is about to
* request may be issued at any time, e.g., if the client is about to // try a nonstandard request. It does not influence server state.
* try a nonstandard request. It does not influence server state.
*/
class SrsRtspOptionsResponse : public SrsRtspResponse class SrsRtspOptionsResponse : public SrsRtspResponse
{ {
public: public:
/** // Join of SrsRtspMethod
* join of SrsRtspMethod
*/
SrsRtspMethod methods; SrsRtspMethod methods;
public: public:
SrsRtspOptionsResponse(int cseq); SrsRtspOptionsResponse(int cseq);
@ -614,28 +506,26 @@ protected:
virtual srs_error_t encode_header(std::stringstream& ss); virtual srs_error_t encode_header(std::stringstream& ss);
}; };
/** // 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65
* 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65 // The SETUP request for a URI specifies the transport mechanism to be
* The SETUP request for a URI specifies the transport mechanism to be // used for the streamed media. A client can issue a SETUP request for a
* used for the streamed media. A client can issue a SETUP request for a // stream that is already playing to change transport parameters, which
* stream that is already playing to change transport parameters, which // a server MAY allow. If it does not allow this, it MUST respond with
* a server MAY allow. If it does not allow this, it MUST respond with // error "455 Method Not Valid In This State". For the benefit of any
* error "455 Method Not Valid In This State". For the benefit of any // intervening firewalls, a client must indicate the transport
* intervening firewalls, a client must indicate the transport // parameters even if it has no influence over these parameters, for
* parameters even if it has no influence over these parameters, for // example, where the server advertises a fixed multicast address.
* example, where the server advertises a fixed multicast address.
*/
class SrsRtspSetupResponse : public SrsRtspResponse class SrsRtspSetupResponse : public SrsRtspResponse
{ {
public: public:
// the client specified port. // The client specified port.
int client_port_min; int client_port_min;
int client_port_max; int client_port_max;
// client will use the port in: // The client will use the port in:
// [local_port_min, local_port_max) // [local_port_min, local_port_max)
int local_port_min; int local_port_min;
int local_port_max; int local_port_max;
// session. // The session.
std::string session; std::string session;
public: public:
SrsRtspSetupResponse(int cseq); SrsRtspSetupResponse(int cseq);
@ -644,65 +534,45 @@ protected:
virtual srs_error_t encode_header(std::stringstream& ss); virtual srs_error_t encode_header(std::stringstream& ss);
}; };
/** // The rtsp protocol stack to parse the rtsp packets.
* the rtsp protocol stack to parse the rtsp packets.
*/
class SrsRtspStack class SrsRtspStack
{ {
private: private:
/** // The cached bytes buffer.
* cached bytes buffer.
*/
SrsSimpleStream* buf; SrsSimpleStream* buf;
/** // The underlayer socket object, send/recv bytes.
* underlayer socket object, send/recv bytes.
*/
ISrsProtocolReadWriter* skt; ISrsProtocolReadWriter* skt;
public: public:
SrsRtspStack(ISrsProtocolReadWriter* s); SrsRtspStack(ISrsProtocolReadWriter* s);
virtual ~SrsRtspStack(); virtual ~SrsRtspStack();
public: public:
/** // Recv rtsp message from underlayer io.
* recv rtsp message from underlayer io. // @param preq the output rtsp request message, which user must free it.
* @param preq the output rtsp request message, which user must free it. // @return an int error code.
* @return an int error code. // ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
* ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
*/
virtual srs_error_t recv_message(SrsRtspRequest** preq); virtual srs_error_t recv_message(SrsRtspRequest** preq);
/** // Send rtsp message over underlayer io.
* send rtsp message over underlayer io. // @param res the rtsp response message, which user should never free it.
* @param res the rtsp response message, which user should never free it. // @return an int error code.
* @return an int error code.
*/
virtual srs_error_t send_message(SrsRtspResponse* res); virtual srs_error_t send_message(SrsRtspResponse* res);
private: private:
/** // Recv the rtsp message.
* recv the rtsp message.
*/
virtual srs_error_t do_recv_message(SrsRtspRequest* req); virtual srs_error_t do_recv_message(SrsRtspRequest* req);
/** // Read a normal token from io, error when token state is not normal.
* read a normal token from io, error when token state is not normal.
*/
virtual srs_error_t recv_token_normal(std::string& token); virtual srs_error_t recv_token_normal(std::string& token);
/** // Read a normal token from io, error when token state is not eof.
* read a normal token from io, error when token state is not eof.
*/
virtual srs_error_t recv_token_eof(std::string& token); virtual srs_error_t recv_token_eof(std::string& token);
/** // Read the token util got eof, for example, to read the response status Reason-Phrase
* read the token util got eof, for example, to read the response status Reason-Phrase // @param pconsumed, output the token parsed length. NULL to ignore.
* @param pconsumed, output the token parsed length. NULL to ignore.
*/
virtual srs_error_t recv_token_util_eof(std::string& token, int* pconsumed = NULL); virtual srs_error_t recv_token_util_eof(std::string& token, int* pconsumed = NULL);
/** // Read a token from io, split by SP, endswith CRLF:
* read a token from io, split by SP, endswith CRLF: // token1 SP token2 SP ... tokenN CRLF
* token1 SP token2 SP ... tokenN CRLF // @param token, output the read token.
* @param token, output the read token. // @param state, output the token parse state.
* @param state, output the token parse state. // @param normal_ch, the char to indicates the normal token.
* @param normal_ch, the char to indicates the normal token. // the SP use to indicates the normal token, @see SRS_RTSP_SP
* the SP use to indicates the normal token, @see SRS_RTSP_SP // the 0x00 use to ignore normal token flag. @see recv_token_util_eof
* the 0x00 use to ignore normal token flag. @see recv_token_util_eof // @param pconsumed, output the token parsed length. NULL to ignore.
* @param pconsumed, output the token parsed length. NULL to ignore.
*/
virtual srs_error_t recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch = SRS_RTSP_SP, int* pconsumed = NULL); virtual srs_error_t recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch = SRS_RTSP_SP, int* pconsumed = NULL);
}; };