added support for gzip compression
new config option: compression_encoding (integer) 1 - use deflate if available (or raw deflate for Internet Explorer) or don't compress 2 - use gzip if available or don't compress 10 - prefer deflate -- use deflate (or raw deflate for IE) if both deflate and gzip are available 20 - prefer gzip -- use gzip if both deflate and gzip are available default: 20 git-svn-id: svn://ttmath.org/publicrep/winix/trunk@727 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
110
core/app.cpp
110
core/app.cpp
@@ -2,7 +2,7 @@
|
||||
* This file is a part of Winix
|
||||
* and is not publicly distributed
|
||||
*
|
||||
* Copyright (c) 2010, Tomasz Sowa
|
||||
* Copyright (c) 2010-2011, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
@@ -385,7 +385,7 @@ void App::ReadRequest()
|
||||
|
||||
ReadGetPostVars();
|
||||
cookie_parser.Parse(cur.request->env_http_cookie, cur.request->cookie_tab);
|
||||
accept_encoding_parser.Parse(cur.request->env_http_accept_encoding);
|
||||
accept_encoding_parser.ParseAndLog(cur.request->env_http_accept_encoding);
|
||||
|
||||
CheckIE();
|
||||
CheckKonqueror();
|
||||
@@ -540,7 +540,7 @@ void App::PrepareSessionCookie()
|
||||
|
||||
|
||||
|
||||
void App::SendHeaders(bool compressing, Header header)
|
||||
void App::SendHeaders(bool compressing, int compress_encoding, Header header)
|
||||
{
|
||||
PrepareSessionCookie();
|
||||
|
||||
@@ -590,8 +590,13 @@ void App::SendHeaders(bool compressing, Header header)
|
||||
}
|
||||
}
|
||||
|
||||
if( compressing )
|
||||
FCGX_PutS("Content-Encoding: deflate\r\n", fcgi_request.out);
|
||||
if( compressing )
|
||||
{
|
||||
if( compress_encoding == 0 || compress_encoding == 1 )
|
||||
FCGX_PutS("Content-Encoding: deflate\r\n", fcgi_request.out);
|
||||
else
|
||||
FCGX_PutS("Content-Encoding: gzip\r\n", fcgi_request.out);
|
||||
}
|
||||
|
||||
FCGX_PutS(cur.request->headers.CStr(), fcgi_request.out);
|
||||
FCGX_PutS("\r\n", fcgi_request.out);
|
||||
@@ -610,14 +615,12 @@ void App::SetHtmlFilterConf()
|
||||
}
|
||||
|
||||
|
||||
// !! kopiowanie tych stringow bedzie zmienione
|
||||
// gdy bedziemy korzystac w przyszlosci z wlasnego stringstream
|
||||
void App::FilterCompressSend(bool compressing, const std::wstring & source_ref)
|
||||
void App::FilterCompressSend(bool compressing, int compress_encoding, const std::wstring & source_ref)
|
||||
{
|
||||
const std::wstring * source = &source_ref;
|
||||
|
||||
bool raw = cur.request->is_item && cur.request->item.content_type == Item::ct_raw && cur.request->status == WINIX_ERR_OK &&
|
||||
cur.request->function && (cur.request->function == &functions.fun_cat || cur.request->function == &functions.fun_run);
|
||||
cur.request->function && (cur.request->function == &functions.fun_cat || cur.request->function == &functions.fun_run);
|
||||
|
||||
if( config.html_filter && !raw )
|
||||
{
|
||||
@@ -633,32 +636,76 @@ void App::FilterCompressSend(bool compressing, const std::wstring & source_ref)
|
||||
source = &html_with_debug;
|
||||
}
|
||||
|
||||
|
||||
// !! zrobic z tym porzadek
|
||||
std::string temp;
|
||||
Ezc::WideToUTF8(*source, temp);
|
||||
if( config.utf8 )
|
||||
Ezc::WideToUTF8(*source, source_a);
|
||||
else
|
||||
AssignString(*source, source_a);
|
||||
|
||||
if( compressing )
|
||||
compress.CompressAndPut(temp.c_str(), temp.length(), fcgi_request.out);
|
||||
compress.CompressAndPut(source_a.c_str(), source_a.length(), fcgi_request.out, compress_encoding);
|
||||
else
|
||||
FCGX_PutS(temp.c_str(), fcgi_request.out);
|
||||
FCGX_PutS(source_a.c_str(), fcgi_request.out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool App::IsCompressionAllowed(const std::wstring & source)
|
||||
int App::SelectDeflateVersion()
|
||||
{
|
||||
return( config.compression &&
|
||||
cur.request->role == Request::responder &&
|
||||
cur.request->redirect_to.empty() &&
|
||||
cur.request->x_sendfile.empty() &&
|
||||
!cur.request->browser_msie &&
|
||||
!cur.request->browser_konqueror &&
|
||||
accept_encoding_parser.AcceptDeflate() &&
|
||||
source.size() >= (size_t)config.compression_page_min_size );
|
||||
if( cur.request->browser_msie )
|
||||
return 0; // raw deflate
|
||||
else
|
||||
return 1; // deflate
|
||||
}
|
||||
|
||||
|
||||
void App::SelectCompression(size_t source_len, bool & compression_allowed, int & compression_encoding)
|
||||
{
|
||||
compression_allowed = false;
|
||||
compression_encoding = 0;
|
||||
|
||||
if( config.compression &&
|
||||
cur.request->role == Request::responder &&
|
||||
cur.request->redirect_to.empty() &&
|
||||
cur.request->x_sendfile.empty() &&
|
||||
!cur.request->browser_konqueror && /* !! sprawdzic czy Konqueror bedzie obslugiwal raw deflate */
|
||||
source_len >= config.compression_page_min_size )
|
||||
{
|
||||
if( config.compression_encoding == 1 || config.compression_encoding == 10 )
|
||||
{
|
||||
if( accept_encoding_parser.AcceptDeflate() )
|
||||
{
|
||||
compression_allowed = true;
|
||||
compression_encoding = SelectDeflateVersion();
|
||||
}
|
||||
else
|
||||
if( config.compression_encoding == 10 && accept_encoding_parser.AcceptGzip() )
|
||||
{
|
||||
compression_allowed = true;
|
||||
compression_encoding = 2; // gzip
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( config.compression_encoding == 2 || config.compression_encoding == 20 )
|
||||
{
|
||||
if( accept_encoding_parser.AcceptGzip() )
|
||||
{
|
||||
compression_allowed = true;
|
||||
compression_encoding = 2; // gzip
|
||||
}
|
||||
else
|
||||
if( config.compression_encoding == 20 && accept_encoding_parser.AcceptDeflate() )
|
||||
{
|
||||
compression_allowed = true;
|
||||
compression_encoding = SelectDeflateVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool App::CanSendContent(Header header)
|
||||
{
|
||||
if( !cur.request->redirect_to.empty() || !cur.request->x_sendfile.empty() )
|
||||
@@ -698,9 +745,12 @@ void App::AddDebugInfo(std::wstring & out)
|
||||
void App::SendAnswer()
|
||||
{
|
||||
const std::wstring & source = cur.request->page.Str();
|
||||
Header header = h_200;
|
||||
bool compressing = IsCompressionAllowed(source);
|
||||
Error status = cur.request->status;
|
||||
Header header = h_200;
|
||||
Error status = cur.request->status;
|
||||
bool compressing;
|
||||
int compress_encoding;
|
||||
|
||||
SelectCompression(source.length(), compressing, compress_encoding);
|
||||
|
||||
if( status == WINIX_ERR_NO_ITEM || status == WINIX_ERR_NO_FUNCTION || status == WINIX_ERR_UNKNOWN_PARAM )
|
||||
header = h_404;
|
||||
@@ -708,12 +758,12 @@ Error status = cur.request->status;
|
||||
if( status == WINIX_ERR_PERMISSION_DENIED || status == WINIX_ERR_CANT_CHANGE_USER || status == WINIX_ERR_CANT_CHANGE_GROUP )
|
||||
header = h_403;
|
||||
|
||||
SendHeaders(compressing, header);
|
||||
SendHeaders(compressing, compress_encoding, header);
|
||||
|
||||
if( CanSendContent(header) )
|
||||
{
|
||||
// filtering (html), compressing (deflate) and sending back to the web browser
|
||||
FilterCompressSend(compressing, source);
|
||||
// filtering (html), compressing and sending back to the web browser
|
||||
FilterCompressSend(compressing, compress_encoding, source);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user