From 8d9a021eab1ceded2c54f98c4dbd65a1b555546b Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 26 Mar 2013 00:04:01 +0000 Subject: [PATCH] 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 --- core/app.cpp | 68 ++++++++++++++++++++++++-------------- core/app.h | 3 +- core/config.cpp | 3 +- core/config.h | 6 +++- core/misc.h | 45 ++++++++++++++++++++----- core/request.cpp | 3 +- core/request.h | 9 +++-- core/sessionmanager.cpp | 4 +-- core/system.cpp | 56 ++++++++++++++++++++++++------- core/system.h | 14 ++++---- core/version.h | 4 +-- html/index.html | 1 - html/index_fullscreen.html | 1 - 13 files changed, 152 insertions(+), 65 deletions(-) diff --git a/core/app.cpp b/core/app.cpp index 8463971..090946c 100755 --- a/core/app.cpp +++ b/core/app.cpp @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2010-2012, Tomasz Sowa + * Copyright (c) 2010-2013, Tomasz Sowa * All rights reserved. * */ @@ -438,6 +438,7 @@ bool sent = false; if( cur.request->ajax_serializer ) { + log << log3 << "App: sending JSON" << logend; std::wstring & ajax_content = cur.request->ajax.Add(L"content", L""); ajax_content = cur.request->page.Str(); cur.request->ajax_serializer->Serialize(cur.request->ajax, cur.request->ajaxpage, true); @@ -524,6 +525,13 @@ void App::Make() 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); MakePage(); @@ -801,21 +809,29 @@ void App::SendHeadersStatic() } + void App::SendHeaderContentType() { - switch( config.content_type_header ) + if( cur.request->ajax_serializer ) { - case 1: - FCGX_PutS("Content-Type: application/xhtml+xml", fcgi_request.out); - break; - - case 2: - FCGX_PutS("Content-Type: application/xml", fcgi_request.out); - break; + FCGX_PutS("Content-Type: application/json", fcgi_request.out); + } + else + { + switch( config.content_type_header ) + { + case 1: + FCGX_PutS("Content-Type: application/xhtml+xml", fcgi_request.out); + break; - case 0: - default: - FCGX_PutS("Content-Type: text/html", fcgi_request.out); + case 2: + FCGX_PutS("Content-Type: application/xml", fcgi_request.out); + break; + + case 0: + default: + FCGX_PutS("Content-Type: text/html", fcgi_request.out); + } } if( config.utf8 ) @@ -830,7 +846,6 @@ void App::SendHeadersForbidden() { FCGX_PutS("Status: 403 Forbidden\r\n", fcgi_request.out); SendHeaderContentType(); - log << log2 << "App: response: 403 Forbidden" << logend; } @@ -893,7 +908,6 @@ void App::SendHeadersNormal(Header header) case h_404: FCGX_PutS("Status: 404 Not Found\r\n", fcgi_request.out); SendHeaderContentType(); - log << log2 << "App: response: 404 Not Found" << logend; break; case h_403: @@ -971,6 +985,9 @@ void App::FilterCompressSend(bool compressing, int compress_encoding, const std: else 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 ) compress.CompressAndPut(source_a.c_str(), source_a.length(), fcgi_request.out, compress_encoding); else @@ -1089,10 +1106,22 @@ 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; + 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 ) + { 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); @@ -1114,24 +1143,13 @@ void App::SendData(const BinaryPage & page, FCGX_Stream * out) BinaryPage::const_iterator i = page.begin(); BinaryPage::const_iterator end = page.end(); -// log << log1 << "size: " << page.size() << logend; - -// for(size_t x=0 ; x 0 ) FCGX_PutStr(send_data_buf.c_str(), s, fcgi_request.out); } diff --git a/core/app.h b/core/app.h index 09c1cdd..5bc07f7 100755 --- a/core/app.h +++ b/core/app.h @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2010-2012, Tomasz Sowa + * Copyright (c) 2010-2013, Tomasz Sowa * All rights reserved. * */ @@ -122,6 +122,7 @@ private: std::string sendh_t, sendh_t2, sendh_t3; std::string sendfilea, sendfile2a; std::string send_data_buf; + PT::SpaceToJSON ajax_generic_serializer; bool CheckAccessFromPlugins(); void ProcessRequestThrow(); diff --git a/core/config.cpp b/core/config.cpp index 3873706..9ae92e6 100755 --- a/core/config.cpp +++ b/core/config.cpp @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2008-2012, Tomasz Sowa + * Copyright (c) 2008-2013, Tomasz Sowa * All rights reserved. * */ @@ -113,6 +113,7 @@ void Config::AssignValues(bool stdout_is_closed) log_request = Int(L"log_request", 1); log_save_each_line = Bool(L"log_save_each_line", false); 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_db_query = Bool(L"log_db_query", false); log_plugin_call = Bool(L"log_plugin_call", false); diff --git a/core/config.h b/core/config.h index 913f5ac..0d53424 100755 --- a/core/config.h +++ b/core/config.h @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2008-2012, Tomasz Sowa + * Copyright (c) 2008-2013, Tomasz Sowa * All rights reserved. * */ @@ -71,6 +71,10 @@ public: // default: 34 (Coordinated Universal Time UTC+00:00) 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 // default: false bool log_db_query; diff --git a/core/misc.h b/core/misc.h index ccf2cac..5203e6f 100755 --- a/core/misc.h +++ b/core/misc.h @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2008-2012, Tomasz Sowa + * Copyright (c) 2008-2013, Tomasz Sowa * All rights reserved. * */ @@ -272,7 +272,24 @@ typename StringType::size_type i; template -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 +void TrimLast(StringType & s, wchar_t c) { typename StringType::size_type i; @@ -292,16 +309,23 @@ typename StringType::size_type i; // deleting 'c' characters at the end if( i != s.size() - 1 ) s.erase(i+1, StringType::npos); - - // looking for the 'c' characters at the beginning - for(i=0 ; i +void Trim(StringType & s, wchar_t c) +{ + if( s.empty() ) + return; + + TrimLast(s, c); + TrimFirst(s, c); +} + + + + template void MaxSize(StringType & str, size_t max_size) { @@ -971,4 +995,7 @@ size_t i1, i2; + + + #endif diff --git a/core/request.cpp b/core/request.cpp index 8ecd510..67a49a3 100755 --- a/core/request.cpp +++ b/core/request.cpp @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2008-2012, Tomasz Sowa + * Copyright (c) 2008-2013, Tomasz Sowa * All rights reserved. * */ @@ -129,6 +129,7 @@ void Request::Clear() gen_use_special_chars = false; ip = 0; + use_200_status_for_not_found_and_permission_denied = false; } diff --git a/core/request.h b/core/request.h index e02bbc9..eb989aa 100755 --- a/core/request.h +++ b/core/request.h @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2008-2012, Tomasz Sowa + * Copyright (c) 2008-2013, Tomasz Sowa * All rights reserved. * */ @@ -160,12 +160,17 @@ struct Request // used as a JSON output (when ajax_serializer is defined) // it will be serialized and have at least: // '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; // if not null then the request will have a JSON as an output 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 bool gen_trim_white; bool gen_skip_new_line; diff --git a/core/sessionmanager.cpp b/core/sessionmanager.cpp index 127406d..92e9f7a 100755 --- a/core/sessionmanager.cpp +++ b/core/sessionmanager.cpp @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2008-2012, Tomasz Sowa + * Copyright (c) 2008-2013, Tomasz Sowa * All rights reserved. * */ @@ -89,7 +89,7 @@ long id; { if( sizeof(long) == 8 ) { - id = ((unsigned long)std::rand()) << 32 + std::rand(); + id = (((unsigned long)std::rand()) << 32) + std::rand(); } else { diff --git a/core/system.cpp b/core/system.cpp index f1d552a..e073aa7 100755 --- a/core/system.cpp +++ b/core/system.cpp @@ -150,7 +150,7 @@ bool ssl = false; /* 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); @@ -176,6 +176,12 @@ void System::RedirectTo(const Item & item, const wchar_t * postfix) if( 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 */ -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); @@ -224,6 +230,12 @@ void System::RedirectTo(long item_id, const wchar_t * postfix) if( 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 */ -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); @@ -262,15 +274,21 @@ void System::RedirectTo(const wchar_t * 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 */ -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() ) - 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 ) - 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 ) { - cur->request->redirect_to += cur->request->item.url; cur->request->redirect_to += '/'; + cur->request->redirect_to += cur->request->item.url; } if( cur->request->function ) + { + cur->request->redirect_to += '/'; cur->request->redirect_to += cur->request->function->fun.url; + } if( postfix ) { cur->request->redirect_to += '/'; 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"); + } + } diff --git a/core/system.h b/core/system.h index e855dd8..eb0d84c 100755 --- a/core/system.h +++ b/core/system.h @@ -90,15 +90,15 @@ public: 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 RedirectTo(const Item & item, const wchar_t * postfix = 0); - void RedirectTo(long item_id, const wchar_t * postfix = 0); - void RedirectTo(const wchar_t * url); - void RedirectTo(const std::wstring & url); + void RedirectTo(const Item & item, const wchar_t * postfix = 0, bool use_reqtype = true); + void RedirectTo(long item_id, const wchar_t * postfix = 0, bool use_reqtype = true); + void RedirectTo(const wchar_t * url, bool use_reqtype = true); + void RedirectTo(const std::wstring & url, bool use_reqtype = true); void RedirectWithFunctionAndParamsTo(const wchar_t * url); void RedirectWithFunctionAndParamsTo(const std::wstring & url); - void RedirectToLastDir(const wchar_t * postfix = 0); - void RedirectToLastItem(const wchar_t * postfix = 0); // redirect to an item if exists or to the last directory - void RedirectToLastFunction(const wchar_t * postfix = 0); + void RedirectToLastDir(const wchar_t * postfix = 0, bool use_reqtype = true); + 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, bool use_reqtype = true); bool CanChangeUser(const Item & item, long new_user_id); diff --git a/core/version.h b/core/version.h index 6af559d..61bbeca 100755 --- a/core/version.h +++ b/core/version.h @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2008-2012, Tomasz Sowa + * Copyright (c) 2008-2013, Tomasz Sowa * All rights reserved. * */ @@ -13,7 +13,7 @@ #define WINIX_VER_MAJOR 0 #define WINIX_VER_MINOR 5 -#define WINIX_VER_REVISION 2 +#define WINIX_VER_REVISION 3 #endif diff --git a/html/index.html b/html/index.html index 69738bb..04d186b 100755 --- a/html/index.html +++ b/html/index.html @@ -6,7 +6,6 @@ [doc_title] - [include "index_head_functions_add.html"] diff --git a/html/index_fullscreen.html b/html/index_fullscreen.html index 69738bb..04d186b 100755 --- a/html/index_fullscreen.html +++ b/html/index_fullscreen.html @@ -6,7 +6,6 @@ [doc_title] - [include "index_head_functions_add.html"]