mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
refine http stream server
This commit is contained in:
parent
9eedf1ac40
commit
6fba0db9b5
2 changed files with 104 additions and 86 deletions
|
@ -164,104 +164,120 @@ int SrsHttpVhost::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
|
||||||
std::string fullpath = get_request_file(req);
|
std::string fullpath = get_request_file(req);
|
||||||
|
|
||||||
if (srs_string_ends_with(fullpath, ".ts")) {
|
if (srs_string_ends_with(fullpath, ".ts")) {
|
||||||
// TODO: FIXME: use more advance cache.
|
return response_ts_file(skt, req, fullpath);
|
||||||
// for ts video large file, use bytes to write it.
|
|
||||||
int fd = ::open(fullpath.c_str(), O_RDONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
ret = ERROR_HTTP_OPEN_FILE;
|
|
||||||
srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t length = (int64_t)::lseek(fd, 0, SEEK_END);
|
|
||||||
::lseek(fd, 0, SEEK_SET);
|
|
||||||
|
|
||||||
// write http header for ts.
|
|
||||||
std::stringstream ss;
|
|
||||||
|
|
||||||
res_status_line(ss)->res_content_type_mpegts(ss)
|
|
||||||
->res_content_length(ss, (int)length);
|
|
||||||
|
|
||||||
if (req->requires_crossdomain()) {
|
|
||||||
res_enable_crossdomain(ss);
|
|
||||||
}
|
|
||||||
|
|
||||||
res_header_eof(ss);
|
|
||||||
|
|
||||||
// flush http header to peer
|
|
||||||
if ((ret = res_flush(skt, ss)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write body.
|
|
||||||
int64_t left = length;
|
|
||||||
char* buf = req->http_ts_send_buffer();
|
|
||||||
|
|
||||||
while (left > 0) {
|
|
||||||
ssize_t nread = -1;
|
|
||||||
// TODO: FIXME: use st_read.
|
|
||||||
if ((nread = ::read(fd, buf, HTTP_TS_SEND_BUFFER_SIZE)) < 0) {
|
|
||||||
::close(fd);
|
|
||||||
ret = ERROR_HTTP_READ_FILE;
|
|
||||||
srs_warn("read file %s failed, ret=%d", fullpath.c_str(), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
left -= nread;
|
|
||||||
if ((ret = skt->write(buf, nread, NULL)) != ERROR_SUCCESS) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
::close(fd);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: FIXME: refine the file stream.
|
return response_regular_file(skt, req, fullpath);
|
||||||
int fd = ::open(fullpath.c_str(), O_RDONLY);
|
}
|
||||||
if (fd < 0) {
|
|
||||||
ret = ERROR_HTTP_OPEN_FILE;
|
|
||||||
srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t length = (int64_t)::lseek(fd, 0, SEEK_END);
|
return ret;
|
||||||
::lseek(fd, 0, SEEK_SET);
|
}
|
||||||
|
|
||||||
char* buf = new char[length];
|
int SrsHttpVhost::response_regular_file(SrsSocket* skt, SrsHttpMessage* req, string fullpath)
|
||||||
SrsAutoFree(char, buf);
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// TODO: FIXME: refine the file stream.
|
||||||
|
int fd = ::open(fullpath.c_str(), O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
ret = ERROR_HTTP_OPEN_FILE;
|
||||||
|
srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t length = (int64_t)::lseek(fd, 0, SEEK_END);
|
||||||
|
::lseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
char* buf = new char[length];
|
||||||
|
SrsAutoFree(char, buf);
|
||||||
|
|
||||||
|
// TODO: FIXME: use st_read.
|
||||||
|
if (::read(fd, buf, length) < 0) {
|
||||||
|
::close(fd);
|
||||||
|
ret = ERROR_HTTP_READ_FILE;
|
||||||
|
srs_warn("read file %s failed, ret=%d", fullpath.c_str(), ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
::close(fd);
|
||||||
|
|
||||||
|
std::string str;
|
||||||
|
str.append(buf, length);
|
||||||
|
|
||||||
|
if (srs_string_ends_with(fullpath, ".ts")) {
|
||||||
|
return res_mpegts(skt, req, str);
|
||||||
|
} else if (srs_string_ends_with(fullpath, ".m3u8")) {
|
||||||
|
return res_m3u8(skt, req, str);
|
||||||
|
} else if (srs_string_ends_with(fullpath, ".xml")) {
|
||||||
|
return res_xml(skt, req, str);
|
||||||
|
} else if (srs_string_ends_with(fullpath, ".js")) {
|
||||||
|
return res_javascript(skt, req, str);
|
||||||
|
} else if (srs_string_ends_with(fullpath, ".json")) {
|
||||||
|
return res_json(skt, req, str);
|
||||||
|
} else if (srs_string_ends_with(fullpath, ".swf")) {
|
||||||
|
return res_swf(skt, req, str);
|
||||||
|
} else if (srs_string_ends_with(fullpath, ".css")) {
|
||||||
|
return res_css(skt, req, str);
|
||||||
|
} else if (srs_string_ends_with(fullpath, ".ico")) {
|
||||||
|
return res_ico(skt, req, str);
|
||||||
|
} else {
|
||||||
|
return res_text(skt, req, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsHttpVhost::response_ts_file(SrsSocket* skt, SrsHttpMessage* req, string fullpath)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// TODO: FIXME: use more advance cache.
|
||||||
|
// for ts video large file, use bytes to write it.
|
||||||
|
int fd = ::open(fullpath.c_str(), O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
ret = ERROR_HTTP_OPEN_FILE;
|
||||||
|
srs_warn("open file %s failed, ret=%d", fullpath.c_str(), ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t length = (int64_t)::lseek(fd, 0, SEEK_END);
|
||||||
|
::lseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
// write http header for ts.
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
res_status_line(ss)->res_content_type_mpegts(ss)
|
||||||
|
->res_content_length(ss, (int)length);
|
||||||
|
|
||||||
|
if (req->requires_crossdomain()) {
|
||||||
|
res_enable_crossdomain(ss);
|
||||||
|
}
|
||||||
|
|
||||||
|
res_header_eof(ss);
|
||||||
|
|
||||||
|
// flush http header to peer
|
||||||
|
if ((ret = res_flush(skt, ss)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write body.
|
||||||
|
int64_t left = length;
|
||||||
|
char* buf = req->http_ts_send_buffer();
|
||||||
|
|
||||||
|
while (left > 0) {
|
||||||
|
ssize_t nread = -1;
|
||||||
// TODO: FIXME: use st_read.
|
// TODO: FIXME: use st_read.
|
||||||
if (::read(fd, buf, length) < 0) {
|
if ((nread = ::read(fd, buf, HTTP_TS_SEND_BUFFER_SIZE)) < 0) {
|
||||||
::close(fd);
|
::close(fd);
|
||||||
ret = ERROR_HTTP_READ_FILE;
|
ret = ERROR_HTTP_READ_FILE;
|
||||||
srs_warn("read file %s failed, ret=%d", fullpath.c_str(), ret);
|
srs_warn("read file %s failed, ret=%d", fullpath.c_str(), ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
::close(fd);
|
|
||||||
|
|
||||||
std::string str;
|
left -= nread;
|
||||||
str.append(buf, length);
|
if ((ret = skt->write(buf, nread, NULL)) != ERROR_SUCCESS) {
|
||||||
|
break;
|
||||||
if (srs_string_ends_with(fullpath, ".ts")) {
|
|
||||||
return res_mpegts(skt, req, str);
|
|
||||||
} else if (srs_string_ends_with(fullpath, ".m3u8")) {
|
|
||||||
return res_m3u8(skt, req, str);
|
|
||||||
} else if (srs_string_ends_with(fullpath, ".xml")) {
|
|
||||||
return res_xml(skt, req, str);
|
|
||||||
} else if (srs_string_ends_with(fullpath, ".js")) {
|
|
||||||
return res_javascript(skt, req, str);
|
|
||||||
} else if (srs_string_ends_with(fullpath, ".json")) {
|
|
||||||
return res_json(skt, req, str);
|
|
||||||
} else if (srs_string_ends_with(fullpath, ".swf")) {
|
|
||||||
return res_swf(skt, req, str);
|
|
||||||
} else if (srs_string_ends_with(fullpath, ".css")) {
|
|
||||||
return res_css(skt, req, str);
|
|
||||||
} else if (srs_string_ends_with(fullpath, ".ico")) {
|
|
||||||
return res_ico(skt, req, str);
|
|
||||||
} else {
|
|
||||||
return res_text(skt, req, str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
::close(fd);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,8 @@ protected:
|
||||||
virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase);
|
virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase);
|
||||||
virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
|
virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
|
||||||
private:
|
private:
|
||||||
|
virtual int response_regular_file(SrsSocket* skt, SrsHttpMessage* req, std::string fullpath);
|
||||||
|
virtual int response_ts_file(SrsSocket* skt, SrsHttpMessage* req, std::string fullpath);
|
||||||
virtual std::string get_request_file(SrsHttpMessage* req);
|
virtual std::string get_request_file(SrsHttpMessage* req);
|
||||||
public:
|
public:
|
||||||
virtual std::string vhost();
|
virtual std::string vhost();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue