added: Request::header_in (Space) http input headers (without cookies)
added: config parameter: log_env_http_variables (bool) (for logging http headers) added: support for DELETE http method, added method FunctionBase::MakeDelete() changed: winix version incremented to 0.6.6 git-svn-id: svn://ttmath.org/publicrep/winix/trunk@1100 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
b01db89942
commit
ca14b1a427
|
@ -711,6 +711,22 @@ void App::LogEnvironmentVariables()
|
|||
}
|
||||
|
||||
|
||||
void App::LogEnvironmentHTTPVariables()
|
||||
{
|
||||
PT::Space::Table::iterator i = cur.request->headers_in.table.begin();
|
||||
|
||||
for( ; i != cur.request->headers_in.table.end() ; ++i)
|
||||
{
|
||||
log << log1 << "HTTP Env: " << i->first << "=";
|
||||
|
||||
if( i->second.size() == 1 )
|
||||
log << i->second[0] << logend;
|
||||
else
|
||||
log << "(incorrect value table size, should be one but is " << i->second.size() << ")" << logend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* reading the request (without GET parameters in the URL)
|
||||
|
@ -724,6 +740,7 @@ void App::ReadRequest()
|
|||
SetSubdomain();
|
||||
|
||||
LogAccess();
|
||||
ReadEnvHTTPVariables();
|
||||
|
||||
ReadPostVars();
|
||||
|
||||
|
@ -733,6 +750,9 @@ void App::ReadRequest()
|
|||
if( config.log_env_variables )
|
||||
LogEnvironmentVariables();
|
||||
|
||||
if( config.log_env_http_variables )
|
||||
LogEnvironmentHTTPVariables();
|
||||
|
||||
CheckIE();
|
||||
CheckKonqueror();
|
||||
|
||||
|
@ -759,17 +779,102 @@ void App::ReadEnvVariables()
|
|||
{
|
||||
SetEnv("REQUEST_METHOD", cur.request->env_request_method);
|
||||
SetEnv("REQUEST_URI", cur.request->env_request_uri);
|
||||
SetEnv("HTTP_COOKIE", cur.request->env_http_cookie);
|
||||
SetEnv("REMOTE_ADDR", cur.request->env_remote_addr);
|
||||
SetEnv("HTTP_HOST", cur.request->env_http_host);
|
||||
SetEnv("HTTP_USER_AGENT", cur.request->env_http_user_agent);
|
||||
SetEnv("FCGI_ROLE", cur.request->env_fcgi_role);
|
||||
SetEnv("CONTENT_TYPE", cur.request->env_content_type);
|
||||
SetEnv("HTTP_ACCEPT_ENCODING", cur.request->env_http_accept_encoding);
|
||||
SetEnv("HTTPS", cur.request->env_https);
|
||||
|
||||
SetEnv("HTTP_HOST", cur.request->env_http_host);
|
||||
SetEnv("HTTP_USER_AGENT", cur.request->env_http_user_agent);
|
||||
SetEnv("HTTP_COOKIE", cur.request->env_http_cookie);
|
||||
SetEnv("HTTP_ACCEPT_ENCODING", cur.request->env_http_accept_encoding);
|
||||
}
|
||||
|
||||
|
||||
// reading from fastcgi env
|
||||
void App::ReadEnvHTTPVariables()
|
||||
{
|
||||
const char http_prefix[] = "HTTP_";
|
||||
size_t http_prefix_len = sizeof(http_prefix) / sizeof(char) - 1; // 1 means terminating null character
|
||||
size_t http_headers_saved = 0;
|
||||
|
||||
for(char ** e = fcgi_request.envp ; *e && http_headers_saved < Request::MAX_INPUT_HEADERS ; ++e)
|
||||
{
|
||||
char * env = *e;
|
||||
|
||||
if( IsSubStringNoCasep("HTTP_", env) )
|
||||
{
|
||||
env += http_prefix_len;
|
||||
|
||||
// cookies we have in a different table
|
||||
if( !IsSubStringNoCasep("COOKIE=", env) )
|
||||
{
|
||||
if( SaveEnvHTTPVariable(env) )
|
||||
{
|
||||
http_headers_saved += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( http_headers_saved == Request::MAX_INPUT_HEADERS )
|
||||
{
|
||||
log << log4 << "App: the maximum number of HTTP headers has been reached, skipping the rest" << logend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* headers in fcgi are in the form of name=value
|
||||
*/
|
||||
bool App::SaveEnvHTTPVariable(const char * env)
|
||||
{
|
||||
// CHECK ME may move to a better place? Request::INPUT_HEADER_VALUE_MAX_LENGTH is a high value
|
||||
char header_name[Request::INPUT_HEADER_NAME_MAX_LENGTH + 1];
|
||||
char header_value[Request::INPUT_HEADER_VALUE_MAX_LENGTH + 1];
|
||||
|
||||
size_t i = 0;
|
||||
|
||||
for( ; env[i] != 0 && env[i] != '=' && i < Request::INPUT_HEADER_NAME_MAX_LENGTH ; ++i)
|
||||
{
|
||||
header_name[i] = ToSmall(env[i]);
|
||||
}
|
||||
|
||||
header_name[i] = 0;
|
||||
|
||||
if( env[i] != '=' )
|
||||
{
|
||||
// too long header name, skipping
|
||||
log << log4 << "App: skipped HTTP header \"" << env << "\" because the header name is too long" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
i += 1; // skipping '=' character
|
||||
size_t h = 0;
|
||||
|
||||
for( ; env[i] != 0 && h < Request::INPUT_HEADER_VALUE_MAX_LENGTH ; ++i, ++h)
|
||||
{
|
||||
header_value[h] = env[i];
|
||||
}
|
||||
|
||||
header_value[h] = 0;
|
||||
|
||||
if( env[i] != 0 )
|
||||
{
|
||||
// too long header value, skipping
|
||||
log << log4 << "App: skipped HTTP header \"" << env << "\" because the header value is too long" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
PT::UTF8ToWide(header_name, http_header);
|
||||
|
||||
std::wstring & inserted_header = cur.request->headers_in.Add(http_header, L"", true);
|
||||
PT::UTF8ToWide(header_value, inserted_header);
|
||||
http_header.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void App::ReadEnvRemoteIP()
|
||||
{
|
||||
|
@ -798,6 +903,9 @@ void App::CheckRequestMethod()
|
|||
else
|
||||
if( ToSmall(cur.request->env_request_method[0]) == 'h' )
|
||||
cur.request->method = Request::head;
|
||||
else
|
||||
if( ToSmall(cur.request->env_request_method[0]) == 'd' )
|
||||
cur.request->method = Request::delete_;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010-2014, Tomasz Sowa
|
||||
* Copyright (c) 2010-2018, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -156,6 +156,8 @@ private:
|
|||
std::string output_8bit;
|
||||
BinaryPage compressed_output;
|
||||
std::wstring cookie_id_string;
|
||||
std::wstring http_header;
|
||||
|
||||
|
||||
bool InitFCGI(char * sock, char * sock_user, char * sock_group);
|
||||
bool InitFCGIChmodChownSocket(char * sock, char * sock_user, char * sock_group);
|
||||
|
@ -182,9 +184,12 @@ private:
|
|||
void SendAnswer();
|
||||
|
||||
void LogEnvironmentVariables();
|
||||
void LogEnvironmentHTTPVariables();
|
||||
|
||||
void SetEnv(const char * name, std::wstring & env);
|
||||
void ReadEnvVariables();
|
||||
void ReadEnvHTTPVariables();
|
||||
bool SaveEnvHTTPVariable(const char * env);
|
||||
void ReadEnvRemoteIP();
|
||||
void ReadPostVars();
|
||||
|
||||
|
|
|
@ -147,6 +147,7 @@ void Config::AssignValues(bool stdout_is_closed)
|
|||
log_plugin_call = Bool(L"log_plugin_call", false);
|
||||
log_post_value_size = Size(L"log_post_value_size", 80);
|
||||
log_env_variables = Bool(L"log_env_variables", false);
|
||||
log_env_http_variables = Bool(L"log_env_http_variables", false);
|
||||
log_http_answer_headers = Bool(L"log_http_answer_headers", false);
|
||||
|
||||
post_file_max = Size(L"post_file_max", 8388608); // 8 MB
|
||||
|
|
|
@ -133,6 +133,9 @@ public:
|
|||
// log environment variables (fastcgi environment)
|
||||
bool log_env_variables;
|
||||
|
||||
// log environment http variables (only HTTP_* variables from fastcgi environment)
|
||||
bool log_env_http_variables;
|
||||
|
||||
// log headers (+cookies) which are returned to the client
|
||||
// this is what winix has generated -- the web server can change or add other headers
|
||||
// default: false
|
||||
|
|
|
@ -416,7 +416,7 @@ bool IsSubString(const StringType1 & short_str, const StringType2 & long_str)
|
|||
|
||||
|
||||
template<class StringType1, class StringType2>
|
||||
bool IsSubStringNoCase(const StringType1 * short_str, const StringType2 * long_str)
|
||||
bool IsSubStringNoCasep(const StringType1 * short_str, const StringType2 * long_str)
|
||||
{
|
||||
while( *short_str && *long_str && ToSmall(*short_str) == ToSmall(*long_str) )
|
||||
{
|
||||
|
@ -430,11 +430,17 @@ bool IsSubStringNoCase(const StringType1 * short_str, const StringType2 * long_s
|
|||
return false;
|
||||
}
|
||||
|
||||
template<class StringType1, class StringType2>
|
||||
bool IsSubStringNoCase(const StringType1 * short_str, const StringType2 * long_str)
|
||||
{
|
||||
return IsSubStringNoCasep(short_str, long_str);
|
||||
}
|
||||
|
||||
|
||||
template<class StringType1, class StringType2>
|
||||
bool IsSubStringNoCase(const StringType1 & short_str, const StringType2 & long_str)
|
||||
{
|
||||
return IsSubStringNoCase(short_str.c_str(), long_str.c_str());
|
||||
return IsSubStringNoCasep(short_str.c_str(), long_str.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -96,6 +96,8 @@ void Request::Clear()
|
|||
|
||||
method = unknown_method;
|
||||
|
||||
headers_in.Clear();
|
||||
|
||||
out_headers.Clear();
|
||||
out_cookies.Clear();
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2015, Tomasz Sowa
|
||||
* Copyright (c) 2008-2018, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -64,6 +64,16 @@ class FunctionBase;
|
|||
|
||||
struct Request
|
||||
{
|
||||
// how many input headers can be put to in_headers struct
|
||||
static const size_t MAX_INPUT_HEADERS = 32;
|
||||
|
||||
// how many characters there can be in one header name
|
||||
static const size_t INPUT_HEADER_NAME_MAX_LENGTH = 64;
|
||||
|
||||
// how many characters there can be in one header value
|
||||
static const size_t INPUT_HEADER_VALUE_MAX_LENGTH = 8192;
|
||||
|
||||
|
||||
/*
|
||||
request id
|
||||
is incremented for each request and is never 0
|
||||
|
@ -97,7 +107,7 @@ struct Request
|
|||
the HTTP method
|
||||
!! IMPROVE ME add the rest methods here
|
||||
*/
|
||||
enum Method { get, post, head, unknown_method } method;
|
||||
enum Method { get, post, head, delete_, unknown_method } method;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -116,6 +126,15 @@ struct Request
|
|||
PostFileTab post_file_tab;
|
||||
CookieTab cookie_tab;
|
||||
|
||||
// input headers (without cookies)
|
||||
// at the moment we are using FastCGI and HTTP headers are prefixed with 'HTTP_' string
|
||||
// so we drop the prefix and change all characters to small ones
|
||||
|
||||
// although https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 says that there can be more
|
||||
// than one http header with the same name we do not support it
|
||||
// each header has a different name here, cookies we have in a different container (cookie_tab)
|
||||
PT::Space headers_in;
|
||||
|
||||
|
||||
/*
|
||||
html anchor (those part of URI after '#' character)
|
||||
|
@ -209,7 +228,7 @@ struct Request
|
|||
// send as attachment (causes generating header: content-disposition: attachment)
|
||||
bool send_as_attachment;
|
||||
|
||||
// headers send to the client (without cookies)
|
||||
// headers send to the client (without cookies) (may change to headers_out?)
|
||||
PT::Space out_headers;
|
||||
|
||||
// cookies send to the client
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace Winix
|
|||
|
||||
#define WINIX_VER_MAJOR 0
|
||||
#define WINIX_VER_MINOR 6
|
||||
#define WINIX_VER_REVISION 5
|
||||
#define WINIX_VER_REVISION 6
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010-2016, Tomasz Sowa
|
||||
* Copyright (c) 2010-2018, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -136,6 +136,10 @@ void FunctionBase::MakeGet()
|
|||
// do nothing by default
|
||||
}
|
||||
|
||||
void FunctionBase::MakeDelete()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010-2016, Tomasz Sowa
|
||||
* Copyright (c) 2010-2018, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -84,6 +84,7 @@ public:
|
|||
virtual bool HasAccess();
|
||||
virtual void MakePost();
|
||||
virtual void MakeGet();
|
||||
virtual void MakeDelete();
|
||||
|
||||
void SetConfig(Config * pconfig);
|
||||
void SetCur(Cur * pcur);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010-2016, Tomasz Sowa
|
||||
* Copyright (c) 2010-2018, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -449,6 +449,12 @@ void Functions::MakeFunction()
|
|||
// we should make a page similar like in a GET request but the content should not be returned only
|
||||
}
|
||||
else
|
||||
if( cur->request->method == Request::delete_ )
|
||||
{
|
||||
if( cur->request->redirect_to.empty() )
|
||||
cur->request->function->MakeDelete();
|
||||
}
|
||||
else
|
||||
{
|
||||
log << log1 << "Functions: unknown request method (skipping)" << logend;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue