Skip to content

Commit

Permalink
HTTP: Fix mp4/flv file size exceed 2GB download error. (ossrs#2780)
Browse files Browse the repository at this point in the history
  • Loading branch information
chundonglinlin committed Dec 23, 2021
1 parent 0f12e9c commit b9757c4
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 53 deletions.
30 changes: 15 additions & 15 deletions trunk/src/app/srs_app_http_static.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ SrsVodStream::~SrsVodStream()
map_ctx_info_.clear();
}

srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int offset)
srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int64_t offset)
{
srs_error_t err = srs_success;

Expand All @@ -69,7 +69,7 @@ srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
}

if (offset > fs->filesize()) {
return srs_error_new(ERROR_HTTP_REMUX_OFFSET_OVERFLOW, "http flv streaming %s overflow. size=%" PRId64 ", offset=%d",
return srs_error_new(ERROR_HTTP_REMUX_OFFSET_OVERFLOW, "http flv streaming %s overflow. size=%" PRId64 ", offset=%" PRId64,
fullpath.c_str(), fs->filesize(), offset);
}

Expand Down Expand Up @@ -112,7 +112,7 @@ srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
int64_t left = fs->filesize() - offset;

// write http header for ts.
w->header()->set_content_length((int)(sizeof(flv_header) + sh_size + left));
w->header()->set_content_length((sizeof(flv_header) + sh_size + left));
w->header()->set_content_type("video/x-flv");
w->write_header(SRS_CONSTS_HTTP_OK);

Expand All @@ -123,40 +123,40 @@ srs_error_t SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
if (sh_size > 0 && (err = w->write(sh_data, sh_size)) != srs_success) {
return srs_error_wrap(err, "write sequence");
}

// write body.
if ((err = ffd.seek2(offset)) != srs_success) {
return srs_error_wrap(err, "ffd seek");
}

// send data
if ((err = copy(w, fs, r, (int)left)) != srs_success) {
return srs_error_wrap(err, "read flv=%s size=%d", fullpath.c_str(), (int)left);
if ((err = copy(w, fs, r, left)) != srs_success) {
return srs_error_wrap(err, "read flv=%s size=%" PRId64, fullpath.c_str(), left);
}

return err;
}

srs_error_t SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int start, int end)
srs_error_t SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int64_t start, int64_t end)
{
srs_error_t err = srs_success;

srs_assert(start >= 0);
srs_assert(end == -1 || end >= 0);

SrsFileReader* fs = fs_factory->create_file_reader();
SrsAutoFree(SrsFileReader, fs);

// open flv file
if ((err = fs->open(fullpath)) != srs_success) {
return srs_error_wrap(err, "fs open");
}

// parse -1 to whole file.
if (end == -1) {
end = (int)(fs->filesize() - 1);
end = fs->filesize() - 1;
}

if (end > fs->filesize() || start > end || end < 0) {
return srs_error_new(ERROR_HTTP_REMUX_OFFSET_OVERFLOW, "http mp4 streaming %s overflow. size=%" PRId64 ", offset=%d",
fullpath.c_str(), fs->filesize(), start);
Expand All @@ -180,8 +180,8 @@ srs_error_t SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMe
fs->seek2(start);

// send data
if ((err = copy(w, fs, r, (int)left)) != srs_success) {
return srs_error_wrap(err, "read mp4=%s size=%d", fullpath.c_str(), (int)left);
if ((err = copy(w, fs, r, left)) != srs_success) {
return srs_error_wrap(err, "read mp4=%s size=%" PRId64, fullpath.c_str(), left);
}

return err;
Expand Down
12 changes: 6 additions & 6 deletions trunk/src/app/srs_app_http_static.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@

#include <srs_app_http_conn.hpp>

struct SrsM3u8CtxInfo
{
srs_utime_t request_time;
SrsRequest* req;
struct SrsM3u8CtxInfo
{
srs_utime_t request_time;
SrsRequest* req;
};

// The flv vod stream supports flv?start=offset-bytes.
Expand All @@ -30,8 +30,8 @@ class SrsVodStream : public SrsHttpFileServer, public ISrsFastTimer
SrsVodStream(std::string root_dir);
virtual ~SrsVodStream();
protected:
virtual srs_error_t serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int offset);
virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end);
virtual srs_error_t serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int64_t offset);
virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int64_t start, int64_t end);
virtual srs_error_t serve_m3u8_ctx(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
private:
virtual bool ctx_is_exist(std::string ctx);
Expand Down
56 changes: 28 additions & 28 deletions trunk/src/protocol/srs_http_stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,8 +456,8 @@ srs_error_t SrsHttpFileServer::serve_file(ISrsHttpResponseWriter* w, ISrsHttpMes

// write body.
int64_t left = length;
if ((err = copy(w, fs, r, (int)left)) != srs_success) {
return srs_error_wrap(err, "copy file=%s size=%d", fullpath.c_str(), (int)left);
if ((err = copy(w, fs, r, left)) != srs_success) {
return srs_error_wrap(err, "copy file=%s size=%" PRId64, fullpath.c_str(), left);
}

if ((err = w->final_request()) != srs_success) {
Expand All @@ -473,12 +473,12 @@ srs_error_t SrsHttpFileServer::serve_flv_file(ISrsHttpResponseWriter* w, ISrsHtt
if (start.empty()) {
return serve_file(w, r, fullpath);
}
int offset = ::atoi(start.c_str());

int64_t offset = ::atoll(start.c_str());
if (offset <= 0) {
return serve_file(w, r, fullpath);
}

return serve_flv_stream(w, r, fullpath, offset);
}

Expand All @@ -499,64 +499,64 @@ srs_error_t SrsHttpFileServer::serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHtt
range = range.substr(6);
}
}

// rollback to serve whole file.
size_t pos = string::npos;
if (range.empty() || (pos = range.find("-")) == string::npos) {
return serve_file(w, r, fullpath);
}

// parse the start in query string
int start = 0;
int64_t start = 0;
if (pos > 0) {
start = ::atoi(range.substr(0, pos).c_str());
start = ::atoll(range.substr(0, pos).c_str());
}

// parse end in query string.
int end = -1;
int64_t end = -1;
if (pos < range.length() - 1) {
end = ::atoi(range.substr(pos + 1).c_str());
end = ::atoll(range.substr(pos + 1).c_str());
}

// invalid param, serve as whole mp4 file.
if (start < 0 || (end != -1 && start > end)) {
return serve_file(w, r, fullpath);
}

return serve_mp4_stream(w, r, fullpath, start, end);
}

srs_error_t SrsHttpFileServer::serve_m3u8_file(ISrsHttpResponseWriter * w, ISrsHttpMessage * r, std::string fullpath)
}

srs_error_t SrsHttpFileServer::serve_m3u8_file(ISrsHttpResponseWriter * w, ISrsHttpMessage * r, std::string fullpath)
{
return serve_m3u8_ctx(w, r, fullpath);
return serve_m3u8_ctx(w, r, fullpath);
}

srs_error_t SrsHttpFileServer::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int offset)
srs_error_t SrsHttpFileServer::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int64_t offset)
{
// @remark For common http file server, we don't support stream request, please use SrsVodStream instead.
// TODO: FIXME: Support range in header https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Range_requests
return serve_file(w, r, fullpath);
}

srs_error_t SrsHttpFileServer::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int start, int end)
srs_error_t SrsHttpFileServer::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int64_t start, int64_t end)
{
// @remark For common http file server, we don't support stream request, please use SrsVodStream instead.
// TODO: FIXME: Support range in header https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Range_requests
return serve_file(w, r, fullpath);
}

srs_error_t SrsHttpFileServer::serve_m3u8_ctx(ISrsHttpResponseWriter * w, ISrsHttpMessage * r, std::string fullpath)
{
}

srs_error_t SrsHttpFileServer::serve_m3u8_ctx(ISrsHttpResponseWriter * w, ISrsHttpMessage * r, std::string fullpath)
{
// @remark For common http file server, we don't support stream request, please use SrsVodStream instead.
// TODO: FIXME: Support range in header https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Range_requests
return serve_file(w, r, fullpath);
return serve_file(w, r, fullpath);
}

srs_error_t SrsHttpFileServer::copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int size)
srs_error_t SrsHttpFileServer::copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int64_t size)
{
srs_error_t err = srs_success;

int left = size;
int64_t left = size;
char* buf = new char[SRS_HTTP_TS_SEND_BUFFER_SIZE];
SrsAutoFreeA(char, buf);

Expand All @@ -569,7 +569,7 @@ srs_error_t SrsHttpFileServer::copy(ISrsHttpResponseWriter* w, SrsFileReader* fs

left -= nread;
if ((err = w->write(buf, (int)nread)) != srs_success) {
return srs_error_wrap(err, "write limit=%d, bytes=%d, left=%d", max_read, (int)nread, left);
return srs_error_wrap(err, "write limit=%d, bytes=%d, left=%" PRId64, max_read, (int)nread, left);
}
}

Expand Down
6 changes: 3 additions & 3 deletions trunk/src/protocol/srs_http_stack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,12 @@ class SrsHttpFileServer : public ISrsHttpHandler
virtual srs_error_t serve_m3u8_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
protected:
// 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, int64_t offset);
// When access mp4 file with x.mp4?range=start-end
// @param start the start offset in bytes.
// @param end the end offset in bytes. -1 to end of file.
// @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, int64_t start, int64_t end);
// For HLS protocol.
// When the request url, like as "http://127.0.0.1:8080/live/livestream.m3u8",
// returns the response like as "http://127.0.0.1:8080/live/livestream.m3u8?hls_ctx=12345678" .
Expand All @@ -306,7 +306,7 @@ class SrsHttpFileServer : public ISrsHttpHandler
virtual srs_error_t serve_m3u8_ctx(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath);
protected:
// 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, int64_t size);
};

// The mux entry for server mux.
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/protocol/srs_service_http_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ srs_error_t SrsHttpResponseWriter::write(char* data, int size)
// check the bytes send and content length.
written += size;
if (content_length != -1 && written > content_length) {
return srs_error_new(ERROR_HTTP_CONTENT_LENGTH, "overflow writen=%d, max=%d", (int)written, (int)content_length);
return srs_error_new(ERROR_HTTP_CONTENT_LENGTH, "overflow writen=%" PRId64 ", max=%" PRId64, written, content_length);
}

// ignore NULL content.
Expand Down

0 comments on commit b9757c4

Please sign in to comment.