changed: when there is reqtype:json parameter and there is not set request.ajax_serializer

then we are using a generic json serializer
changed: we are sending the application/json header when returning an json string
added:   to config: log_server_answer (default false)
         when true we put the whole string (server's answer) to the log file
added:   to Request: use_200_status_for_not_found_and_permission_denied
         if this is true then if the server http code would be 403 or 404
         then we return 200 OK (useful when using ajax)
changed: System::RedirectTo() methods take as the last parameter: use_reqtype
         if this is true (default) then reqtype:type parameter is automatically added to the redirecting path
         




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@918 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2013-03-26 00:04:01 +00:00
parent be6e09c5af
commit 8d9a021eab
13 changed files with 152 additions and 65 deletions

View File

@ -2,7 +2,7 @@
* This file is a part of Winix * This file is a part of Winix
* and is not publicly distributed * and is not publicly distributed
* *
* Copyright (c) 2010-2012, Tomasz Sowa * Copyright (c) 2010-2013, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
*/ */
@ -438,6 +438,7 @@ bool sent = false;
if( cur.request->ajax_serializer ) if( cur.request->ajax_serializer )
{ {
log << log3 << "App: sending JSON" << logend;
std::wstring & ajax_content = cur.request->ajax.Add(L"content", L""); std::wstring & ajax_content = cur.request->ajax.Add(L"content", L"");
ajax_content = cur.request->page.Str(); ajax_content = cur.request->page.Str();
cur.request->ajax_serializer->Serialize(cur.request->ajax, cur.request->ajaxpage, true); cur.request->ajax_serializer->Serialize(cur.request->ajax, cur.request->ajaxpage, true);
@ -524,6 +525,13 @@ void App::Make()
return; return;
} }
if( !cur.request->ajax_serializer && cur.request->ParamValue(L"reqtype") == L"json")
{
log << log3 << "App: using generic JSON serializer" << logend;
ajax_generic_serializer.Clear();
cur.request->ajax_serializer = &ajax_generic_serializer;
}
plugin.Call(WINIX_CONTENT_MAKE); plugin.Call(WINIX_CONTENT_MAKE);
MakePage(); MakePage();
@ -801,21 +809,29 @@ void App::SendHeadersStatic()
} }
void App::SendHeaderContentType() void App::SendHeaderContentType()
{ {
switch( config.content_type_header ) if( cur.request->ajax_serializer )
{ {
case 1: FCGX_PutS("Content-Type: application/json", fcgi_request.out);
FCGX_PutS("Content-Type: application/xhtml+xml", fcgi_request.out); }
break; else
{
case 2: switch( config.content_type_header )
FCGX_PutS("Content-Type: application/xml", fcgi_request.out); {
break; case 1:
FCGX_PutS("Content-Type: application/xhtml+xml", fcgi_request.out);
break;
case 0: case 2:
default: FCGX_PutS("Content-Type: application/xml", fcgi_request.out);
FCGX_PutS("Content-Type: text/html", fcgi_request.out); break;
case 0:
default:
FCGX_PutS("Content-Type: text/html", fcgi_request.out);
}
} }
if( config.utf8 ) if( config.utf8 )
@ -830,7 +846,6 @@ void App::SendHeadersForbidden()
{ {
FCGX_PutS("Status: 403 Forbidden\r\n", fcgi_request.out); FCGX_PutS("Status: 403 Forbidden\r\n", fcgi_request.out);
SendHeaderContentType(); SendHeaderContentType();
log << log2 << "App: response: 403 Forbidden" << logend;
} }
@ -893,7 +908,6 @@ void App::SendHeadersNormal(Header header)
case h_404: case h_404:
FCGX_PutS("Status: 404 Not Found\r\n", fcgi_request.out); FCGX_PutS("Status: 404 Not Found\r\n", fcgi_request.out);
SendHeaderContentType(); SendHeaderContentType();
log << log2 << "App: response: 404 Not Found" << logend;
break; break;
case h_403: case h_403:
@ -971,6 +985,9 @@ void App::FilterCompressSend(bool compressing, int compress_encoding, const std:
else else
AssignString(*source, source_a); AssignString(*source, source_a);
if( config.log_server_answer )
log << log1 << "App: the server's answer is:\n" << source_a << "\nApp: end of the server's answer" << logend;
if( compressing ) if( compressing )
compress.CompressAndPut(source_a.c_str(), source_a.length(), fcgi_request.out, compress_encoding); compress.CompressAndPut(source_a.c_str(), source_a.length(), fcgi_request.out, compress_encoding);
else else
@ -1089,10 +1106,22 @@ int compress_encoding;
SelectCompression(source->length(), compressing, compress_encoding); SelectCompression(source->length(), compressing, compress_encoding);
if( status == WINIX_ERR_NO_ITEM || status == WINIX_ERR_NO_FUNCTION || status == WINIX_ERR_UNKNOWN_PARAM ) if( status == WINIX_ERR_NO_ITEM || status == WINIX_ERR_NO_FUNCTION || status == WINIX_ERR_UNKNOWN_PARAM )
{
header = h_404; header = h_404;
log << log2 << "App: http response: 404 Not Found" << logend;
}
if( status == WINIX_ERR_PERMISSION_DENIED || status == WINIX_ERR_CANT_CHANGE_USER || status == WINIX_ERR_CANT_CHANGE_GROUP ) if( status == WINIX_ERR_PERMISSION_DENIED || status == WINIX_ERR_CANT_CHANGE_USER || status == WINIX_ERR_CANT_CHANGE_GROUP )
{
header = h_403; header = h_403;
log << log2 << "App: http response: 403 Forbidden" << logend;
}
if( cur.request->use_200_status_for_not_found_and_permission_denied && (header == h_404 || header == h_403) )
{
log << log3 << "App: changing the http response to: 200 OK" << logend;
header = h_200;
}
SendHeaders(compressing, compress_encoding, header); SendHeaders(compressing, compress_encoding, header);
@ -1114,24 +1143,13 @@ void App::SendData(const BinaryPage & page, FCGX_Stream * out)
BinaryPage::const_iterator i = page.begin(); BinaryPage::const_iterator i = page.begin();
BinaryPage::const_iterator end = page.end(); BinaryPage::const_iterator end = page.end();
// log << log1 << "size: " << page.size() << logend;
// for(size_t x=0 ; x<page.size() ; ++x)
// log << int((unsigned char)page[x]) << ' ';
// log << logend;
while( i != end ) while( i != end )
{ {
size_t s = 0; size_t s = 0;
for( ; i != end && s < buf_size ; ++i, ++s) for( ; i != end && s < buf_size ; ++i, ++s)
{
send_data_buf[s] = *i; send_data_buf[s] = *i;
// log << "swinka: " << int((unsigned char)*i) << logend;
}
if( s > 0 ) if( s > 0 )
FCGX_PutStr(send_data_buf.c_str(), s, fcgi_request.out); FCGX_PutStr(send_data_buf.c_str(), s, fcgi_request.out);
} }

View File

@ -2,7 +2,7 @@
* This file is a part of Winix * This file is a part of Winix
* and is not publicly distributed * and is not publicly distributed
* *
* Copyright (c) 2010-2012, Tomasz Sowa * Copyright (c) 2010-2013, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
*/ */
@ -122,6 +122,7 @@ private:
std::string sendh_t, sendh_t2, sendh_t3; std::string sendh_t, sendh_t2, sendh_t3;
std::string sendfilea, sendfile2a; std::string sendfilea, sendfile2a;
std::string send_data_buf; std::string send_data_buf;
PT::SpaceToJSON ajax_generic_serializer;
bool CheckAccessFromPlugins(); bool CheckAccessFromPlugins();
void ProcessRequestThrow(); void ProcessRequestThrow();

View File

@ -2,7 +2,7 @@
* This file is a part of Winix * This file is a part of Winix
* and is not publicly distributed * and is not publicly distributed
* *
* Copyright (c) 2008-2012, Tomasz Sowa * Copyright (c) 2008-2013, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
*/ */
@ -113,6 +113,7 @@ void Config::AssignValues(bool stdout_is_closed)
log_request = Int(L"log_request", 1); log_request = Int(L"log_request", 1);
log_save_each_line = Bool(L"log_save_each_line", false); log_save_each_line = Bool(L"log_save_each_line", false);
log_time_zone_id = Size(L"log_time_zone_id", 34); log_time_zone_id = Size(L"log_time_zone_id", 34);
log_server_answer = Bool(L"log_server_answer", false);
log_stdout = Bool(L"log_stdout", false); log_stdout = Bool(L"log_stdout", false);
log_db_query = Bool(L"log_db_query", false); log_db_query = Bool(L"log_db_query", false);
log_plugin_call = Bool(L"log_plugin_call", false); log_plugin_call = Bool(L"log_plugin_call", false);

View File

@ -2,7 +2,7 @@
* This file is a part of Winix * This file is a part of Winix
* and is not publicly distributed * and is not publicly distributed
* *
* Copyright (c) 2008-2012, Tomasz Sowa * Copyright (c) 2008-2013, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
*/ */
@ -71,6 +71,10 @@ public:
// default: 34 (Coordinated Universal Time UTC+00:00) // default: 34 (Coordinated Universal Time UTC+00:00)
size_t log_time_zone_id; size_t log_time_zone_id;
// put to log what server is sending back to the client (html/json etc)
// default: false
bool log_server_answer;
// logging db queries // logging db queries
// default: false // default: false
bool log_db_query; bool log_db_query;

View File

@ -2,7 +2,7 @@
* This file is a part of Winix * This file is a part of Winix
* and is not publicly distributed * and is not publicly distributed
* *
* Copyright (c) 2008-2012, Tomasz Sowa * Copyright (c) 2008-2013, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
*/ */
@ -272,7 +272,24 @@ typename StringType::size_type i;
template<class StringType> template<class StringType>
void Trim(StringType & s, wchar_t c) void TrimFirst(StringType & s, wchar_t c)
{
typename StringType::size_type i;
if( s.empty() )
return;
// looking for the 'c' characters at the beginning
for(i=0 ; i<s.size() && s[i]==c ; ++i);
// deleting the 'c' characters at the beginning
if( i != 0 )
s.erase(0, i);
}
template<class StringType>
void TrimLast(StringType & s, wchar_t c)
{ {
typename StringType::size_type i; typename StringType::size_type i;
@ -292,16 +309,23 @@ typename StringType::size_type i;
// deleting 'c' characters at the end // deleting 'c' characters at the end
if( i != s.size() - 1 ) if( i != s.size() - 1 )
s.erase(i+1, StringType::npos); s.erase(i+1, StringType::npos);
// looking for the 'c' characters at the beginning
for(i=0 ; i<s.size() && s[i]==c ; ++i);
// deleting the 'c' characters at the beginning
if( i != 0 )
s.erase(0, i);
} }
template<class StringType>
void Trim(StringType & s, wchar_t c)
{
if( s.empty() )
return;
TrimLast(s, c);
TrimFirst(s, c);
}
template<class StringType> template<class StringType>
void MaxSize(StringType & str, size_t max_size) void MaxSize(StringType & str, size_t max_size)
{ {
@ -971,4 +995,7 @@ size_t i1, i2;
#endif #endif

View File

@ -2,7 +2,7 @@
* This file is a part of Winix * This file is a part of Winix
* and is not publicly distributed * and is not publicly distributed
* *
* Copyright (c) 2008-2012, Tomasz Sowa * Copyright (c) 2008-2013, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
*/ */
@ -129,6 +129,7 @@ void Request::Clear()
gen_use_special_chars = false; gen_use_special_chars = false;
ip = 0; ip = 0;
use_200_status_for_not_found_and_permission_denied = false;
} }

View File

@ -2,7 +2,7 @@
* This file is a part of Winix * This file is a part of Winix
* and is not publicly distributed * and is not publicly distributed
* *
* Copyright (c) 2008-2012, Tomasz Sowa * Copyright (c) 2008-2013, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
*/ */
@ -160,12 +160,17 @@ struct Request
// used as a JSON output (when ajax_serializer is defined) // used as a JSON output (when ajax_serializer is defined)
// it will be serialized and have at least: // it will be serialized and have at least:
// 'content' string - the whole html content // 'content' string - the whole html content
// 'http_status' integer - http status code (e.g. 200) // 'http_status' integer - http status code (e.g. 200) !! FIXME this is not added at the moment
PT::Space ajax; PT::Space ajax;
// if not null then the request will have a JSON as an output // if not null then the request will have a JSON as an output
PT::SpaceToJSON * ajax_serializer; PT::SpaceToJSON * ajax_serializer;
// if this variable is true then winix always return 200 OK header
// when the status would be 404 (not found) or 403 (permission denied)
// default: false
bool use_200_status_for_not_found_and_permission_denied;
// options used by ezc generators // options used by ezc generators
bool gen_trim_white; bool gen_trim_white;
bool gen_skip_new_line; bool gen_skip_new_line;

View File

@ -2,7 +2,7 @@
* This file is a part of Winix * This file is a part of Winix
* and is not publicly distributed * and is not publicly distributed
* *
* Copyright (c) 2008-2012, Tomasz Sowa * Copyright (c) 2008-2013, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
*/ */
@ -89,7 +89,7 @@ long id;
{ {
if( sizeof(long) == 8 ) if( sizeof(long) == 8 )
{ {
id = ((unsigned long)std::rand()) << 32 + std::rand(); id = (((unsigned long)std::rand()) << 32) + std::rand();
} }
else else
{ {

View File

@ -150,7 +150,7 @@ bool ssl = false;
/* /*
postfix will not be UrlEncoded postfix will not be UrlEncoded
*/ */
void System::RedirectTo(const Item & item, const wchar_t * postfix) void System::RedirectTo(const Item & item, const wchar_t * postfix, bool use_reqtype)
{ {
PutUrlProto(config->use_ssl, cur->request->redirect_to); PutUrlProto(config->use_ssl, cur->request->redirect_to);
@ -176,6 +176,12 @@ void System::RedirectTo(const Item & item, const wchar_t * postfix)
if( postfix ) if( postfix )
cur->request->redirect_to += postfix; cur->request->redirect_to += postfix;
if( use_reqtype && cur->request->IsParam(L"reqtype") )
{
cur->request->redirect_to += L"/-/reqtype:";
cur->request->redirect_to += cur->request->ParamValue(L"reqtype");
}
} }
@ -183,7 +189,7 @@ void System::RedirectTo(const Item & item, const wchar_t * postfix)
/* /*
postfix will not be UrlEncoded postfix will not be UrlEncoded
*/ */
void System::RedirectTo(long item_id, const wchar_t * postfix) void System::RedirectTo(long item_id, const wchar_t * postfix, bool use_reqtype)
{ {
PutUrlProto(config->use_ssl, cur->request->redirect_to); PutUrlProto(config->use_ssl, cur->request->redirect_to);
@ -224,6 +230,12 @@ void System::RedirectTo(long item_id, const wchar_t * postfix)
if( postfix ) if( postfix )
cur->request->redirect_to += postfix; cur->request->redirect_to += postfix;
if( use_reqtype && cur->request->IsParam(L"reqtype") )
{
cur->request->redirect_to += L"/-/reqtype:";
cur->request->redirect_to += cur->request->ParamValue(L"reqtype");
}
} }
@ -231,7 +243,7 @@ void System::RedirectTo(long item_id, const wchar_t * postfix)
/* /*
url will not be UrlEncoded url will not be UrlEncoded
*/ */
void System::RedirectTo(const wchar_t * url) void System::RedirectTo(const wchar_t * url, bool use_reqtype)
{ {
PutUrlProto(config->use_ssl, cur->request->redirect_to); PutUrlProto(config->use_ssl, cur->request->redirect_to);
@ -262,15 +274,21 @@ void System::RedirectTo(const wchar_t * url)
cur->request->redirect_to += url; cur->request->redirect_to += url;
} }
} }
if( use_reqtype && cur->request->IsParam(L"reqtype") )
{
cur->request->redirect_to += L"/-/reqtype:";
cur->request->redirect_to += cur->request->ParamValue(L"reqtype");
}
} }
/* /*
url will not be UrlEncoded url will not be UrlEncoded
*/ */
void System::RedirectTo(const std::wstring & url) void System::RedirectTo(const std::wstring & url, bool use_reqtype)
{ {
RedirectTo(url.c_str()); RedirectTo(url.c_str(), use_reqtype);
} }
@ -324,38 +342,52 @@ void System::RedirectWithFunctionAndParamsTo(const std::wstring & url)
} }
void System::RedirectToLastDir(const wchar_t * postfix) void System::RedirectToLastDir(const wchar_t * postfix, bool use_reqtype)
{ {
if( !cur->request->dir_tab.empty() ) if( !cur->request->dir_tab.empty() )
RedirectTo( *cur->request->dir_tab.back(), postfix ); RedirectTo( *cur->request->dir_tab.back(), postfix, use_reqtype);
} }
void System::RedirectToLastItem(const wchar_t * postfix) void System::RedirectToLastItem(const wchar_t * postfix, bool use_reqtype)
{ {
if( cur->request->last_item ) if( cur->request->last_item )
RedirectTo( *cur->request->last_item, postfix ); RedirectTo( *cur->request->last_item, postfix, use_reqtype );
} }
void System::RedirectToLastFunction(const wchar_t * postfix) void System::RedirectToLastFunction(const wchar_t * postfix, bool use_reqtype)
{ {
RedirectToLastDir(); RedirectToLastDir(0, false);
TrimLast(cur->request->redirect_to, '/');
if( cur->request->is_item ) if( cur->request->is_item )
{ {
cur->request->redirect_to += cur->request->item.url;
cur->request->redirect_to += '/'; cur->request->redirect_to += '/';
cur->request->redirect_to += cur->request->item.url;
} }
if( cur->request->function ) if( cur->request->function )
{
cur->request->redirect_to += '/';
cur->request->redirect_to += cur->request->function->fun.url; cur->request->redirect_to += cur->request->function->fun.url;
}
if( postfix ) if( postfix )
{ {
cur->request->redirect_to += '/'; cur->request->redirect_to += '/';
cur->request->redirect_to += postfix; cur->request->redirect_to += postfix;
} }
if( use_reqtype && cur->request->IsParam(L"reqtype") )
{
if( !cur->request->function && !postfix )
cur->request->redirect_to += L"/-";
cur->request->redirect_to += L"/reqtype:";
cur->request->redirect_to += cur->request->ParamValue(L"reqtype");
}
} }

View File

@ -90,15 +90,15 @@ public:
void AddParams(const ParamTab & param_tab, std::wstring & str, bool clear_str = true); void AddParams(const ParamTab & param_tab, std::wstring & str, bool clear_str = true);
void PutUrlProto(bool can_use_ssl, std::wstring & str, bool clear_str = true); void PutUrlProto(bool can_use_ssl, std::wstring & str, bool clear_str = true);
void RedirectTo(const Item & item, const wchar_t * postfix = 0); void RedirectTo(const Item & item, const wchar_t * postfix = 0, bool use_reqtype = true);
void RedirectTo(long item_id, const wchar_t * postfix = 0); void RedirectTo(long item_id, const wchar_t * postfix = 0, bool use_reqtype = true);
void RedirectTo(const wchar_t * url); void RedirectTo(const wchar_t * url, bool use_reqtype = true);
void RedirectTo(const std::wstring & url); void RedirectTo(const std::wstring & url, bool use_reqtype = true);
void RedirectWithFunctionAndParamsTo(const wchar_t * url); void RedirectWithFunctionAndParamsTo(const wchar_t * url);
void RedirectWithFunctionAndParamsTo(const std::wstring & url); void RedirectWithFunctionAndParamsTo(const std::wstring & url);
void RedirectToLastDir(const wchar_t * postfix = 0); void RedirectToLastDir(const wchar_t * postfix = 0, bool use_reqtype = true);
void RedirectToLastItem(const wchar_t * postfix = 0); // redirect to an item if exists or to the last directory void RedirectToLastItem(const wchar_t * postfix = 0, bool use_reqtype = true); // redirect to an item if exists or to the last directory
void RedirectToLastFunction(const wchar_t * postfix = 0); void RedirectToLastFunction(const wchar_t * postfix = 0, bool use_reqtype = true);
bool CanChangeUser(const Item & item, long new_user_id); bool CanChangeUser(const Item & item, long new_user_id);

View File

@ -2,7 +2,7 @@
* This file is a part of Winix * This file is a part of Winix
* and is not publicly distributed * and is not publicly distributed
* *
* Copyright (c) 2008-2012, Tomasz Sowa * Copyright (c) 2008-2013, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
*/ */
@ -13,7 +13,7 @@
#define WINIX_VER_MAJOR 0 #define WINIX_VER_MAJOR 0
#define WINIX_VER_MINOR 5 #define WINIX_VER_MINOR 5
#define WINIX_VER_REVISION 2 #define WINIX_VER_REVISION 3
#endif #endif

View File

@ -6,7 +6,6 @@
<head> <head>
<meta charset="{charset}"> <meta charset="{charset}">
<title>[doc_title]</title> <title>[doc_title]</title>
<link rel="stylesheet" href="[doc_base_url_common]/winix/winix.css">
[include "index_head_functions_add.html"] [include "index_head_functions_add.html"]
</head> </head>

View File

@ -6,7 +6,6 @@
<head> <head>
<meta charset="{charset}"> <meta charset="{charset}">
<title>[doc_title]</title> <title>[doc_title]</title>
<link rel="stylesheet" href="[doc_base_url_common]/winix/winix.css">
[include "index_head_functions_add.html"] [include "index_head_functions_add.html"]
</head> </head>