diff options
-rw-r--r-- | httptnt/resourceStreamer.ecpp | 86 | ||||
-rw-r--r-- | plugins/provider/recProvider/recProvider.cpp | 23 |
2 files changed, 60 insertions, 49 deletions
diff --git a/httptnt/resourceStreamer.ecpp b/httptnt/resourceStreamer.ecpp index 3ab17bd..67aa69a 100644 --- a/httptnt/resourceStreamer.ecpp +++ b/httptnt/resourceStreamer.ecpp @@ -37,6 +37,7 @@ int doRequest(tnt::HttpReply reply, tnt::HttpRequest request, std::string object int code = HTTP_OK; + //reply.setKeepAliveHeader(); reply.setContentType(streamer->GetContentType()); reply.setHeader("friendlyName.dlna.org ", server->GetServerDescription().friendlyName); reply.setHeader("contentFeatures.dlna.org ", streamer->GetContentFeatures()); @@ -44,7 +45,7 @@ int doRequest(tnt::HttpReply reply, tnt::HttpRequest request, std::string object if(streamer->GetContentLength() > 0){ reply.setContentLengthHeader(streamer->GetContentLength()); - if(streamer->Seekable()) reply.setHeader("Accept-Ranges", "bytes"); + if(streamer->Seekable()) reply.setHeader("Accept-Ranges ", "bytes"); } if(!request.isMethodHEAD()){ @@ -54,59 +55,68 @@ int doRequest(tnt::HttpReply reply, tnt::HttpRequest request, std::string object goto ret; } - int offset = 0, length = std::numeric_limits<long>::max(); + unsigned long offset = 0, length = streamer->GetContentLength(); + ssize_t bytesRead = 0; bool hasRange = false; - if(streamer->Seekable() && streamer->GetContentLength() > 0){ - if(request.hasHeader("Range")){ - std::string rangeRequest = request.getHeader("Range"); - if(rangeRequest.find("bytes=",0) == 0){ - int minus = rangeRequest.find_first_of('-',6); + if(request.hasHeader("Range:")){ + std::string rangeRequest = request.getHeader("Range:"); + if(rangeRequest.find("bytes=",0) == 0){ + unsigned int minus = rangeRequest.find_first_of('-',6); + if(minus != std::string::npos){ offset = atoi(rangeRequest.substr(6, minus - 6).c_str()); length = atoi(rangeRequest.substr(minus + 1).c_str()) - offset; - - if(length == 0) length = std::numeric_limits<long>::max(); - - hasRange = (offset == 0 && length == std::numeric_limits<long>::max()) ? false : true; + if(length == 0){ + length = streamer->GetContentLength() - offset; + } else { + if(length > MB(1)) + length = MB(1); + hasRange = true; + } } } + } + + if(hasRange && streamer->Seekable() && streamer->GetContentLength() > 0){ if(!streamer->Seek(offset, SEEK_SET)){ code = HTTP_INTERNAL_SERVER_ERROR; - goto ret; + goto close; } - } - char buffer[KB(16)]; - ssize_t bytesRead = 0; - size_t totalBytesRead = 0; - size_t toRead = std::min<size_t>(length, sizeof(buffer)); - while (0 < (bytesRead = streamer->Read(buffer, toRead)) && length > 0) { - reply.out().write(buffer, bytesRead); - if (!reply.out()) { - code = HTTP_GONE; - goto ret; + char buffer[length]; + if((bytesRead = streamer->Read(buffer, length)) > 0){ + std::stringstream ss; + ss << "bytes " << offset << "-" << offset + bytesRead << "/" << streamer->GetContentLength(); + reply.setHeader("Content-Range ", ss.str()); + reply.setContentLengthHeader(bytesRead); + code = HTTP_PARTIAL_CONTENT; + reply.out().write(buffer, bytesRead); + if (!reply.out()) { + code = HTTP_GONE; + goto close; + } + } + + } else { + reply.setDirectMode(); + char buffer[KB(20)]; + while ((bytesRead = streamer->Read(buffer, KB(20))) > 0) { + reply.out().write(buffer, bytesRead); + if (!reply.out()) { + code = HTTP_GONE; + goto close; + } } - length -= bytesRead; - totalBytesRead += bytesRead; - toRead = std::min<size_t>(length, sizeof(buffer)); - } - - reply.setContentLengthHeader(totalBytesRead); - - if ((bytesRead < 0 || length <= 0) && hasRange) { - std::stringstream ss; - ss << "bytes " << offset << "-" << offset + totalBytesRead << "/" << streamer->GetContentLength(); - reply.setHeader("Content-Range", ss.str()); - code = HTTP_PARTIAL_CONTENT; - goto ret; } - + } else { + goto ret; } - ret: + close: streamer->Close(); - //reply.out() << std::flush; + ret: + reply.out() << std::flush; return code; </%cpp> <# diff --git a/plugins/provider/recProvider/recProvider.cpp b/plugins/provider/recProvider/recProvider.cpp index 55d465c..c7e5b1e 100644 --- a/plugins/provider/recProvider/recProvider.cpp +++ b/plugins/provider/recProvider/recProvider.cpp @@ -57,25 +57,23 @@ private: } bool OpenFile(int i = 1){ - static int fileNumber = i; - - if(fileNumber != i && fileFD){ + if(currentFileNumber != i && fileFD){ CloseFile(); } char fileBuf[1024]; strncpy(fileBuf, filename.c_str(), 1024); char* pFileNumber = fileBuf + strlen(fileBuf); - sprintf(pFileNumber, "/%05d.ts", fileNumber); + sprintf(pFileNumber, "/%05d.ts", i); fileFD = fopen(fileBuf, "r"); if(!fileFD) return false; - currentFileNumber = i; + return true; } bool OpenNext(){ - return OpenFile(++currentFileNumber); + return OpenFile(currentFileNumber+1); } bool ScanFiles(){ @@ -93,6 +91,7 @@ public: RecProvider() : fileFD(NULL) , currentFileNumber(1) + , lastFileNumber(1) , offsets(65536) { } @@ -189,8 +188,12 @@ public: return true; } + virtual bool Seekable() const { + return true; + } + virtual bool Open(const string& uri){ - filename = uri.substr(6); + filename = string(VideoDirectory) + "/" + uri.substr(6); currentFileNumber = 1; return ScanFiles(); } @@ -198,13 +201,11 @@ public: virtual size_t Read(char* buf, size_t bufLen){ if(!fileFD) return -1; - char secondBuf[bufLen]; - size_t bytesRead = 0; - bytesRead += fread(secondBuf, 1, bufLen, fileFD); + bytesRead += fread(buf, 1, bufLen, fileFD); if(bytesRead != bufLen && OpenNext()){ - bytesRead += fread(secondBuf + bytesRead, 1, bufLen - bytesRead, fileFD); + bytesRead += fread(buf + bytesRead, 1, bufLen - bytesRead, fileFD); } return bytesRead; |