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