summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--httptnt/resourceStreamer.ecpp86
-rw-r--r--plugins/provider/recProvider/recProvider.cpp23
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;