fixed: winix incorrectly sent the binary stream

headers and cookies were not sent
       (instead of headers the content was sent, so the client's browser was unable to open it correctly)
added: standard http headers are added by winix only if there are not such headers already
       e.g. if a plugin adds "Content-Type" header then winix will not overwrite it 
       (headers names are case sensitive)


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@945 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2013-12-19 17:19:47 +00:00
parent fe1f84e29d
commit 5d37b6c6ae
2 changed files with 101 additions and 40 deletions

View File

@ -780,6 +780,53 @@ void App::PrepareSessionCookie()
} }
bool App::AddHeader(const wchar_t * name, const wchar_t * value)
{
if( !cur.request->out_headers.GetValue(name) )
{
cur.request->out_headers.Add(name, value);
return true;
}
return false;
}
bool App::AddHeader(const std::wstring & name, const std::wstring & value)
{
if( !cur.request->out_headers.GetValue(name) )
{
cur.request->out_headers.Add(name, value);
return true;
}
return false;
}
bool App::AddHeader(const wchar_t * name, const PT::WTextStream & value)
{
if( !cur.request->out_headers.GetValue(name) )
{
cur.request->out_headers.Add(name, value);
return true;
}
return false;
}
bool App::AddHeader(const std::wstring & name, const PT::WTextStream & value)
{
if( !cur.request->out_headers.GetValue(name) )
{
cur.request->out_headers.Add(name, value);
return true;
}
return false;
}
bool App::PrepareHeadersStaticCreateResource(PT::WTextStream & out_path) bool App::PrepareHeadersStaticCreateResource(PT::WTextStream & out_path)
{ {
@ -837,48 +884,51 @@ void App::PrepareHeadersStatic()
return; return;
} }
cur.request->out_headers.Add(config.http_header_send_file, path); AddHeader(L"Status", L"200 OK");
cur.request->out_headers.Add(L"Status", L"200 OK");
log << log2 << "App: sending a file from a static mountpoint: " << path << logend;
}
if( AddHeader(config.http_header_send_file, path) )
log << log2 << "App: sending a file from a static mountpoint: " << path << logend;
}
void App::PrepareHeaderContentType() void App::PrepareHeaderContentType()
{ {
std::wstring * value = 0; std::wstring * value = 0;
if( cur.request->return_json ) if( !cur.request->out_headers.GetValue(L"Content-Type") )
{ {
value = &cur.request->out_headers.Add(L"Content-Type", L"application/json"); if( cur.request->return_json )
}
else
{
switch( config.content_type_header )
{ {
case 1: value = &cur.request->out_headers.Add(L"Content-Type", L"application/json");
value = &cur.request->out_headers.Add(L"Content-Type", L"application/xhtml+xml");
break;
case 2:
value = &cur.request->out_headers.Add(L"Content-Type", L"application/xml");
break;
case 0:
default:
value = &cur.request->out_headers.Add(L"Content-Type", L"text/html");
} }
} else
{
switch( config.content_type_header )
{
case 1:
value = &cur.request->out_headers.Add(L"Content-Type", L"application/xhtml+xml");
break;
case 2:
value = &cur.request->out_headers.Add(L"Content-Type", L"application/xml");
break;
if( value && config.utf8 ) case 0:
*value += L"; charset=UTF-8"; default:
value = &cur.request->out_headers.Add(L"Content-Type", L"text/html");
}
}
if( value && config.utf8 )
*value += L"; charset=UTF-8";
}
} }
void App::PrepareHeadersForbidden() void App::PrepareHeadersForbidden()
{ {
cur.request->out_headers.Add(L"Status", L"403 Forbidden"); AddHeader(L"Status", L"403 Forbidden");
PrepareHeaderContentType(); PrepareHeaderContentType();
} }
@ -888,47 +938,47 @@ void App::PrepareHeadersRedirect()
switch(cur.request->redirect_type) switch(cur.request->redirect_type)
{ {
case 300: case 300:
cur.request->out_headers.Add(L"Status", L"300 Multiple Choices"); AddHeader(L"Status", L"300 Multiple Choices");
break; break;
case 301: case 301:
cur.request->out_headers.Add(L"Status", L"301 Moved Permanently"); AddHeader(L"Status", L"301 Moved Permanently");
break; break;
case 302: case 302:
cur.request->out_headers.Add(L"Status", L"302 Found"); AddHeader(L"Status", L"302 Found");
break; break;
case 307: case 307:
cur.request->out_headers.Add(L"Status", L"307 Temporary Redirect"); AddHeader(L"Status", L"307 Temporary Redirect");
break; break;
case 303: case 303:
default: default:
cur.request->out_headers.Add(L"Status", L"303 See Other"); AddHeader(L"Status", L"303 See Other");
break; break;
} }
cur.request->out_headers.Add(L"Location", cur.request->redirect_to); AddHeader(L"Location", cur.request->redirect_to);
log << log2 << "App: redirect to: " << cur.request->redirect_to << logend; log << log2 << "App: redirect to: " << cur.request->redirect_to << logend;
} }
void App::PrepareHeadersSendFile() void App::PrepareHeadersSendFile()
{ {
cur.request->out_headers.Add(L"Status", L"200 OK"); AddHeader(L"Status", L"200 OK");
cur.request->out_headers.Add(config.http_header_send_file, cur.request->x_sendfile);
log << log2 << "App: sending file: " << cur.request->x_sendfile << logend; if( AddHeader(config.http_header_send_file, cur.request->x_sendfile) )
log << log2 << "App: sending file: " << cur.request->x_sendfile << logend;
} }
void App::PrepareHeadersCompression(int compress_encoding) void App::PrepareHeadersCompression(int compress_encoding)
{ {
if( compress_encoding == 0 || compress_encoding == 1 ) if( compress_encoding == 0 || compress_encoding == 1 )
cur.request->out_headers.Add(L"Content-Encoding", L"deflate"); AddHeader(L"Content-Encoding", L"deflate");
else else
cur.request->out_headers.Add(L"Content-Encoding", L"gzip"); AddHeader(L"Content-Encoding", L"gzip");
} }
@ -937,7 +987,7 @@ void App::PrepareHeadersNormal(Header header, size_t output_size)
switch( header ) switch( header )
{ {
case h_404: case h_404:
cur.request->out_headers.Add(L"Status", L"404 Not Found"); AddHeader(L"Status", L"404 Not Found");
PrepareHeaderContentType(); PrepareHeaderContentType();
break; break;
@ -946,12 +996,16 @@ void App::PrepareHeadersNormal(Header header, size_t output_size)
break; break;
default: default:
cur.request->out_headers.Add(L"Status", L"200 OK"); AddHeader(L"Status", L"200 OK");
PrepareHeaderContentType(); PrepareHeaderContentType();
} }
if( output_size != static_cast<size_t>(-1) ) if( output_size != static_cast<size_t>(-1) )
cur.request->out_headers.Add(L"Content-Length", output_size); {
PT::WTextStream buf;
buf << output_size;
AddHeader(L"Content-Length", buf);
}
} }
@ -1011,7 +1065,7 @@ void App::PrepareHeaders(bool compressing, int compress_encoding, Header header,
PrepareSessionCookie(); PrepareSessionCookie();
if( cur.request->send_as_attachment ) if( cur.request->send_as_attachment )
cur.request->out_headers.Add(L"Content-Disposition", L"attachment"); AddHeader(L"Content-Disposition", L"attachment");
if( !cur.request->redirect_to.empty() ) if( !cur.request->redirect_to.empty() )
{ {
@ -1287,6 +1341,9 @@ int compress_encoding;
// then winix would send an incorrect content-lenght header, // then winix would send an incorrect content-lenght header,
// we are waiting for the fsck winix function to be implemented // we are waiting for the fsck winix function to be implemented
PrepareHeaders(compressing, compress_encoding, header, static_cast<size_t>(-1)); PrepareHeaders(compressing, compress_encoding, header, static_cast<size_t>(-1));
SendHeaders();
SendCookies();
FCGX_PutS("\r\n", fcgi_request.out);
if( CanSendContent() ) if( CanSendContent() )
{ {

View File

@ -163,6 +163,10 @@ private:
void FilterContent(); void FilterContent();
void SendHeaders(); void SendHeaders();
void SendCookies(); void SendCookies();
bool AddHeader(const wchar_t * name, const wchar_t * value);
bool AddHeader(const std::wstring & name, const std::wstring & value);
bool AddHeader(const wchar_t * name, const PT::WTextStream & value);
bool AddHeader(const std::wstring & name, const PT::WTextStream & value);
bool PrepareHeadersStaticCreateResource(PT::WTextStream & out_path); bool PrepareHeadersStaticCreateResource(PT::WTextStream & out_path);
void PrepareHeadersStatic(); void PrepareHeadersStatic();
void PrepareHeaderContentType(); void PrepareHeaderContentType();