Added support for all common content-types into MHDFilestreamerHandler

File extension --> content-type associations are read from mime.types file.
This commit is contained in:
hunbernd 2015-11-06 22:05:35 +01:00
parent bdc70c6561
commit ce40760791
4 changed files with 96 additions and 4 deletions

View File

@ -7,6 +7,7 @@
#include <algorithm>
#include <util/rsdir.h>
#include "util/ContentTypes.h"
// for filestreamer
#include <retroshare/rsfiles.h>
@ -302,8 +303,13 @@ public:
struct MHD_Response* resp = MHD_create_response_from_callback(
mSize, 1024*1024, &contentReadercallback, this, NULL);
// only mp3 at the moment
MHD_add_response_header(resp, "Content-Type", "audio/mpeg3");
// get content-type from extension
std::string ext = "";
unsigned int i = info.fname.rfind('.');
if(i != std::string::npos)
ext = info.fname.substr(i+1);
MHD_add_response_header(resp, "Content-Type", ContentTypes::ContentTypes::cTypeFromExt(ext).c_str());
secure_queue_response(connection, MHD_HTTP_OK, resp);
MHD_destroy_response(resp);
return MHD_YES;

View File

@ -59,7 +59,8 @@ SOURCES += \
api/GetPluginInterfaces.cpp \
api/ChatHandler.cpp \
api/LivereloadHandler.cpp \
api/TmpBlobStore.cpp
api/TmpBlobStore.cpp \
util/ContentTypes.cpp
HEADERS += \
api/ApiServer.h \
@ -82,4 +83,5 @@ HEADERS += \
api/GetPluginInterfaces.h \
api/ChatHandler.h \
api/LivereloadHandler.h \
api/TmpBlobStore.h
api/TmpBlobStore.h \
util/ContentTypes.h

View File

@ -0,0 +1,63 @@
#include "ContentTypes.h"
#include <fstream>
RsMutex ContentTypes::ctmtx = RsMutex("CTMTX");
std::map<std::string, std::string> ContentTypes::cache;
#ifdef WINDOWS_SYS
//Next to the executable
const char* ContentTypes::filename = ".\\mime.types";
#else
const char* ContentTypes::filename = "/etc/mime.types";
#endif
std::string ContentTypes::cTypeFromExt(const std::string &extension)
{
if(extension.empty())
return DEFAULTCT;
RsStackMutex mtx(ctmtx);
//looking into the cache
std::map<std::string,std::string>::iterator it;
it = cache.find(extension);
if (it != cache.end())
{
std::cout << "Mime " + it->second + " for extension ." + extension + " was found in cache" << std::endl;
return it->second;
}
//looking into mime.types
std::string line;
std::string ext;
std::ifstream file(filename);
while(getline(file, line))
{
if(line.empty() || line[0] == '#') continue;
unsigned int i = line.find_first_of("\t ");
unsigned int j;
while(i != std::string::npos) //tokenize
{
j = i;
i = line.find_first_of("\t ", i+1);
if(i == std::string::npos)
ext = line.substr(j+1);
else
ext = line.substr(j+1, i-j-1);
if(extension == ext)
{
std::string mime = line.substr(0, line.find_first_of("\t "));
cache[extension] = mime;
std::cout << "Mime " + mime + " for extension ." + extension + " was found in mime.types" << std::endl;
return mime;
}
}
}
//nothing found
std::cout << "Mime for " + extension + " was not found in " + filename + " falling back to " << DEFAULTCT << std::endl;
cache[extension] = DEFAULTCT;
return DEFAULTCT;
}

View File

@ -0,0 +1,21 @@
#ifndef CONTENTTYPES_H
#define CONTENTTYPES_H
#include <util/rsthreads.h>
#include <map>
#include <string>
#define DEFAULTCT "application/octet-stream"
class ContentTypes
{
public:
static std::string cTypeFromExt(const std::string& extension);
private:
static std::map<std::string, std::string> cache;
static RsMutex ctmtx;
static const char* filename;
};
#endif // CONTENTTYPES_H