winlin

refine protocol, add comments. add utest for protocol bytes and timeout.

@@ -61,48 +61,47 @@ public: @@ -61,48 +61,47 @@ public:
61 std::string pageUrl; 61 std::string pageUrl;
62 std::string swfUrl; 62 std::string swfUrl;
63 double objectEncoding; 63 double objectEncoding;
64 - 64 +// data discovery from request.
  65 +public:
  66 + // discovery from tcUrl and play/publish.
65 std::string schema; 67 std::string schema;
66 std::string vhost; 68 std::string vhost;
67 std::string host; 69 std::string host;
68 std::string port; 70 std::string port;
69 std::string app; 71 std::string app;
70 std::string stream; 72 std::string stream;
71 -  
72 // for play live stream, 73 // for play live stream,
73 // used to specified the stop when exceed the duration. 74 // used to specified the stop when exceed the duration.
74 // @see https://github.com/winlinvip/simple-rtmp-server/issues/45 75 // @see https://github.com/winlinvip/simple-rtmp-server/issues/45
75 // in ms. 76 // in ms.
76 double duration; 77 double duration;
77 -  
78 // the token in the connect request, 78 // the token in the connect request,
79 // used for edge traverse to origin authentication, 79 // used for edge traverse to origin authentication,
80 // @see https://github.com/winlinvip/simple-rtmp-server/issues/104 80 // @see https://github.com/winlinvip/simple-rtmp-server/issues/104
81 SrsAmf0Object* args; 81 SrsAmf0Object* args;
82 - 82 +public:
83 SrsRequest(); 83 SrsRequest();
84 virtual ~SrsRequest(); 84 virtual ~SrsRequest();
85 - 85 +public:
86 /** 86 /**
87 * deep copy the request, for source to use it to support reload, 87 * deep copy the request, for source to use it to support reload,
88 * for when initialize the source, the request is valid, 88 * for when initialize the source, the request is valid,
89 * when reload it, the request maybe invalid, so need to copy it. 89 * when reload it, the request maybe invalid, so need to copy it.
90 */ 90 */
91 virtual SrsRequest* copy(); 91 virtual SrsRequest* copy();
92 -  
93 /** 92 /**
94 * update the auth info of request, 93 * update the auth info of request,
95 * to keep the current request ptr is ok, 94 * to keep the current request ptr is ok,
96 * for many components use the ptr of request. 95 * for many components use the ptr of request.
97 */ 96 */
98 virtual void update_auth(SrsRequest* req); 97 virtual void update_auth(SrsRequest* req);
99 -  
100 /** 98 /**
101 * get the stream identify, vhost/app/stream. 99 * get the stream identify, vhost/app/stream.
102 */ 100 */
103 virtual std::string get_stream_url(); 101 virtual std::string get_stream_url();
104 -  
105 - // strip url, user must strip when update the url. 102 + /**
  103 + * strip url, user must strip when update the url.
  104 + */
106 virtual void strip(); 105 virtual void strip();
107 }; 106 };
108 107
@@ -112,8 +111,11 @@ public: @@ -112,8 +111,11 @@ public:
112 class SrsResponse 111 class SrsResponse
113 { 112 {
114 public: 113 public:
  114 + /**
  115 + * the stream id to response client createStream.
  116 + */
115 int stream_id; 117 int stream_id;
116 - 118 +public:
117 SrsResponse(); 119 SrsResponse();
118 virtual ~SrsResponse(); 120 virtual ~SrsResponse();
119 }; 121 };
@@ -29,6 +29,8 @@ using namespace std; @@ -29,6 +29,8 @@ using namespace std;
29 #include <srs_protocol_utility.hpp> 29 #include <srs_protocol_utility.hpp>
30 #include <srs_protocol_msg_array.hpp> 30 #include <srs_protocol_msg_array.hpp>
31 #include <srs_protocol_rtmp_stack.hpp> 31 #include <srs_protocol_rtmp_stack.hpp>
  32 +#include <srs_kernel_utility.hpp>
  33 +#include <srs_app_st.hpp>
32 34
33 MockEmptyIO::MockEmptyIO() 35 MockEmptyIO::MockEmptyIO()
34 { 36 {
@@ -91,6 +93,114 @@ int MockEmptyIO::read(void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/) @@ -91,6 +93,114 @@ int MockEmptyIO::read(void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/)
91 return ERROR_SUCCESS; 93 return ERROR_SUCCESS;
92 } 94 }
93 95
  96 +MockBufferIO::MockBufferIO()
  97 +{
  98 + recv_timeout = send_timeout = ST_UTIME_NO_TIMEOUT;
  99 + recv_bytes = send_bytes = 0;
  100 +}
  101 +
  102 +MockBufferIO::~MockBufferIO()
  103 +{
  104 +}
  105 +
  106 +bool MockBufferIO::is_never_timeout(int64_t timeout_us)
  107 +{
  108 + return (int64_t)ST_UTIME_NO_TIMEOUT == timeout_us;
  109 +}
  110 +
  111 +int MockBufferIO::read_fully(void* buf, size_t size, ssize_t* nread)
  112 +{
  113 + if (in_buffer.length() < (int)size) {
  114 + return ERROR_SOCKET_READ;
  115 + }
  116 + memcpy(buf, in_buffer.bytes(), size);
  117 +
  118 + recv_bytes += size;
  119 + if (nread) {
  120 + *nread = size;
  121 + }
  122 + in_buffer.erase(size);
  123 + return ERROR_SUCCESS;
  124 +}
  125 +
  126 +int MockBufferIO::write(void* buf, size_t size, ssize_t* nwrite)
  127 +{
  128 + send_bytes += size;
  129 + if (nwrite) {
  130 + *nwrite = size;
  131 + }
  132 + out_buffer.append((char*)buf, size);
  133 + return ERROR_SUCCESS;
  134 +}
  135 +
  136 +void MockBufferIO::set_recv_timeout(int64_t timeout_us)
  137 +{
  138 + recv_timeout = timeout_us;
  139 +}
  140 +
  141 +int64_t MockBufferIO::get_recv_timeout()
  142 +{
  143 + return recv_timeout;
  144 +}
  145 +
  146 +int64_t MockBufferIO::get_recv_bytes()
  147 +{
  148 + return recv_bytes;
  149 +}
  150 +
  151 +void MockBufferIO::set_send_timeout(int64_t timeout_us)
  152 +{
  153 + send_timeout = timeout_us;
  154 +}
  155 +
  156 +int64_t MockBufferIO::get_send_timeout()
  157 +{
  158 + return send_timeout;
  159 +}
  160 +
  161 +int64_t MockBufferIO::get_send_bytes()
  162 +{
  163 + return send_bytes;
  164 +}
  165 +
  166 +int MockBufferIO::writev(const iovec *iov, int iov_size, ssize_t* nwrite)
  167 +{
  168 + int ret = ERROR_SUCCESS;
  169 +
  170 + ssize_t total = 0;
  171 + for (int i = 0; i <iov_size; i++) {
  172 + const iovec& pi = iov[i];
  173 +
  174 + ssize_t writen = 0;
  175 + if ((ret = write(pi.iov_base, pi.iov_len, &writen)) != ERROR_SUCCESS) {
  176 + return ret;
  177 + }
  178 + total += writen;
  179 + }
  180 +
  181 + if (nwrite) {
  182 + *nwrite = total;
  183 + }
  184 + return ret;
  185 +}
  186 +
  187 +int MockBufferIO::read(void* buf, size_t size, ssize_t* nread)
  188 +{
  189 + if (in_buffer.length() <= 0) {
  190 + return ERROR_SOCKET_READ;
  191 + }
  192 +
  193 + size_t available = srs_min(in_buffer.length(), (int)size);
  194 + memcpy(buf, in_buffer.bytes(), available);
  195 +
  196 + recv_bytes += available;
  197 + if (nread) {
  198 + *nread = available;
  199 + }
  200 + in_buffer.erase(available);
  201 + return ERROR_SUCCESS;
  202 +}
  203 +
94 #ifdef SRS_AUTO_SSL 204 #ifdef SRS_AUTO_SSL
95 205
96 // verify the sha256 206 // verify the sha256
@@ -426,3 +536,31 @@ VOID TEST(ProtocolMsgArrayTest, MessageArray) @@ -426,3 +536,31 @@ VOID TEST(ProtocolMsgArrayTest, MessageArray)
426 EXPECT_EQ(0, msg.count()); 536 EXPECT_EQ(0, msg.count());
427 } 537 }
428 538
  539 +VOID TEST(ProtocolStackTest, ProtocolTimeout)
  540 +{
  541 + MockBufferIO bio;
  542 + SrsProtocol proto(&bio);
  543 +
  544 + EXPECT_TRUE((int64_t)ST_UTIME_NO_TIMEOUT == proto.get_recv_timeout());
  545 + EXPECT_TRUE((int64_t)ST_UTIME_NO_TIMEOUT == proto.get_send_timeout());
  546 +
  547 + proto.set_recv_timeout(10);
  548 + EXPECT_TRUE(10 == proto.get_recv_timeout());
  549 +
  550 + proto.set_send_timeout(10);
  551 + EXPECT_TRUE(10 == proto.get_send_timeout());
  552 +}
  553 +
  554 +VOID TEST(ProtocolStackTest, ProtocolBytes)
  555 +{
  556 + MockBufferIO bio;
  557 + SrsProtocol proto(&bio);
  558 +
  559 + EXPECT_TRUE(0 == proto.get_recv_bytes());
  560 + EXPECT_TRUE(0 == proto.get_send_bytes());
  561 +
  562 + SrsConnectAppPacket* pkt = new SrsConnectAppPacket();
  563 + proto.send_and_free_packet(pkt, 0);
  564 + EXPECT_TRUE(0 < proto.get_send_bytes());
  565 +}
  566 +
@@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 34
35 #include <srs_protocol_rtmp.hpp> 35 #include <srs_protocol_rtmp.hpp>
36 #include <srs_protocol_handshake.hpp> 36 #include <srs_protocol_handshake.hpp>
  37 +#include <srs_kernel_buffer.hpp>
37 38
38 #ifdef SRS_AUTO_SSL 39 #ifdef SRS_AUTO_SSL
39 using namespace _srs_internal; 40 using namespace _srs_internal;
@@ -69,4 +70,41 @@ public: @@ -69,4 +70,41 @@ public:
69 virtual int read(void* buf, size_t size, ssize_t* nread); 70 virtual int read(void* buf, size_t size, ssize_t* nread);
70 }; 71 };
71 72
  73 +class MockBufferIO : public ISrsProtocolReaderWriter
  74 +{
  75 +public:
  76 + int64_t recv_timeout;
  77 + int64_t send_timeout;
  78 + int64_t recv_bytes;
  79 + int64_t send_bytes;
  80 + // data source for socket read.
  81 + SrsBuffer in_buffer;
  82 + // data buffer for socket send.
  83 + SrsBuffer out_buffer;
  84 +public:
  85 + MockBufferIO();
  86 + virtual ~MockBufferIO();
  87 +// for protocol
  88 +public:
  89 + virtual bool is_never_timeout(int64_t timeout_us);
  90 +// for handshake.
  91 +public:
  92 + virtual int read_fully(void* buf, size_t size, ssize_t* nread);
  93 + virtual int write(void* buf, size_t size, ssize_t* nwrite);
  94 +// for protocol
  95 +public:
  96 + virtual void set_recv_timeout(int64_t timeout_us);
  97 + virtual int64_t get_recv_timeout();
  98 + virtual int64_t get_recv_bytes();
  99 +// for protocol
  100 +public:
  101 + virtual void set_send_timeout(int64_t timeout_us);
  102 + virtual int64_t get_send_timeout();
  103 + virtual int64_t get_send_bytes();
  104 + virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite);
  105 +// for protocol/amf0/msg-codec
  106 +public:
  107 + virtual int read(void* buf, size_t size, ssize_t* nread);
  108 +};
  109 +
72 #endif 110 #endif