Merge pull request #16 from kiwix/kiwix-serve.bugfix

Kiwix serve.bugfix
This commit is contained in:
Matthieu Gautier 2017-03-20 11:05:21 +01:00 committed by GitHub
commit 25091c320b

View File

@ -49,6 +49,7 @@ extern "C" {
#include <getopt.h>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <iostream>
@ -120,12 +121,12 @@ static std::string getMimeTypeForFile(const std::string& filename) {
void introduceTaskbar(string &content, const string &humanReadableBookId) {
if (!nosearchbarFlag) {
content = appendToFirstOccurence(content, "<head>",
content = appendToFirstOccurence(content, "<head>",
replaceRegex(RESOURCE::include_html_part,
humanReadableBookId, "__CONTENT__"));
content = appendToFirstOccurence(content, "<head>", "<style>" +
RESOURCE::taskbar_css + "</style>");
content = appendToFirstOccurence(content, "<body[^>]*>",
content = appendToFirstOccurence(content, "<body[^>]*>",
replaceRegex(RESOURCE::taskbar_html_part,
humanReadableBookId, "__CONTENT__"));
}
@ -140,50 +141,47 @@ bool isVerbose() {
return value;
}
/* For compression */
#define COMPRESSOR_BUFFER_SIZE 10000000
static Bytef *compr = (Bytef *)malloc(COMPRESSOR_BUFFER_SIZE);
static uLongf comprLen;
static
bool compress_content(string &content,
const string &mimeType)
{
static std::vector<Bytef> compr_buffer;
/* Should be deflate */
bool deflated = mimeType.find("text/") != string::npos ||
mimeType.find("application/javascript") != string::npos ||
mimeType.find("application/json") != string::npos;
if ( ! deflated )
return false;
/* Compute the lengh */
unsigned int contentLength = content.size();
/* Should be deflate */
bool deflated =
contentLength > KIWIX_MIN_CONTENT_SIZE_TO_DEFLATE &&
contentLength < COMPRESSOR_BUFFER_SIZE &&
(mimeType.find("text/") != string::npos ||
mimeType.find("application/javascript") != string::npos ||
mimeType.find("application/json") != string::npos);
/* If the content is too short, no need to compress it */
if ( contentLength <= KIWIX_MIN_CONTENT_SIZE_TO_DEFLATE)
return false;
uLong bufferBound = compressBound(contentLength);
/* Compress the content if necessary */
if (deflated) {
pthread_mutex_lock(&compressorLock);
comprLen = COMPRESSOR_BUFFER_SIZE;
compress(compr, &comprLen, (const Bytef*)(content.data()), contentLength);
pthread_mutex_lock(&compressorLock);
compr_buffer.reserve(bufferBound);
uLongf comprLen = compr_buffer.capacity();
int err = compress(&compr_buffer[0], &comprLen, (const Bytef*)(content.data()), contentLength);
if (comprLen > 2 && comprLen < contentLength) {
/* /!\ Internet Explorer has a bug with deflate compression.
It can not handle the first two bytes (compression headers)
We need to chunk them off (move the content 2bytes)
It has no incidence on other browsers
See http://www.subbu.org/blog/2008/03/ie7-deflate-or-not and comments */
compr += 2;
content = string((char *)compr, comprLen);
contentLength = comprLen;
} else {
deflated = false;
}
pthread_mutex_unlock(&compressorLock);
if (err == Z_OK && comprLen > 2 && comprLen < (contentLength+2)) {
/* /!\ Internet Explorer has a bug with deflate compression.
It can not handle the first two bytes (compression headers)
We need to chunk them off (move the content 2bytes)
It has no incidence on other browsers
See http://www.subbu.org/blog/2008/03/ie7-deflate-or-not and comments */
content = string((char *)&compr_buffer[2], comprLen-2);
} else {
deflated = false;
}
pthread_mutex_unlock(&compressorLock);
return deflated;
}
@ -426,7 +424,6 @@ struct MHD_Response* handle_random(struct MHD_Connection * connection,
bool acceptEncodingDeflate)
{
std::string httpRedirection;
bool cacheEnabled = false;
httpResponseCode = MHD_HTTP_FOUND;
if (reader != NULL) {
pthread_mutex_lock(&readerLock);
@ -449,7 +446,6 @@ struct MHD_Response* handle_content(struct MHD_Connection * connection,
std::string baseUrl;
std::string content;
std::string mimeType;
unsigned int contentLength;
bool found = false;
zim::Article article;
@ -591,7 +587,7 @@ static int accessHandlerCallback(void *cls,
const char* acceptEncodingHeaderValue = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_ACCEPT_ENCODING);
const bool acceptEncodingDeflate = acceptEncodingHeaderValue && string(acceptEncodingHeaderValue).find("deflate") != string::npos;
/* Check if range is requested */
/* Check if range is requested. [TODO] Handle this somehow */
const char* acceptRangeHeaderValue = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_RANGE);
const bool acceptRange = acceptRangeHeaderValue != NULL;
@ -607,7 +603,7 @@ static int accessHandlerCallback(void *cls,
const char* tmpGetValue = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "content");
humanReadableBookId = (tmpGetValue != NULL ? string(tmpGetValue) : "");
} else {
humanReadableBookId = urlStr.substr(1, urlStr.find("/", 1) != string::npos ?
humanReadableBookId = urlStr.substr(1, urlStr.find("/", 1) != string::npos ?
urlStr.find("/", 1) - 1 : urlStr.size() - 2);
if (!humanReadableBookId.empty()) {
urlStr = urlStr.substr(urlStr.find("/", 1) != string::npos ?
@ -697,7 +693,7 @@ static int accessHandlerCallback(void *cls,
httpResponseCode,
response);
MHD_destroy_response(response);
return ret;
}
@ -792,7 +788,7 @@ int main(int argc, char **argv) {
if (libraryFlag) {
vector<string> libraryPaths = kiwix::split(libraryPath, ";");
vector<string>::iterator itr;
for ( itr = libraryPaths.begin(); itr != libraryPaths.end(); ++itr ) {
if (!itr->empty()) {
bool retVal = false;
@ -924,7 +920,7 @@ int main(int argc, char **argv) {
pthread_mutex_init(&compressorLock, NULL);
pthread_mutex_init(&verboseFlagLock, NULL);
pthread_mutex_init(&mimeTypeLock, NULL);
/* Hard coded mimetypes */
extMimeTypes["html"] = "text/html";
extMimeTypes["htm"] = "text/html";
@ -945,7 +941,7 @@ int main(int argc, char **argv) {
extMimeTypes["ttf"] = "application/font-ttf";
extMimeTypes["woff"] = "application/font-woff";
extMimeTypes["vtt"] = "text/vtt";
/* Start the HTTP daemon */
void *page = NULL;
if (interface.length() > 0) {
@ -956,7 +952,6 @@ int main(int argc, char **argv) {
struct sockaddr_in sockAddr;
struct ifaddrs *ifaddr, *ifa;
int family, n;
char host[NI_MAXHOST];
/* Search all available interfaces */
if (getifaddrs(&ifaddr) == -1) {