Main  /  Edit version 1  /  Edit version 2  /   /  Users Area

Difference "Serving Static Files" ver. 1 versus ver. 2

Content:

For serving static files the web server it the best option... :-)
<!--toc-->
However, cppcms can be used to serve static files so that the same permission logic can be used as other dynamic contents.
## Introduction
--------------------------------
For serving static files the web server it the best option, lighttpd, nginx or Apache would do much better job then you probably can.
However, cppcms can be used to serve static files so that the same permission logic can be used as other dynamic contents.
This is quite different. To handle this kind of situation
you should be aware of two very important factors:
When serving static files you should be aware of two very important factors:
1. Security
2. Performance
## Security
Let's start from the first. I assume you want to let user
to download certain files that you are controlling.
For url like
/some/files/[...] <- these are allows.
Things you DO NOT EVER-EVER-EVER do:
class my_server {
my_server(...)
{
...
dispatcher().assign("/some/files/(.*)",&my_server::serve_file,this,1)
}
void serve_file(std::string file_name)
{
std::ifstream f(("some_dir_name/" + file_name).c_str());
if(!f) {
response().status(404)
/some/files/[...] <- these are allowed
}
else {
response().content_type("application/octet-stream")
Things you should **never do:**
response().out() << f.rdbuf();
class my_server {
my_server(...)
{
dispatcher().assign("/some/files/(.*)",&my_server::serve_file,this,1)
}
void serve_file(std::string file_name)
{
std::ifstream f(("some_dir_name/" + file_name).c_str());
if(!f) {
response().status(404)
}
else {
response().content_type("application/octet-stream")
response().out() << f.rdbuf();
}
}
...
}
}
...
}
Because attacker cat create path
/some/files/../../../etc/some_secret.txt
Because attacker can create path
And read it...
/some/files/../../../etc/some_secret.txt
It would be VERY BAD.
And read it... It would be **very bad**.
If you want to serve a file create a very strict **WHITE** list
of allowed names like:
If you want to serve a file create a very strict **white** list of allowed names like:
/some/files/([a-z_0-9\.]\.txt)
/some/files/([a-z_0-9\.]+\.txt)
Or even better convert the name to sha1 representation and save
files using cryptographic hash.
Or even better convert the name to sha1 or md5 representation and save files using names generated
from their hash.
Like:
For example:
name = some_dir_per_user + "/" + cppcms::util::md5hex(file_name) + ".dat";
std::ifstream f(name.c_str());
## Performance
For small files (several K or even MB)
response().out() << f.rdbuf();
response().out() << f.rdbuf();
Is fine and works very well.
For the big files it is better to use headers like X-Send-File that are
supported by lighttpd, apache and nginx.
http://redmine.lighttpd.net/projects/1/wiki/X-LIGHTTPD-send-file
<http://redmine.lighttpd.net/projects/1/wiki/X-LIGHTTPD-send-file>
So instead of calling
response().content_type("application/octet-stream")
response().out() << f.rdbuf();
response().content_type("application/octet-stream")
response().out() << f.rdbuf();
You call:
response().content_type("application/octet-stream")
response().set_header("X-Lighttpd-Send-File",pysical_file_name);
response().content_type("application/octet-stream")
response().set_header("X-Lighttpd-Send-File",pysical_file_name);
This is specially critical for big files were the
server may for example save the entire FastCGI output
to temporary file and before serving it (Nginx) or
cache entire (huge) buffer in the memory (Lighttpd)
More then that X-SendFile usually much more effective as
it allows to the web server not to transfer buffers
to the memory.
`X-SendFile` usually much more effective than
serving files via FastCGI as it reduces the data transfer
over IPC and sometimes does not even copy file
data to the user space.
----------------

About

CppCMS is a web development framework for performance demanding applications.

Support This Project

SourceForge.net Logo

Поддержать проект

CppCMS needs You


Navigation

Main Page


Valid CSS | Valid XHTML 1.0