正在显示
8 个修改的文件
包含
214 行增加
和
37 行删除
@@ -204,8 +204,9 @@ help: | @@ -204,8 +204,9 @@ help: | ||
204 | @echo " uninstall uninstall srs from prefix path" | 204 | @echo " uninstall uninstall srs from prefix path" |
205 | 205 | ||
206 | clean: | 206 | clean: |
207 | - (cd ${SRS_OBJS}; rm -f rm -rf srs bandwidth srs_utest) | ||
208 | - (cd ${SRS_OBJS}; rm -rf src research include lib utest) | 207 | + (cd ${SRS_OBJS}; rm -rf srs bandwidth srs_utest) |
208 | + (cd ${SRS_OBJS}; rm -rf src research include lib) | ||
209 | + (cd ${SRS_OBJS}/utest; rm -rf *.o *.a) | ||
209 | (cd research/librtmp; make clean) | 210 | (cd research/librtmp; make clean) |
210 | (cd research/api-server/static-dir; rm -rf crossdomain.xml forward live players) | 211 | (cd research/api-server/static-dir; rm -rf crossdomain.xml forward live players) |
211 | 212 |
@@ -43,6 +43,9 @@ using namespace srs; | @@ -43,6 +43,9 @@ using namespace srs; | ||
43 | #define SRS_DEFAULT_HTTP_PORT 80 | 43 | #define SRS_DEFAULT_HTTP_PORT 80 |
44 | #define SRS_HTTP_RESPONSE_OK "0" | 44 | #define SRS_HTTP_RESPONSE_OK "0" |
45 | 45 | ||
46 | +#define SRS_HTTP_HEADER_BUFFER 1024 | ||
47 | +#define SRS_HTTP_BODY_BUFFER 32 * 1024 | ||
48 | + | ||
46 | SrsHttpUri::SrsHttpUri() | 49 | SrsHttpUri::SrsHttpUri() |
47 | { | 50 | { |
48 | port = SRS_DEFAULT_HTTP_PORT; | 51 | port = SRS_DEFAULT_HTTP_PORT; |
@@ -153,13 +156,13 @@ int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res) | @@ -153,13 +156,13 @@ int SrsHttpClient::post(SrsHttpUri* uri, std::string req, std::string& res) | ||
153 | // POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s | 156 | // POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s |
154 | std::stringstream ss; | 157 | std::stringstream ss; |
155 | ss << "POST " << uri->get_path() << " " | 158 | ss << "POST " << uri->get_path() << " " |
156 | - << "HTTP/1.1" << CRLF | ||
157 | - << "Host: " << uri->get_host() << CRLF | ||
158 | - << "Connection: Keep-Alive" << CRLF | ||
159 | - << "Content-Length: " << std::dec << req.length() << CRLF | ||
160 | - << "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << CRLF | ||
161 | - << "Content-Type: text/html" << CRLF | ||
162 | - << CRLF | 159 | + << "HTTP/1.1" << __CRLF |
160 | + << "Host: " << uri->get_host() << __CRLF | ||
161 | + << "Connection: Keep-Alive" << __CRLF | ||
162 | + << "Content-Length: " << std::dec << req.length() << __CRLF | ||
163 | + << "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << __CRLF | ||
164 | + << "Content-Type: text/html" << __CRLF | ||
165 | + << __CRLF | ||
163 | << req; | 166 | << req; |
164 | 167 | ||
165 | SrsSocket skt(stfd); | 168 | SrsSocket skt(stfd); |
@@ -375,13 +378,13 @@ int SrsHttpClient::parse_response_body_data(SrsHttpUri* uri, SrsSocket* skt, std | @@ -375,13 +378,13 @@ int SrsHttpClient::parse_response_body_data(SrsHttpUri* uri, SrsSocket* skt, std | ||
375 | int SrsHttpClient::on_headers_complete(http_parser* parser) | 378 | int SrsHttpClient::on_headers_complete(http_parser* parser) |
376 | { | 379 | { |
377 | SrsHttpClient* obj = (SrsHttpClient*)parser->data; | 380 | SrsHttpClient* obj = (SrsHttpClient*)parser->data; |
378 | - obj->comple_header(parser); | 381 | + obj->complete_header(parser); |
379 | 382 | ||
380 | // see http_parser.c:1570, return 1 to skip body. | 383 | // see http_parser.c:1570, return 1 to skip body. |
381 | return 1; | 384 | return 1; |
382 | } | 385 | } |
383 | 386 | ||
384 | -void SrsHttpClient::comple_header(http_parser* parser) | 387 | +void SrsHttpClient::complete_header(http_parser* parser) |
385 | { | 388 | { |
386 | // save the parser status when header parse completed. | 389 | // save the parser status when header parse completed. |
387 | memcpy(&http_header, parser, sizeof(http_header)); | 390 | memcpy(&http_header, parser, sizeof(http_header)); |
@@ -35,18 +35,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -35,18 +35,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
35 | namespace srs | 35 | namespace srs |
36 | { | 36 | { |
37 | // CR = <US-ASCII CR, carriage return (13)> | 37 | // CR = <US-ASCII CR, carriage return (13)> |
38 | - const static char CR = '\r'; | 38 | + #define __CR "\r" // 0x0D |
39 | // LF = <US-ASCII LF, linefeed (10)> | 39 | // LF = <US-ASCII LF, linefeed (10)> |
40 | - const static char LF = '\n'; | 40 | + #define __LF "\n" // 0x0A |
41 | // SP = <US-ASCII SP, space (32)> | 41 | // SP = <US-ASCII SP, space (32)> |
42 | - const static char SP = ' '; | 42 | + #define __SP " " // 0x20 |
43 | // HT = <US-ASCII HT, horizontal-tab (9)> | 43 | // HT = <US-ASCII HT, horizontal-tab (9)> |
44 | - const static char HT = 9; | ||
45 | - | 44 | + #define __HT "\x09" // 0x09 |
45 | + | ||
46 | // HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all | 46 | // HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all |
47 | // protocol elements except the entity-body (see appendix 19.3 for | 47 | // protocol elements except the entity-body (see appendix 19.3 for |
48 | // tolerant applications). | 48 | // tolerant applications). |
49 | - const static char* CRLF = "\r\n"; | 49 | + #define __CRLF __CR""__LF // 0x0D0A |
50 | }; | 50 | }; |
51 | 51 | ||
52 | #ifdef SRS_HTTP_CALLBACK | 52 | #ifdef SRS_HTTP_CALLBACK |
@@ -58,9 +58,6 @@ class SrsSocket; | @@ -58,9 +58,6 @@ class SrsSocket; | ||
58 | 58 | ||
59 | #include <http_parser.h> | 59 | #include <http_parser.h> |
60 | 60 | ||
61 | -#define SRS_HTTP_HEADER_BUFFER 1024 | ||
62 | -#define SRS_HTTP_BODY_BUFFER 32 * 1024 | ||
63 | - | ||
64 | /** | 61 | /** |
65 | * used to resolve the http uri. | 62 | * used to resolve the http uri. |
66 | */ | 63 | */ |
@@ -124,7 +121,7 @@ private: | @@ -124,7 +121,7 @@ private: | ||
124 | virtual int parse_response_body_data(SrsHttpUri* uri, SrsSocket* skt, std::string* response, size_t body_left, const void* buf, size_t size); | 121 | virtual int parse_response_body_data(SrsHttpUri* uri, SrsSocket* skt, std::string* response, size_t body_left, const void* buf, size_t size); |
125 | private: | 122 | private: |
126 | static int on_headers_complete(http_parser* parser); | 123 | static int on_headers_complete(http_parser* parser); |
127 | - virtual void comple_header(http_parser* parser); | 124 | + virtual void complete_header(http_parser* parser); |
128 | }; | 125 | }; |
129 | 126 | ||
130 | /** | 127 | /** |
@@ -25,6 +25,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -25,6 +25,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
25 | 25 | ||
26 | #include <srs_kernel_log.hpp> | 26 | #include <srs_kernel_log.hpp> |
27 | #include <srs_kernel_error.hpp> | 27 | #include <srs_kernel_error.hpp> |
28 | +#include <srs_app_socket.hpp> | ||
29 | + | ||
30 | +#define SRS_HTTP_HEADER_BUFFER 1024 | ||
28 | 31 | ||
29 | SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd) | 32 | SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd) |
30 | : SrsConnection(srs_server, client_stfd) | 33 | : SrsConnection(srs_server, client_stfd) |
@@ -44,13 +47,151 @@ int SrsHttpConn::do_cycle() | @@ -44,13 +47,151 @@ int SrsHttpConn::do_cycle() | ||
44 | return ret; | 47 | return ret; |
45 | } | 48 | } |
46 | srs_trace("http get peer ip success. ip=%s", ip); | 49 | srs_trace("http get peer ip success. ip=%s", ip); |
50 | + | ||
51 | + // setup http parser | ||
52 | + http_parser_settings settings; | ||
53 | + | ||
54 | + memset(&settings, 0, sizeof(settings)); | ||
55 | + settings.on_message_begin = on_message_begin; | ||
56 | + settings.on_url = on_url; | ||
57 | + settings.on_header_field = on_header_field; | ||
58 | + settings.on_header_value = on_header_value; | ||
59 | + settings.on_headers_complete = on_headers_complete; | ||
60 | + settings.on_body = on_body; | ||
61 | + settings.on_message_complete = on_message_complete; | ||
62 | + | ||
63 | + http_parser parser; | ||
64 | + http_parser_init(&parser, HTTP_REQUEST); | ||
65 | + // callback object ptr. | ||
66 | + parser.data = (void*)this; | ||
67 | + | ||
68 | + // underlayer socket | ||
69 | + SrsSocket skt(stfd); | ||
70 | + | ||
71 | + for (;;) { | ||
72 | + if ((ret = process_request(&skt, &parser, &settings)) != ERROR_SUCCESS) { | ||
73 | + if (!srs_is_client_gracefully_close(ret)) { | ||
74 | + srs_error("http client cycle failed. ret=%d", ret); | ||
75 | + } | ||
76 | + return ret; | ||
77 | + } | ||
78 | + } | ||
79 | + | ||
80 | + return ret; | ||
81 | +} | ||
82 | + | ||
83 | +int SrsHttpConn::process_request(SrsSocket* skt, http_parser* parser, http_parser_settings* settings) | ||
84 | +{ | ||
85 | + int ret = ERROR_SUCCESS; | ||
86 | + | ||
87 | + // reset response header. | ||
88 | + http_header = NULL; | ||
89 | + | ||
90 | + // parser header. | ||
91 | + char buf[SRS_HTTP_HEADER_BUFFER]; | ||
92 | + for (;;) { | ||
93 | + ssize_t nread; | ||
94 | + if ((ret = skt->read(buf, (size_t)sizeof(buf), &nread)) != ERROR_SUCCESS) { | ||
95 | + if (!srs_is_client_gracefully_close(ret)) { | ||
96 | + srs_error("read body from server failed. ret=%d", ret); | ||
97 | + } | ||
98 | + return ret; | ||
99 | + } | ||
100 | + | ||
101 | + ssize_t nparsed = http_parser_execute(parser, settings, buf, nread); | ||
102 | + srs_info("read_size=%d, nparsed=%d", (int)nread, (int)nparsed); | ||
103 | + | ||
104 | + // check header size. | ||
105 | + if (http_header) { | ||
106 | + int nb_body = nread - nparsed; | ||
107 | + | ||
108 | + srs_info("http header parsed, size=%d, content-length=%"PRId64", nb_body=%d", | ||
109 | + http_header->nread, http_header->content_length, nb_body); | ||
110 | + | ||
111 | + return complete_header(skt, http_header, buf + nparsed, nb_body); | ||
112 | + } | ||
113 | + | ||
114 | + if (nparsed != nread) { | ||
115 | + ret = ERROR_HTTP_PARSE_HEADER; | ||
116 | + srs_error("parse response error, parsed(%d)!=read(%d), ret=%d", (int)nparsed, (int)nread, ret); | ||
117 | + return ret; | ||
118 | + } | ||
119 | + } | ||
120 | + | ||
121 | + return ret; | ||
122 | +} | ||
123 | + | ||
124 | +int SrsHttpConn::complete_header(SrsSocket* skt, http_parser* header, char* body, int nb_body) | ||
125 | +{ | ||
126 | + int ret = ERROR_SUCCESS; | ||
47 | 127 | ||
48 | char data[] = "HTTP/1.1 200 OK\r\n" | 128 | char data[] = "HTTP/1.1 200 OK\r\n" |
49 | "Server: SRS/"RTMP_SIG_SRS_VERSION"\r\n" | 129 | "Server: SRS/"RTMP_SIG_SRS_VERSION"\r\n" |
50 | "Content-Length: 15\r\n" | 130 | "Content-Length: 15\r\n" |
51 | "Content-Type: text/html;charset=utf-8\r\n\r\n" | 131 | "Content-Type: text/html;charset=utf-8\r\n\r\n" |
52 | "hello http/1.1~"; | 132 | "hello http/1.1~"; |
53 | - st_write(stfd, data, sizeof(data), -1); | ||
54 | 133 | ||
134 | + skt->write(data, sizeof(data), NULL); | ||
135 | + | ||
55 | return ret; | 136 | return ret; |
56 | } | 137 | } |
138 | + | ||
139 | +int SrsHttpConn::on_message_begin(http_parser* parser) | ||
140 | +{ | ||
141 | + SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
142 | + (void)obj; | ||
143 | + srs_trace("***MESSAGE BEGIN***"); | ||
144 | + return 0; | ||
145 | +} | ||
146 | + | ||
147 | +int SrsHttpConn::on_headers_complete(http_parser* parser) | ||
148 | +{ | ||
149 | + SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
150 | + (void)obj; | ||
151 | + srs_trace("***HEADERS COMPLETE***"); | ||
152 | + | ||
153 | + // see http_parser.c:1570, return 1 to skip body. | ||
154 | + return 0; | ||
155 | +} | ||
156 | + | ||
157 | +int SrsHttpConn::on_message_complete(http_parser* parser) | ||
158 | +{ | ||
159 | + SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
160 | + srs_trace("***MESSAGE COMPLETE***\n"); | ||
161 | + | ||
162 | + // save the parser when header parse completed. | ||
163 | + obj->http_header = parser; | ||
164 | + return 0; | ||
165 | +} | ||
166 | + | ||
167 | +int SrsHttpConn::on_url(http_parser* parser, const char* at, size_t length) | ||
168 | +{ | ||
169 | + SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
170 | + (void)obj; | ||
171 | + srs_trace("Method: %d, Url: %.*s", parser->method, (int)length, at); | ||
172 | + return 0; | ||
173 | +} | ||
174 | + | ||
175 | +int SrsHttpConn::on_header_field(http_parser* parser, const char* at, size_t length) | ||
176 | +{ | ||
177 | + SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
178 | + (void)obj; | ||
179 | + srs_trace("Header field: %.*s", (int)length, at); | ||
180 | + return 0; | ||
181 | +} | ||
182 | + | ||
183 | +int SrsHttpConn::on_header_value(http_parser* parser, const char* at, size_t length) | ||
184 | +{ | ||
185 | + SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
186 | + (void)obj; | ||
187 | + srs_trace("Header value: %.*s", (int)length, at); | ||
188 | + return 0; | ||
189 | +} | ||
190 | + | ||
191 | +int SrsHttpConn::on_body(http_parser* parser, const char* at, size_t length) | ||
192 | +{ | ||
193 | + SrsHttpConn* obj = (SrsHttpConn*)parser->data; | ||
194 | + (void)obj; | ||
195 | + srs_trace("Body: %.*s", (int)length, at); | ||
196 | + return 0; | ||
197 | +} |
@@ -33,13 +33,30 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -33,13 +33,30 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
33 | #include <srs_app_st.hpp> | 33 | #include <srs_app_st.hpp> |
34 | #include <srs_app_conn.hpp> | 34 | #include <srs_app_conn.hpp> |
35 | 35 | ||
36 | +#include <http_parser.h> | ||
37 | + | ||
38 | +class SrsSocket; | ||
39 | + | ||
36 | class SrsHttpConn : public SrsConnection | 40 | class SrsHttpConn : public SrsConnection |
37 | { | 41 | { |
42 | +private: | ||
43 | + http_parser* http_header; | ||
38 | public: | 44 | public: |
39 | SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd); | 45 | SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd); |
40 | virtual ~SrsHttpConn(); | 46 | virtual ~SrsHttpConn(); |
41 | protected: | 47 | protected: |
42 | virtual int do_cycle(); | 48 | virtual int do_cycle(); |
49 | +private: | ||
50 | + virtual int process_request(SrsSocket* skt, http_parser* parser, http_parser_settings* settings); | ||
51 | + virtual int complete_header(SrsSocket* skt, http_parser* header, char* body, int nb_body); | ||
52 | +private: | ||
53 | + static int on_message_begin(http_parser* parser); | ||
54 | + static int on_headers_complete(http_parser* parser); | ||
55 | + static int on_message_complete(http_parser* parser); | ||
56 | + static int on_url(http_parser* parser, const char* at, size_t length); | ||
57 | + static int on_header_field(http_parser* parser, const char* at, size_t length); | ||
58 | + static int on_header_value(http_parser* parser, const char* at, size_t length); | ||
59 | + static int on_body(http_parser* parser, const char* at, size_t length); | ||
43 | }; | 60 | }; |
44 | 61 | ||
45 | #endif | 62 | #endif |
@@ -99,23 +99,26 @@ int SrsSocket::read(const void* buf, size_t size, ssize_t* nread) | @@ -99,23 +99,26 @@ int SrsSocket::read(const void* buf, size_t size, ssize_t* nread) | ||
99 | { | 99 | { |
100 | int ret = ERROR_SUCCESS; | 100 | int ret = ERROR_SUCCESS; |
101 | 101 | ||
102 | - *nread = st_read(stfd, (void*)buf, size, recv_timeout); | 102 | + ssize_t nb_read = st_read(stfd, (void*)buf, size, recv_timeout); |
103 | + if (nread) { | ||
104 | + *nread = nb_read; | ||
105 | + } | ||
103 | 106 | ||
104 | // On success a non-negative integer indicating the number of bytes actually read is returned | 107 | // On success a non-negative integer indicating the number of bytes actually read is returned |
105 | // (a value of 0 means the network connection is closed or end of file is reached). | 108 | // (a value of 0 means the network connection is closed or end of file is reached). |
106 | - if (*nread <= 0) { | 109 | + if (nb_read <= 0) { |
107 | if (errno == ETIME) { | 110 | if (errno == ETIME) { |
108 | return ERROR_SOCKET_TIMEOUT; | 111 | return ERROR_SOCKET_TIMEOUT; |
109 | } | 112 | } |
110 | 113 | ||
111 | - if (*nread == 0) { | 114 | + if (nb_read == 0) { |
112 | errno = ECONNRESET; | 115 | errno = ECONNRESET; |
113 | } | 116 | } |
114 | 117 | ||
115 | return ERROR_SOCKET_READ; | 118 | return ERROR_SOCKET_READ; |
116 | } | 119 | } |
117 | 120 | ||
118 | - recv_bytes += *nread; | 121 | + recv_bytes += nb_read; |
119 | 122 | ||
120 | return ret; | 123 | return ret; |
121 | } | 124 | } |
@@ -124,23 +127,26 @@ int SrsSocket::read_fully(const void* buf, size_t size, ssize_t* nread) | @@ -124,23 +127,26 @@ int SrsSocket::read_fully(const void* buf, size_t size, ssize_t* nread) | ||
124 | { | 127 | { |
125 | int ret = ERROR_SUCCESS; | 128 | int ret = ERROR_SUCCESS; |
126 | 129 | ||
127 | - *nread = st_read_fully(stfd, (void*)buf, size, recv_timeout); | 130 | + ssize_t nb_read = st_read_fully(stfd, (void*)buf, size, recv_timeout); |
131 | + if (nread) { | ||
132 | + *nread = nb_read; | ||
133 | + } | ||
128 | 134 | ||
129 | // On success a non-negative integer indicating the number of bytes actually read is returned | 135 | // On success a non-negative integer indicating the number of bytes actually read is returned |
130 | // (a value less than nbyte means the network connection is closed or end of file is reached) | 136 | // (a value less than nbyte means the network connection is closed or end of file is reached) |
131 | - if (*nread != (ssize_t)size) { | 137 | + if (nb_read != (ssize_t)size) { |
132 | if (errno == ETIME) { | 138 | if (errno == ETIME) { |
133 | return ERROR_SOCKET_TIMEOUT; | 139 | return ERROR_SOCKET_TIMEOUT; |
134 | } | 140 | } |
135 | 141 | ||
136 | - if (*nread >= 0) { | 142 | + if (nb_read >= 0) { |
137 | errno = ECONNRESET; | 143 | errno = ECONNRESET; |
138 | } | 144 | } |
139 | 145 | ||
140 | return ERROR_SOCKET_READ_FULLY; | 146 | return ERROR_SOCKET_READ_FULLY; |
141 | } | 147 | } |
142 | 148 | ||
143 | - recv_bytes += *nread; | 149 | + recv_bytes += nb_read; |
144 | 150 | ||
145 | return ret; | 151 | return ret; |
146 | } | 152 | } |
@@ -149,9 +155,12 @@ int SrsSocket::write(const void* buf, size_t size, ssize_t* nwrite) | @@ -149,9 +155,12 @@ int SrsSocket::write(const void* buf, size_t size, ssize_t* nwrite) | ||
149 | { | 155 | { |
150 | int ret = ERROR_SUCCESS; | 156 | int ret = ERROR_SUCCESS; |
151 | 157 | ||
152 | - *nwrite = st_write(stfd, (void*)buf, size, send_timeout); | 158 | + ssize_t nb_write = st_write(stfd, (void*)buf, size, send_timeout); |
159 | + if (nwrite) { | ||
160 | + *nwrite = nb_write; | ||
161 | + } | ||
153 | 162 | ||
154 | - if (*nwrite <= 0) { | 163 | + if (nb_write <= 0) { |
155 | if (errno == ETIME) { | 164 | if (errno == ETIME) { |
156 | return ERROR_SOCKET_TIMEOUT; | 165 | return ERROR_SOCKET_TIMEOUT; |
157 | } | 166 | } |
@@ -159,7 +168,7 @@ int SrsSocket::write(const void* buf, size_t size, ssize_t* nwrite) | @@ -159,7 +168,7 @@ int SrsSocket::write(const void* buf, size_t size, ssize_t* nwrite) | ||
159 | return ERROR_SOCKET_WRITE; | 168 | return ERROR_SOCKET_WRITE; |
160 | } | 169 | } |
161 | 170 | ||
162 | - send_bytes += *nwrite; | 171 | + send_bytes += nb_write; |
163 | 172 | ||
164 | return ret; | 173 | return ret; |
165 | } | 174 | } |
@@ -168,9 +177,12 @@ int SrsSocket::writev(const iovec *iov, int iov_size, ssize_t* nwrite) | @@ -168,9 +177,12 @@ int SrsSocket::writev(const iovec *iov, int iov_size, ssize_t* nwrite) | ||
168 | { | 177 | { |
169 | int ret = ERROR_SUCCESS; | 178 | int ret = ERROR_SUCCESS; |
170 | 179 | ||
171 | - *nwrite = st_writev(stfd, iov, iov_size, send_timeout); | 180 | + ssize_t nb_write = st_writev(stfd, iov, iov_size, send_timeout); |
181 | + if (nwrite) { | ||
182 | + *nwrite = nb_write; | ||
183 | + } | ||
172 | 184 | ||
173 | - if (*nwrite <= 0) { | 185 | + if (nb_write <= 0) { |
174 | if (errno == ETIME) { | 186 | if (errno == ETIME) { |
175 | return ERROR_SOCKET_TIMEOUT; | 187 | return ERROR_SOCKET_TIMEOUT; |
176 | } | 188 | } |
@@ -178,7 +190,7 @@ int SrsSocket::writev(const iovec *iov, int iov_size, ssize_t* nwrite) | @@ -178,7 +190,7 @@ int SrsSocket::writev(const iovec *iov, int iov_size, ssize_t* nwrite) | ||
178 | return ERROR_SOCKET_WRITE; | 190 | return ERROR_SOCKET_WRITE; |
179 | } | 191 | } |
180 | 192 | ||
181 | - send_bytes += *nwrite; | 193 | + send_bytes += nb_write; |
182 | 194 | ||
183 | return ret; | 195 | return ret; |
184 | } | 196 | } |
@@ -60,8 +60,14 @@ public: | @@ -60,8 +60,14 @@ public: | ||
60 | virtual int get_recv_kbps(); | 60 | virtual int get_recv_kbps(); |
61 | virtual int get_send_kbps(); | 61 | virtual int get_send_kbps(); |
62 | public: | 62 | public: |
63 | + /** | ||
64 | + * @param nread, the actual read bytes, ignore if NULL. | ||
65 | + */ | ||
63 | virtual int read(const void* buf, size_t size, ssize_t* nread); | 66 | virtual int read(const void* buf, size_t size, ssize_t* nread); |
64 | virtual int read_fully(const void* buf, size_t size, ssize_t* nread); | 67 | virtual int read_fully(const void* buf, size_t size, ssize_t* nread); |
68 | + /** | ||
69 | + * @param nwrite, the actual write bytes, ignore if NULL. | ||
70 | + */ | ||
65 | virtual int write(const void* buf, size_t size, ssize_t* nwrite); | 71 | virtual int write(const void* buf, size_t size, ssize_t* nwrite); |
66 | virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite); | 72 | virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite); |
67 | }; | 73 | }; |
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
31 | // current release version | 31 | // current release version |
32 | #define VERSION_MAJOR "0" | 32 | #define VERSION_MAJOR "0" |
33 | #define VERSION_MINOR "9" | 33 | #define VERSION_MINOR "9" |
34 | -#define VERSION_REVISION "41" | 34 | +#define VERSION_REVISION "42" |
35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION | 35 | #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION |
36 | // server info. | 36 | // server info. |
37 | #define RTMP_SIG_SRS_KEY "srs" | 37 | #define RTMP_SIG_SRS_KEY "srs" |
-
请 注册 或 登录 后发表评论