From 55ac9a61ed5f5e89940d390542f4f63f149ab47b Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 15 Sep 2021 20:28:34 +0200 Subject: [PATCH] added possibility to send static files to nginx via X-Accel-Redirect header added to config: int send_file_mode; // 0 - full path to a file in send_file_header header // 1 - relative path to a file in send_file_header (need http_send_file_relative_prefix set) (used for nginx) std::wstring send_file_header; // default: X-SENDFILE // for Apache set: X-SENDFILE // for Lighttpd set: X-LIGHTTPD-send-file // for Nginx set: X-Accel-Redirect std::wstring send_file_relative_prefix; // relative prefix used for sending static files if send_file_mode is 1 // default: "upload-files-internal" --- winixd/core/app.cpp | 8 ++++++-- winixd/core/config.cpp | 4 +++- winixd/core/config.h | 31 +++++++++++++++++++++++++++-- winixd/core/system.cpp | 37 +++++++++++++++++++++++++++++++++++ winixd/core/system.h | 2 ++ winixd/functions/download.cpp | 16 ++++++++++++--- 6 files changed, 90 insertions(+), 8 deletions(-) diff --git a/winixd/core/app.cpp b/winixd/core/app.cpp index 8727c04..1746a3b 100644 --- a/winixd/core/app.cpp +++ b/winixd/core/app.cpp @@ -1481,7 +1481,11 @@ void App::PrepareHeadersStatic() AddHeader(L"Status", L"200 OK"); - if( AddHeader(config.http_header_send_file, path) ) + /* + * FIX ME now we can send full path (apache, lighttpd) and relative path (nginx) + * but this feature for mounting static content probably will be removed + */ + if( AddHeader(config.send_file_header, path) ) log << log2 << "App: sending a file from a static mountpoint: " << path << logend; } @@ -1558,7 +1562,7 @@ void App::PrepareHeadersSendFile() { AddHeader(L"Status", L"200 OK"); - if( AddHeader(config.http_header_send_file, cur.request->x_sendfile) ) + if( AddHeader(config.send_file_header, cur.request->x_sendfile) ) log << log2 << "App: sending file: " << cur.request->x_sendfile << logend; } diff --git a/winixd/core/config.cpp b/winixd/core/config.cpp index 8a98b40..510d920 100644 --- a/winixd/core/config.cpp +++ b/winixd/core/config.cpp @@ -251,7 +251,9 @@ void Config::AssignValues(bool stdout_is_closed) title_separator = Text(L"title_separator", L" / "); - http_header_send_file = Text(L"http_header_send_file", L"X-LIGHTTPD-send-file"); + send_file_mode = Int(L"send_file_mode", 0); + send_file_header = Text(L"send_file_header", L"X-SENDFILE"); + send_file_relative_prefix = Text(L"send_file_relative_prefix", L"upload-files-internal"); editors_html_safe_mode = Bool(L"editors_html_safe_mode", true); editors_html_safe_mode_skip_root = Bool(L"editors_html_safe_mode_skip_root", true); diff --git a/winixd/core/config.h b/winixd/core/config.h index c2913dd..dcfbcc4 100644 --- a/winixd/core/config.h +++ b/winixd/core/config.h @@ -543,9 +543,36 @@ public: // separator used in html tag std::wstring title_separator; + // how to send static files (uploaded by users) to the webserver + // 0 - full path to a file in send_file_header header + // 1 - relative path to a file in send_file_header (need http_send_file_relative_prefix set) + // default: 0 + // for Apache set: 0 + // for Lighttpd set: 0 + // for Nginx set: 1 + int send_file_mode; + // http header recognized by www server as a file to send back - // default: X-LIGHTTPD-send-file - std::wstring http_header_send_file; + // default: X-SENDFILE + // for Apache set: X-SENDFILE + // for Lighttpd set: X-LIGHTTPD-send-file + // for Nginx set: X-Accel-Redirect + std::wstring send_file_header; + + // relative prefix used for sending static files if send_file_mode is 1 + // default: "upload-files-internal" + // this prefix is added at the beginning of a relative file path e.g. + // /upload-files-internal/simplefs/normal/some_directories/file.jpg + // + // in Nginx config file use 'location' with the prefix, e.g: + // server { + // ..... + // location /upload-files-internal/ { + // alias /path/to/winix/upload/; # trailing slash at the end + // internal; + // } + // } + std::wstring send_file_relative_prefix; // in editors (emacs, ckeditor,...) the html will be filtered and unsafe tags // will be dropped (script, frame, etc.) diff --git a/winixd/core/system.cpp b/winixd/core/system.cpp index 151672f..0b85360 100644 --- a/winixd/core/system.cpp +++ b/winixd/core/system.cpp @@ -971,6 +971,43 @@ return true; } +bool System::MakeRelativeFilePath(const Item & item, const std::wstring & path_prefix, std::wstring & path, bool thumb) +{ + path.clear(); + + if( item.item_content.file_path.empty() || item.item_content.file_type == WINIX_ITEM_FILETYPE_NONE ) + { + log << log1 << "System: MakePath: this item has not a static file" << logend; + return false; + } + + // we allow the prefix to be empty + if( !path_prefix.empty() ) + { + if( path_prefix[0] != '/' ) + path += '/'; + + path += path_prefix; + TrimLast(path, '/'); + } + + if( item.item_content.file_fs == mounts.MountFsHashfs() ) + path += L"/hashfs"; + else + path += L"/simplefs"; + + if( thumb ) + path += L"/thumb"; + else + path += L"/normal"; + + path += '/'; + path += item.item_content.file_path; + +return true; +} + + // item can be a directory, file or a symlink // if item is a directory then the path will be with a slash at the end bool System::MakePath(const Item & item, std::wstring & path, bool clear_path) diff --git a/winixd/core/system.h b/winixd/core/system.h index 3e9aedd..2b4e87b 100644 --- a/winixd/core/system.h +++ b/winixd/core/system.h @@ -178,6 +178,8 @@ public: bool CreateNewFile(Item & item); bool MakeFilePath(const Item & item, std::wstring & path, bool thumb = false, bool create_dir = false, int chmod = 0755, int group = -1); + bool MakeRelativeFilePath(const Item & item, const std::wstring & path_prefix, std::wstring & path, bool thumb = false); + bool MakePath(const Item & item, std::wstring & path, bool clear_path = true); bool AddFile(Item & item, int notify_code = 0, bool call_plugins = true); diff --git a/winixd/functions/download.cpp b/winixd/functions/download.cpp index c26014d..1c80f33 100644 --- a/winixd/functions/download.cpp +++ b/winixd/functions/download.cpp @@ -71,11 +71,21 @@ void Download::MakeGet() } cur->request->send_as_attachment = cur->request->IsParam(L"attachment"); + bool is_thumb = (cur->request->item.item_content.file_has_thumb && cur->request->IsParam(L"thumb")); - if( cur->request->item.item_content.file_has_thumb && cur->request->IsParam(L"thumb") ) - system->MakeFilePath(cur->request->item, cur->request->x_sendfile, true); + if( config->send_file_mode == 0 ) + { + system->MakeFilePath(cur->request->item, cur->request->x_sendfile, is_thumb); + } else - system->MakeFilePath(cur->request->item, cur->request->x_sendfile); + if( config->send_file_mode == 1 ) + { + system->MakeRelativeFilePath(cur->request->item, config->send_file_relative_prefix, cur->request->x_sendfile, is_thumb); + } + else + { + log << log1 << "Download: send_file_mode in the config should be either 0 or 1" << logend; + } }