mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2025-10-26 19:32:55 +00:00
Add support for simple web server
Update Docker README.
This commit is contained in:
@@ -7,7 +7,7 @@ For running this docker, simply use the following commands:
|
||||
# run the container detached, forward internal port 25500 to host port 25500
|
||||
docker run -d --restart=always -p 25500:25500 tindy2013/subconverter:latest
|
||||
# then check its status
|
||||
curl http://localhost:25500
|
||||
curl http://localhost:25500/version
|
||||
# if you see `subconverter vx.x.x backend` then the container is up and running
|
||||
```
|
||||
|
||||
@@ -37,6 +37,6 @@ docker build -t subconverter-custom:latest .
|
||||
# run the docker detached, forward internal port 25500 to host port 25500
|
||||
docker run -d --restart=always -p 25500:25500 subconverter-custom:latest
|
||||
# then check its status
|
||||
curl http://localhost:25500
|
||||
curl http://localhost:25500/version
|
||||
# if you see `subconverter vx.x.x backend` then the container is up and running
|
||||
```
|
||||
|
||||
@@ -126,6 +126,7 @@ aliases:
|
||||
server:
|
||||
listen: 0.0.0.0
|
||||
port: 25500
|
||||
serve_file_root: ""
|
||||
|
||||
advanced:
|
||||
log_level: info
|
||||
|
||||
@@ -251,6 +251,9 @@ listen=0.0.0.0
|
||||
;Port to bind on for Web Server
|
||||
port=25500
|
||||
|
||||
;Root folder for web server, keep empty to disable
|
||||
serve_file_root=
|
||||
|
||||
[advanced]
|
||||
log_level=info
|
||||
print_debug_info=false
|
||||
|
||||
@@ -37,6 +37,9 @@ extern int gLogLevel;
|
||||
extern long gMaxAllowedDownloadSize;
|
||||
string_map gAliases;
|
||||
|
||||
extern bool gServeFile;
|
||||
extern std::string gServeFileRoot;
|
||||
|
||||
//global variables for template
|
||||
std::string gTemplatePath = "templates";
|
||||
string_map gTemplateVars;
|
||||
@@ -837,6 +840,8 @@ void readYAMLConf(YAML::Node &node)
|
||||
{
|
||||
node["server"]["listen"] >> gListenAddress;
|
||||
node["server"]["port"] >> gListenPort;
|
||||
node["server"]["serve_file_root"] >>= gServeFileRoot;
|
||||
gServeFile = !gServeFileRoot.empty();
|
||||
}
|
||||
|
||||
if(node["advanced"].IsDefined())
|
||||
@@ -1088,6 +1093,8 @@ void readConf()
|
||||
ini.EnterSection("server");
|
||||
ini.GetIfExist("listen", gListenAddress);
|
||||
ini.GetIntIfExist("port", gListenPort);
|
||||
gServeFileRoot = ini.Get("serve_file_root");
|
||||
gServeFile = !gServeFileRoot.empty();
|
||||
|
||||
ini.EnterSection("advanced");
|
||||
std::string log_level;
|
||||
|
||||
@@ -143,10 +143,12 @@ int main(int argc, char *argv[])
|
||||
if(gGeneratorMode)
|
||||
return simpleGenerator();
|
||||
|
||||
/*
|
||||
append_response("GET", "/", "text/plain", [](RESPONSE_CALLBACK_ARGS) -> std::string
|
||||
{
|
||||
return "subconverter " VERSION " backend\n";
|
||||
});
|
||||
*/
|
||||
|
||||
append_response("GET", "/version", "text/plain", [](RESPONSE_CALLBACK_ARGS) -> std::string
|
||||
{
|
||||
|
||||
@@ -21,6 +21,72 @@
|
||||
extern std::string user_agent_str;
|
||||
std::atomic_bool SERVER_EXIT_FLAG(false);
|
||||
|
||||
// file server
|
||||
bool gServeFile = false;
|
||||
std::string gServeFileRoot;
|
||||
|
||||
struct MIME_type
|
||||
{
|
||||
std::string extension;
|
||||
std::string mimetype;
|
||||
};
|
||||
|
||||
MIME_type mime_types[] = {{"html htm shtml","text/html"},
|
||||
{"css", "text/css"},
|
||||
{"jpeg jpg", "image/jpeg"},
|
||||
{"js", "application/javascript"},
|
||||
{"txt", "text/plain"},
|
||||
{"png", "image/png"},
|
||||
{"ico", "image/x-icon"},
|
||||
{"svg svgz", "image/svg+xml"},
|
||||
{"woff", "application/font-woff"},
|
||||
{"json", "application/json"}};
|
||||
|
||||
bool matchSpaceSeparatedList(const std::string& source, const std::string &target)
|
||||
{
|
||||
string_size pos_begin = 0, pos_end, total = source.size();
|
||||
while(pos_begin < total)
|
||||
{
|
||||
pos_end = source.find(' ', pos_begin);
|
||||
if(pos_end == source.npos)
|
||||
pos_end = total;
|
||||
if(source.compare(pos_begin, pos_end - pos_begin, target) == 0)
|
||||
return true;
|
||||
pos_begin = pos_end + 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string checkMIMEType(const std::string filename)
|
||||
{
|
||||
string_size name_begin = 0, name_end = 0;
|
||||
name_begin = filename.rfind('/');
|
||||
if(name_begin == filename.npos)
|
||||
name_begin = 0;
|
||||
name_end = filename.rfind('.');
|
||||
if(name_end == filename.npos || name_end < name_begin || name_end == filename.size() - 1)
|
||||
return "application/octet-stream";
|
||||
std::string extension = filename.substr(name_end + 1);
|
||||
for(MIME_type &x : mime_types)
|
||||
if(matchSpaceSeparatedList(x.extension, extension))
|
||||
return x.mimetype;
|
||||
return "application/octet-stream";
|
||||
}
|
||||
|
||||
int serveFile(const std::string &filename, std::string &content_type, std::string &return_data)
|
||||
{
|
||||
std::string realname = gServeFileRoot + filename;
|
||||
if(filename.compare("/") == 0)
|
||||
realname += "index.html";
|
||||
if(!fileExist(realname))
|
||||
return 1;
|
||||
|
||||
return_data = fileGet(realname, false);
|
||||
content_type = checkMIMEType(realname);
|
||||
writeLog(0, "file-server: serving '" + filename + "' type '" + content_type + "'", LOG_LEVEL_INFO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct responseRoute
|
||||
{
|
||||
std::string method;
|
||||
@@ -83,6 +149,12 @@ static inline int process_request(Request &request, Response &response, std::str
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(gServeFile)
|
||||
{
|
||||
if(request.method.compare("GET") == 0 && serveFile(request.url, response.content_type, return_data) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user