winlin

support http methods, support js crossdomain request

@@ -46,7 +46,8 @@ namespace srs @@ -46,7 +46,8 @@ namespace srs
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 - #define __CRLF __CR""__LF // 0x0D0A 49 + #define __CRLF "\r\n" // 0x0D0A
  50 + #define __CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A
50 }; 51 };
51 52
52 #ifdef SRS_HTTP_CALLBACK 53 #ifdef SRS_HTTP_CALLBACK
@@ -23,22 +23,52 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,22 +23,52 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_app_http_conn.hpp> 24 #include <srs_app_http_conn.hpp>
25 25
  26 +#include <sstream>
  27 +using namespace std;
  28 +
26 #include <srs_kernel_log.hpp> 29 #include <srs_kernel_log.hpp>
27 #include <srs_kernel_error.hpp> 30 #include <srs_kernel_error.hpp>
28 #include <srs_app_socket.hpp> 31 #include <srs_app_socket.hpp>
  32 +#include <srs_app_http.hpp>
  33 +#include <srs_kernel_buffer.hpp>
29 34
30 #define SRS_HTTP_HEADER_BUFFER 1024 35 #define SRS_HTTP_HEADER_BUFFER 1024
31 36
  37 +SrsHttpRequest::SrsHttpRequest()
  38 +{
  39 + body = new SrsBuffer();
  40 + state = SrsHttpParseStateInit;
  41 +}
  42 +
  43 +SrsHttpRequest::~SrsHttpRequest()
  44 +{
  45 + srs_freep(body);
  46 +}
  47 +
  48 +void SrsHttpRequest::reset()
  49 +{
  50 + state = SrsHttpParseStateInit;
  51 + body->clear();
  52 + url = "";
  53 +}
  54 +
  55 +bool SrsHttpRequest::is_complete()
  56 +{
  57 + return state == SrsHttpParseStateComplete;
  58 +}
  59 +
32 SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd) 60 SrsHttpConn::SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd)
33 : SrsConnection(srs_server, client_stfd) 61 : SrsConnection(srs_server, client_stfd)
34 { 62 {
  63 + req = new SrsHttpRequest();
35 } 64 }
36 65
37 -SrsHttpConn::~SrsHttpConn() 66 +SrsHttpConn::~SrsHttpConn()
38 { 67 {
  68 + srs_freep(req);
39 } 69 }
40 70
41 -int SrsHttpConn::do_cycle() 71 +int SrsHttpConn::do_cycle()
42 { 72 {
43 int ret = ERROR_SUCCESS; 73 int ret = ERROR_SUCCESS;
44 74
@@ -69,7 +99,7 @@ int SrsHttpConn::do_cycle() @@ -69,7 +99,7 @@ int SrsHttpConn::do_cycle()
69 SrsSocket skt(stfd); 99 SrsSocket skt(stfd);
70 100
71 for (;;) { 101 for (;;) {
72 - if ((ret = process_request(&skt, &parser, &settings)) != ERROR_SUCCESS) { 102 + if ((ret = parse_request(&skt, &parser, &settings)) != ERROR_SUCCESS) {
73 if (!srs_is_client_gracefully_close(ret)) { 103 if (!srs_is_client_gracefully_close(ret)) {
74 srs_error("http client cycle failed. ret=%d", ret); 104 srs_error("http client cycle failed. ret=%d", ret);
75 } 105 }
@@ -80,12 +110,12 @@ int SrsHttpConn::do_cycle() @@ -80,12 +110,12 @@ int SrsHttpConn::do_cycle()
80 return ret; 110 return ret;
81 } 111 }
82 112
83 -int SrsHttpConn::process_request(SrsSocket* skt, http_parser* parser, http_parser_settings* settings) 113 +int SrsHttpConn::parse_request(SrsSocket* skt, http_parser* parser, http_parser_settings* settings)
84 { 114 {
85 int ret = ERROR_SUCCESS; 115 int ret = ERROR_SUCCESS;
86 116
87 // reset response header. 117 // reset response header.
88 - http_header = NULL; 118 + req->reset();
89 119
90 // parser header. 120 // parser header.
91 char buf[SRS_HTTP_HEADER_BUFFER]; 121 char buf[SRS_HTTP_HEADER_BUFFER];
@@ -102,13 +132,11 @@ int SrsHttpConn::process_request(SrsSocket* skt, http_parser* parser, http_parse @@ -102,13 +132,11 @@ int SrsHttpConn::process_request(SrsSocket* skt, http_parser* parser, http_parse
102 srs_info("read_size=%d, nparsed=%d", (int)nread, (int)nparsed); 132 srs_info("read_size=%d, nparsed=%d", (int)nread, (int)nparsed);
103 133
104 // check header size. 134 // 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); 135 + if (req->is_complete()) {
  136 + srs_trace("http request parsed, method=%d, url=%s, content-length=%"PRId64"",
  137 + req->header.method, req->url.c_str(), req->header.content_length);
110 138
111 - return complete_header(skt, http_header, buf + nparsed, nb_body); 139 + return process_request(skt);
112 } 140 }
113 141
114 if (nparsed != nread) { 142 if (nparsed != nread) {
@@ -121,17 +149,38 @@ int SrsHttpConn::process_request(SrsSocket* skt, http_parser* parser, http_parse @@ -121,17 +149,38 @@ int SrsHttpConn::process_request(SrsSocket* skt, http_parser* parser, http_parse
121 return ret; 149 return ret;
122 } 150 }
123 151
124 -int SrsHttpConn::complete_header(SrsSocket* skt, http_parser* header, char* body, int nb_body) 152 +int SrsHttpConn::process_request(SrsSocket* skt)
125 { 153 {
126 int ret = ERROR_SUCCESS; 154 int ret = ERROR_SUCCESS;
127 155
128 - char data[] = "HTTP/1.1 200 OK\r\n"  
129 - "Server: SRS/"RTMP_SIG_SRS_VERSION"\r\n"  
130 - "Content-Length: 15\r\n"  
131 - "Content-Type: text/html;charset=utf-8\r\n\r\n"  
132 - "hello http/1.1~"; 156 + if (req->header.method == HTTP_OPTIONS) {
  157 + char data[] = "HTTP/1.1 200 OK" __CRLF
  158 + "Content-Length: 0"__CRLF
  159 + "Server: SRS/"RTMP_SIG_SRS_VERSION""__CRLF
  160 + "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT"__CRLF
  161 + "Access-Control-Allow-Origin: *"__CRLF
  162 + "Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE"__CRLF
  163 + "Access-Control-Allow-Headers: Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type"__CRLF
  164 + "Content-Type: text/html;charset=utf-8"__CRLFCRLF
  165 + "";
  166 + return skt->write(data, sizeof(data), NULL);
  167 + } else {
  168 + std::string tilte = "SRS/"RTMP_SIG_SRS_VERSION;
  169 + tilte += " hello http/1.1~\n";
133 170
134 - skt->write(data, sizeof(data), NULL); 171 + std::stringstream ss;
  172 + ss << "HTTP/1.1 200 OK " << __CRLF
  173 + << "Content-Length: "<< tilte.length() + req->body->size() << __CRLF
  174 + << "Server: SRS/"RTMP_SIG_SRS_VERSION"" << __CRLF
  175 + << "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF
  176 + << "Access-Control-Allow-Origin: *" << __CRLF
  177 + << "Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE" << __CRLF
  178 + << "Access-Control-Allow-Headers: Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type" << __CRLF
  179 + << "Content-Type: text/html;charset=utf-8" << __CRLFCRLF
  180 + << tilte << (req->body->empty()? "":req->body->bytes())
  181 + << "";
  182 + return skt->write(ss.str().c_str(), ss.str().length(), NULL);
  183 + }
135 184
136 return ret; 185 return ret;
137 } 186 }
@@ -139,16 +188,19 @@ int SrsHttpConn::complete_header(SrsSocket* skt, http_parser* header, char* body @@ -139,16 +188,19 @@ int SrsHttpConn::complete_header(SrsSocket* skt, http_parser* header, char* body
139 int SrsHttpConn::on_message_begin(http_parser* parser) 188 int SrsHttpConn::on_message_begin(http_parser* parser)
140 { 189 {
141 SrsHttpConn* obj = (SrsHttpConn*)parser->data; 190 SrsHttpConn* obj = (SrsHttpConn*)parser->data;
142 - (void)obj;  
143 - srs_trace("***MESSAGE BEGIN***"); 191 + obj->req->state = SrsHttpParseStateStart;
  192 +
  193 + srs_info("***MESSAGE BEGIN***");
  194 +
144 return 0; 195 return 0;
145 } 196 }
146 197
147 int SrsHttpConn::on_headers_complete(http_parser* parser) 198 int SrsHttpConn::on_headers_complete(http_parser* parser)
148 { 199 {
149 SrsHttpConn* obj = (SrsHttpConn*)parser->data; 200 SrsHttpConn* obj = (SrsHttpConn*)parser->data;
150 - (void)obj;  
151 - srs_trace("***HEADERS COMPLETE***"); 201 + memcpy(&obj->req->header, parser, sizeof(http_parser));
  202 +
  203 + srs_info("***HEADERS COMPLETE***");
152 204
153 // see http_parser.c:1570, return 1 to skip body. 205 // see http_parser.c:1570, return 1 to skip body.
154 return 0; 206 return 0;
@@ -157,41 +209,48 @@ int SrsHttpConn::on_headers_complete(http_parser* parser) @@ -157,41 +209,48 @@ int SrsHttpConn::on_headers_complete(http_parser* parser)
157 int SrsHttpConn::on_message_complete(http_parser* parser) 209 int SrsHttpConn::on_message_complete(http_parser* parser)
158 { 210 {
159 SrsHttpConn* obj = (SrsHttpConn*)parser->data; 211 SrsHttpConn* obj = (SrsHttpConn*)parser->data;
160 - srs_trace("***MESSAGE COMPLETE***\n");  
161 -  
162 // save the parser when header parse completed. 212 // save the parser when header parse completed.
163 - obj->http_header = parser; 213 + obj->req->state = SrsHttpParseStateComplete;
  214 +
  215 + srs_info("***MESSAGE COMPLETE***\n");
  216 +
164 return 0; 217 return 0;
165 } 218 }
166 219
167 int SrsHttpConn::on_url(http_parser* parser, const char* at, size_t length) 220 int SrsHttpConn::on_url(http_parser* parser, const char* at, size_t length)
168 { 221 {
169 SrsHttpConn* obj = (SrsHttpConn*)parser->data; 222 SrsHttpConn* obj = (SrsHttpConn*)parser->data;
170 - (void)obj;  
171 - srs_trace("Method: %d, Url: %.*s", parser->method, (int)length, at); 223 +
  224 + if (length > 0) {
  225 + obj->req->url.append(at, (int)length);
  226 + }
  227 +
  228 + srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at);
  229 +
172 return 0; 230 return 0;
173 } 231 }
174 232
175 -int SrsHttpConn::on_header_field(http_parser* parser, const char* at, size_t length) 233 +int SrsHttpConn::on_header_field(http_parser* /*parser*/, const char* at, size_t length)
176 { 234 {
177 - SrsHttpConn* obj = (SrsHttpConn*)parser->data;  
178 - (void)obj;  
179 - srs_trace("Header field: %.*s", (int)length, at); 235 + srs_info("Header field: %.*s", (int)length, at);
180 return 0; 236 return 0;
181 } 237 }
182 238
183 -int SrsHttpConn::on_header_value(http_parser* parser, const char* at, size_t length) 239 +int SrsHttpConn::on_header_value(http_parser* /*parser*/, const char* at, size_t length)
184 { 240 {
185 - SrsHttpConn* obj = (SrsHttpConn*)parser->data;  
186 - (void)obj;  
187 - srs_trace("Header value: %.*s", (int)length, at); 241 + srs_info("Header value: %.*s", (int)length, at);
188 return 0; 242 return 0;
189 } 243 }
190 244
191 int SrsHttpConn::on_body(http_parser* parser, const char* at, size_t length) 245 int SrsHttpConn::on_body(http_parser* parser, const char* at, size_t length)
192 { 246 {
193 SrsHttpConn* obj = (SrsHttpConn*)parser->data; 247 SrsHttpConn* obj = (SrsHttpConn*)parser->data;
194 - (void)obj;  
195 - srs_trace("Body: %.*s", (int)length, at); 248 +
  249 + if (length > 0) {
  250 + obj->req->body->append(at, (int)length);
  251 + }
  252 +
  253 + srs_info("Body: %.*s", (int)length, at);
  254 +
196 return 0; 255 return 0;
197 } 256 }
@@ -36,19 +36,41 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -36,19 +36,41 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 #include <http_parser.h> 36 #include <http_parser.h>
37 37
38 class SrsSocket; 38 class SrsSocket;
  39 +class SrsBuffer;
  40 +
  41 +enum SrsHttpParseState {
  42 + SrsHttpParseStateInit = 0,
  43 + SrsHttpParseStateStart,
  44 + SrsHttpParseStateComplete
  45 +};
  46 +
  47 +class SrsHttpRequest
  48 +{
  49 +public:
  50 + std::string url;
  51 + http_parser header;
  52 + SrsBuffer* body;
  53 + SrsHttpParseState state;
  54 +
  55 + SrsHttpRequest();
  56 + virtual ~SrsHttpRequest();
  57 +
  58 + virtual void reset();
  59 + virtual bool is_complete();
  60 +};
39 61
40 class SrsHttpConn : public SrsConnection 62 class SrsHttpConn : public SrsConnection
41 { 63 {
42 private: 64 private:
43 - http_parser* http_header; 65 + SrsHttpRequest* req;
44 public: 66 public:
45 SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd); 67 SrsHttpConn(SrsServer* srs_server, st_netfd_t client_stfd);
46 virtual ~SrsHttpConn(); 68 virtual ~SrsHttpConn();
47 protected: 69 protected:
48 virtual int do_cycle(); 70 virtual int do_cycle();
49 private: 71 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); 72 + virtual int parse_request(SrsSocket* skt, http_parser* parser, http_parser_settings* settings);
  73 + virtual int process_request(SrsSocket* skt);
52 private: 74 private:
53 static int on_message_begin(http_parser* parser); 75 static int on_message_begin(http_parser* parser);
54 static int on_headers_complete(http_parser* parser); 76 static int on_headers_complete(http_parser* parser);
@@ -49,18 +49,34 @@ int SrsBuffer::size() @@ -49,18 +49,34 @@ int SrsBuffer::size()
49 return (int)data.size(); 49 return (int)data.size();
50 } 50 }
51 51
  52 +bool SrsBuffer::empty()
  53 +{
  54 + return size() <= 0;
  55 +}
  56 +
52 char* SrsBuffer::bytes() 57 char* SrsBuffer::bytes()
53 { 58 {
54 return &data.at(0); 59 return &data.at(0);
55 } 60 }
56 61
57 -void SrsBuffer::erase(int size) 62 +void SrsBuffer::erase(int _size)
  63 +{
  64 + if (_size == size()) {
  65 + clear();
  66 + return;
  67 + }
  68 +
  69 + data.erase(data.begin(), data.begin() + _size);
  70 +}
  71 +
  72 +void SrsBuffer::clear()
58 { 73 {
59 - data.erase(data.begin(), data.begin() + size); 74 + data.clear();
60 } 75 }
61 76
62 -void SrsBuffer::append(char* bytes, int size) 77 +void SrsBuffer::append(const char* bytes, int size)
63 { 78 {
  79 + srs_assert(size > 0);
64 data.insert(data.end(), bytes, bytes + size); 80 data.insert(data.end(), bytes, bytes + size);
65 } 81 }
66 82
@@ -59,10 +59,11 @@ public: @@ -59,10 +59,11 @@ public:
59 virtual ~SrsBuffer(); 59 virtual ~SrsBuffer();
60 public: 60 public:
61 virtual int size(); 61 virtual int size();
  62 + virtual bool empty();
62 virtual char* bytes(); 63 virtual char* bytes();
63 virtual void erase(int size); 64 virtual void erase(int size);
64 -private:  
65 - virtual void append(char* bytes, int size); 65 + virtual void clear();
  66 + virtual void append(const char* bytes, int size);
66 public: 67 public:
67 virtual int ensure_buffer_bytes(ISrsBufferReader* skt, int required_size); 68 virtual int ensure_buffer_bytes(ISrsBufferReader* skt, int required_size);
68 }; 69 };