summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2013-09-16 00:02:21 +0200
committerDavid Kalnischkies <kalnischkies@gmail.com>2013-09-30 09:17:52 +0200
commit14c84d021d82335255275f1eabf3a856bde4df07 (patch)
tree68eb9d60ff3e8c5236e7e89a1fc1c5c8f7150bd8
parent6beca0eb8bfc105ba25e140e8ca4e07e78d097e7 (diff)
add Range and If-Range support in the webserver
Git-Dch: Ignore
-rw-r--r--test/interactive-helper/aptwebserver.cc64
1 files changed, 63 insertions, 1 deletions
diff --git a/test/interactive-helper/aptwebserver.cc b/test/interactive-helper/aptwebserver.cc
index 7134b37bc..4dae342dd 100644
--- a/test/interactive-helper/aptwebserver.cc
+++ b/test/interactive-helper/aptwebserver.cc
@@ -100,8 +100,13 @@ bool sendHead(int const client, int const httpcode, std::list<std::string> &head
std::string response("HTTP/1.1 ");
response.append(httpcodeToStr(httpcode));
headers.push_front(response);
+ _config->Set("APTWebserver::Last-Status-Code", httpcode);
- headers.push_back("Server: APT webserver");
+ std::stringstream buffer;
+ _config->Dump(buffer, "aptwebserver::response-header", "%t: %v%n", false);
+ std::vector<std::string> addheaders = VectorizeString(buffer.str(), '\n');
+ for (std::vector<std::string>::const_iterator h = addheaders.begin(); h != addheaders.end(); ++h)
+ headers.push_back(*h);
std::string date("Date: ");
date.append(TimeRFC1123(time(NULL)));
@@ -512,6 +517,9 @@ int main(int const argc, const char * argv[])
listen(sock, 1);
/*}}}*/
+ _config->CndSet("aptwebserver::response-header::Server", "APT webserver");
+ _config->CndSet("aptwebserver::response-header::Accept-Ranges", "bytes");
+
std::vector<std::string> messages;
int client;
while ((client = accept(sock, NULL, NULL)) != -1)
@@ -600,6 +608,60 @@ int main(int const argc, const char * argv[])
}
}
+ if (_config->FindB("aptwebserver::support::range", true) == true)
+ condition = LookupTag(*m, "Range", "");
+ else
+ condition.clear();
+ if (condition.empty() == false && strncmp(condition.c_str(), "bytes=", 6) == 0)
+ {
+ time_t cache;
+ std::string ifrange;
+ if (_config->FindB("aptwebserver::support::if-range", true) == true)
+ ifrange = LookupTag(*m, "If-Range", "");
+ bool validrange = (ifrange.empty() == true ||
+ (RFC1123StrToTime(ifrange.c_str(), cache) == true &&
+ cache <= data.ModificationTime()));
+
+ // FIXME: support multiple byte-ranges (APT clients do not do this)
+ if (condition.find(',') == std::string::npos)
+ {
+ size_t start = 6;
+ unsigned long long filestart = strtoull(condition.c_str() + start, NULL, 10);
+ // FIXME: no support for last-byte-pos being not the end of the file (APT clients do not do this)
+ size_t dash = condition.find('-') + 1;
+ unsigned long long fileend = strtoull(condition.c_str() + dash, NULL, 10);
+ unsigned long long filesize = data.FileSize();
+ if ((fileend == 0 || (fileend == filesize && fileend >= filestart)) &&
+ validrange == true)
+ {
+ if (filesize > filestart)
+ {
+ data.Skip(filestart);
+ std::ostringstream contentlength;
+ contentlength << "Content-Length: " << (filesize - filestart);
+ headers.push_back(contentlength.str());
+ std::ostringstream contentrange;
+ contentrange << "Content-Range: bytes " << filestart << "-"
+ << filesize - 1 << "/" << filesize;
+ headers.push_back(contentrange.str());
+ sendHead(client, 206, headers);
+ if (sendContent == true)
+ sendFile(client, data);
+ continue;
+ }
+ else
+ {
+ headers.push_back("Content-Length: 0");
+ std::ostringstream contentrange;
+ contentrange << "Content-Range: bytes */" << filesize;
+ headers.push_back(contentrange.str());
+ sendHead(client, 416, headers);
+ continue;
+ }
+ }
+ }
+ }
+
addFileHeaders(headers, data);
sendHead(client, 200, headers);
if (sendContent == true)