From 3af3ac3f6f96035f39c6360409d3f73000757563 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Thu, 14 Nov 2013 20:59:23 +0000 Subject: [PATCH] removed: ezn patterns for rawcontent and ajaxcontent: index_rawcontent.html, index_ajaxcontent.html now we have out_streams in Request and some special keyword in ezc templates for sending content to the specified streams changed: the way how winix answers to the client's browsers: info from Request class: winix answer send to the client's browser | | depending on send_bin_stream ------------------------------------------------- | | text answer binary answer | | depending on return_json sending out_bin_stream ------------------------------------ | | normal request ajax request | | sending out_streams[0] depending on return_info_only ------------------------------------------------------ | | generating JSON object from: generating JSON object only from info out_streams and info, e.g.: e.g.: { { info object serialized here } "stream_1": "some html content", "stream_2": "some other html content", "info": { info object serialized here } } note that out_streams[0] is not sent in JSON answers git-svn-id: svn://ttmath.org/publicrep/winix/trunk@937 e52654a7-88a9-db11-a3e9-0013d4bc506e --- core/app.cpp | 92 ++++++++++++++++++++-------- core/app.h | 6 +- core/misc.h | 30 +++++++++ core/request.cpp | 47 +++++---------- core/request.h | 117 +++++++++++++++++++++++++++++------- core/system.cpp | 26 +++++++- core/system.h | 9 ++- core/version.h | 2 +- functions/rm.cpp | 4 +- functions/upload.cpp | 47 ++++++++++++--- functions/upload.h | 13 +++- html/index_ajaxcontent.html | 1 - html/index_rawcontent.html | 1 - templates/templates.cpp | 21 +++---- templates/templates.h | 2 - 15 files changed, 303 insertions(+), 115 deletions(-) delete mode 100755 html/index_ajaxcontent.html delete mode 100755 html/index_rawcontent.html diff --git a/core/app.cpp b/core/app.cpp index 090946c..57cb752 100755 --- a/core/app.cpp +++ b/core/app.cpp @@ -316,7 +316,8 @@ void App::ProcessRequestThrow() } plugin.Call(WINIX_SESSION_CHANGED); - functions.Parse(); // parsing directories,files,functions and parameters + functions.Parse(); // parsing directories,files,functions and parameters + cur.mount = system.mounts.CalcCurMount(); if( cur.mount->type != system.mounts.MountTypeStatic() ) @@ -400,13 +401,51 @@ void App::SaveSessionsIfNeeded() +void App::CreateJSONAnswer() +{ + Request & req = *cur.request; + json_out_stream.Clear(); + + if( !req.return_info_only ) + { + json_out_stream << L"{\n"; + + for(size_t i=1 ; iSerialize(req.info, json_out_stream, true); + } + else + { + json_out_stream << L"{}"; + log << log1 << "App: Request::info_serializer not defined" << logend; + } + + log << log3 << "App: sending JSON answer"; + + if( !req.return_info_only ) + json_out_stream << L"}\n"; + else + log << " (Request::info only)"; + + log << logend; +} + // !! zmienic na lepsza nazwe void App::MakePage() { bool sent = false; - if( cur.request->page_generated || !cur.request->redirect_to.empty() || !cur.request->x_sendfile.empty() ) return; @@ -419,7 +458,7 @@ bool sent = false; { if( cur.request->function == &functions.fun_cat ) { - cur.request->page << cur.request->item.content; + cur.request->out_streams[0] << cur.request->item.content; // !! CHECK ME is it ok? sent = true; } else @@ -436,12 +475,9 @@ bool sent = false; } - if( cur.request->ajax_serializer ) + if( cur.request->return_json ) { - 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); + CreateJSONAnswer(); } } @@ -476,6 +512,9 @@ void App::Make() return; } + if( cur.request->ParamValue(L"reqtype") == L"json" ) + cur.request->return_json = true; + if( cur.session->ip_ban && cur.session->ip_ban->IsIPBanned() ) { PT::Date date(cur.session->ip_ban->expires); @@ -525,11 +564,10 @@ void App::Make() return; } - if( !cur.request->ajax_serializer && cur.request->ParamValue(L"reqtype") == L"json") + if( !cur.request->info_serializer ) { - log << log3 << "App: using generic JSON serializer" << logend; - ajax_generic_serializer.Clear(); - cur.request->ajax_serializer = &ajax_generic_serializer; + json_generic_serializer.Clear(); // !! IMPROVE ME add to the end of a request + cur.request->info_serializer = &json_generic_serializer; } plugin.Call(WINIX_CONTENT_MAKE); @@ -728,6 +766,7 @@ void App::CheckKonqueror() + void App::PrepareSessionCookie() { if( !cur.session || cur.session->id==0 ) @@ -812,7 +851,7 @@ void App::SendHeadersStatic() void App::SendHeaderContentType() { - if( cur.request->ajax_serializer ) + if( cur.request->return_json ) { FCGX_PutS("Content-Type: application/json", fcgi_request.out); } @@ -967,7 +1006,7 @@ void App::FilterCompressSend(bool compressing, int compress_encoding, const std: 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); - if( config.html_filter && cur.request->use_html_filter && !raw && !cur.request->ajax_serializer ) + if( config.html_filter && cur.request->use_html_filter && !raw && !cur.request->return_json ) { TemplatesFunctions::html_filter.Filter(*source, clean_html); AddDebugInfo(clean_html); @@ -992,6 +1031,9 @@ void App::FilterCompressSend(bool compressing, int compress_encoding, const std: compress.CompressAndPut(source_a.c_str(), source_a.length(), fcgi_request.out, compress_encoding); else FCGX_PutS(source_a.c_str(), fcgi_request.out); + + if( cur.request->return_json ) + json_out_stream.Clear(); } @@ -1098,10 +1140,10 @@ Error status = cur.request->status; bool compressing; int compress_encoding; - if( cur.request->ajax_serializer ) - source = &cur.request->ajaxpage.Str(); + if( cur.request->return_json ) + source = &json_out_stream.Str(); else - source = &cur.request->page.Str(); + source = &cur.request->out_streams[0].Str(); SelectCompression(source->length(), compressing, compress_encoding); @@ -1158,14 +1200,12 @@ void App::SendData(const BinaryPage & page, FCGX_Stream * out) void App::SendBinaryAnswer() { -BinaryPage & source = cur.request->binary_page; -BinaryPage & compressed_page = cur.request->compressed_page; +BinaryPage & source = cur.request->out_bin_stream; Header header = h_200; Error status = cur.request->status; bool compressing; int compress_encoding; - SelectCompression(source.size(), compressing, compress_encoding); if( status == WINIX_ERR_NO_ITEM || status == WINIX_ERR_NO_FUNCTION || status == WINIX_ERR_UNKNOWN_PARAM ) @@ -1182,8 +1222,10 @@ int compress_encoding; { if( compressing ) { - compress.Compressing(source, compressed_page, compress_encoding); - SendData(compressed_page, fcgi_request.out); + out_bin_stream_compressed.clear(); // !! IMPROVE ME add to the end of a request + compress.Compressing(source, out_bin_stream_compressed, compress_encoding); + SendData(out_bin_stream_compressed, fcgi_request.out); + out_bin_stream_compressed.clear(); } else { @@ -1195,10 +1237,10 @@ int compress_encoding; void App::SendAnswer() { - if( cur.request->use_text_page ) - SendTextAnswer(); - else + if( cur.request->send_bin_stream ) SendBinaryAnswer(); + else + SendTextAnswer(); } diff --git a/core/app.h b/core/app.h index 5bc07f7..6a7fd04 100755 --- a/core/app.h +++ b/core/app.h @@ -122,7 +122,9 @@ private: std::string sendh_t, sendh_t2, sendh_t3; std::string sendfilea, sendfile2a; std::string send_data_buf; - PT::SpaceToJSON ajax_generic_serializer; + PT::SpaceToJSON json_generic_serializer; + TextStream json_out_stream; + BinaryPage out_bin_stream_compressed; bool CheckAccessFromPlugins(); void ProcessRequestThrow(); @@ -137,6 +139,7 @@ private: void SaveSessionsIfNeeded(); // !! wywalic do menagera sesji?? void LogAccess(); void SendData(const BinaryPage & page, FCGX_Stream * out); + void CreateJSONAnswer(); void ReadRequest(); void SendTextAnswer(); @@ -156,6 +159,7 @@ private: void CheckSSL(); void SetSubdomain(); + void PrepareSessionCookie(); void AddDebugInfo(std::wstring & out); void FilterCompressSend(bool compressing, int compress_encoding, const std::wstring & source_ref); diff --git a/core/misc.h b/core/misc.h index 6d8a3fd..133b209 100755 --- a/core/misc.h +++ b/core/misc.h @@ -1014,4 +1014,34 @@ void SetMinMax(IntType & val, IntType min_val, IntType max_val) + +template +void JSONescape(Stream & out, const StringType & str) +{ + // !! IMPROVE ME (optimizing) + // it is better to not write one by one character + // but use write method insted + + for(size_t i=0 ; i 0 ) - ajax.RemoveSpace(i); - - ajax.table.clear(); - - PT::Space::TableSingle::iterator s = ajax.table_single.begin(); - - while( s != ajax.table_single.end() ) - { - if( s->first != L"content" && s->first != L"http_status" ) - { - ajax.table_single.erase(s++); - } - else - { - // small optimization when deleting - // the memory for "content" and "http_status" will be reused - s->second.clear(); - - ++s; - } - } + for(size_t i=0 ; i headers; - HtmlTextStream page, debug; - TextStream ajaxpage; + // !! IMPROVE ME change headers to some kind of a map, may PT::Space ? + TextStream headers; + HtmlTextStream debug; - // binary page - BinaryPage binary_page; - // a compressed page ready to send to the client - BinaryPage compressed_page; + // winix can return either a text answer or a binary answer + // if send_bin_stream is true then the binary answer is sent (out_bin_stream) + // or if send_bin_stream is false then the text answer is sent + // default: false + // + // + // + // winix answer send to the client's browser + // | + // | + // depending on send_bin_stream + // ------------------------------------------------- + // | | + // text answer binary answer + // | | + // depending on return_json sending out_bin_stream + // ------------------------------------ + // | | + // normal request ajax request + // | | + // sending out_streams[0] depending on return_info_only + // ------------------------------------------------------ + // | | + // generating JSON object from: generating JSON object only from info + // out_streams and info, e.g.: e.g.: + // { { info object serialized here } + // "stream_1": "some html content", + // "stream_2": "some other html content", + // "info": { info object serialized here } + // } + // note that out_streams[0] is not sent + // in JSON answers + // + // + bool send_bin_stream; + + + + // ------------------------------------------------------------------------------------- + // binary answer + // + + // binary page sent to the client if send_bin_stream is true + BinaryPage out_bin_stream; + + // + // ------------------------------------------------------------------------------------- + + + + // ------------------------------------------------------------------------------------- + // text answer + // + + // when returning the text answer we can either return the whole html page (normal requests) + // or a JSON object (for requests generated from AJAX) + // if return_json is false then we return the whole html page (which is in out_streams[0]) + // if return_json is true we are creating an JSON object from out_streams + // (zero stream is ignored) and from info space (see above picture) + // (or just only from info if return_info_only is true) + // default: false + // return_json is set to true by App at the beginning of a request + // if reqtype:json parameter is present (in the url) + // note: return_json is only valid if send_bin_stream is false + bool return_json; + + // main text output streams where the html otput is generated from ezc templates + // the zero stream (out_streams[0]) is used as the main stream + // to which the whole html page (with doctype, head, body) is generated + // the rest streams can be only used in ajax requests (send in JSON format to the client) + // in ezc templates you can use [ezc stream ...] keyword + // to switch between streams e.g. [ezc stream "0" "2"] + std::vector out_streams; + + // if true the JSON object is generated only from info (out_streams are not used) + // default: false + bool return_info_only; + + // additional info added when sending the JSON answer + PT::Space info; + + // info serializer + // if not set then the json_generic_serializer from App will be used + // default: null (json_generic_serializer used) + PT::SpaceToJSON * info_serializer; + + // + // ------------------------------------------------------------------------------------- - // if true then either page or ajaxpage will be sent to the client - // if false then binary_page is sent - // default: true - bool use_text_page; // if set to true then the standard template system will not be generated // default: false @@ -67,6 +147,10 @@ struct Request // default: true bool use_html_filter; + + + + // raw parameters PostTab post_tab; PostFileTab post_file_tab; @@ -157,15 +241,6 @@ struct Request // subdomain = HTTP_HOST environment variable - config->base_url std::wstring subdomain; - // 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) !! 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 @@ -222,7 +297,7 @@ private: // used in ParamValue() and PostVar() when there is no such a param const std::wstring str_empty; - void ClearAjax(); + void ClearOutputStreams(); }; diff --git a/core/system.cpp b/core/system.cpp index e073aa7..a67ab07 100755 --- a/core/system.cpp +++ b/core/system.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. * */ @@ -144,6 +144,30 @@ bool ssl = false; } +void System::CreateItemLink(long parent_id, const std::wstring & url, const std::wstring & subdomain, + std::wstring & link, bool clear_str) +{ + PutUrlProto(config->use_ssl, link, clear_str); + + if( !subdomain.empty() ) + { + link += subdomain; + link += '.'; + } + + link += config->base_url; + dirs.MakePath(parent_id, link, false); // !! IMPROVE ME may some kind of error checks here? + link += url; +} + + +void System::CreateItemLink(const Item & item, std::wstring & link, bool clear_str) +{ + CreateItemLink(item.parent_id, item.url, cur->request->subdomain, link, clear_str); +} + + + // !! IMPROVE ME // !! mozna zrobic jakas obsluge kiedy nie mozemy sie redirectnac, np gdy wystapil blad // !! moze zwracac jakas wartosc? diff --git a/core/system.h b/core/system.h index eb0d84c..919b534 100755 --- a/core/system.h +++ b/core/system.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. * */ @@ -171,6 +171,13 @@ public: // reloading time zones void ReadTimeZones(); + + void CreateItemLink(long parent_id, const std::wstring & url, const std::wstring & subdomain, + std::wstring & link, bool clear_str = true); + + void CreateItemLink(const Item & item, std::wstring & link, bool clear_str = true); + + private: Cur * cur; diff --git a/core/version.h b/core/version.h index 91a54f6..dd066f3 100755 --- a/core/version.h +++ b/core/version.h @@ -13,7 +13,7 @@ #define WINIX_VER_MAJOR 0 #define WINIX_VER_MINOR 5 -#define WINIX_VER_REVISION 5 +#define WINIX_VER_REVISION 6 #endif diff --git a/functions/rm.cpp b/functions/rm.cpp index 140d2bb..d60fc1b 100755 --- a/functions/rm.cpp +++ b/functions/rm.cpp @@ -464,9 +464,9 @@ void Rm::Clear() void Rm::CreateJSON(bool status) { if( status ) - cur->request->page << "[true]\n"; + cur->request->out_streams[0] << "[true]\n"; else - cur->request->page << "[false]\n"; + cur->request->out_streams[0] << "[false]\n"; cur->request->page_generated = true; cur->request->use_html_filter = false; diff --git a/functions/upload.cpp b/functions/upload.cpp index bb5c7af..af2f3fb 100755 --- a/functions/upload.cpp +++ b/functions/upload.cpp @@ -29,6 +29,12 @@ Upload::Upload() } +void Upload::Init() +{ + json_serializer.TreatAsTable(L"infospace"); + json_serializer.TreatAsNumeric(L"size"); +} + bool Upload::HasAccess(const Item & item) { @@ -188,7 +194,7 @@ void Upload::UploadMulti() } if( is_jquery_upload ) - CreateJSON(); + CreateAnswer(); else system->RedirectToLastDir(); } @@ -224,7 +230,7 @@ void Upload::UploadSingle() post_file.tmp_filename.clear(); if( is_jquery_upload ) - CreateJSON(); + CreateAnswer(); else if( cur->request->status == WINIX_ERR_OK ) system->RedirectTo(cur->request->item, L"/cat"); @@ -255,17 +261,38 @@ void Upload::MakePost() -void Upload::CreateJSON() +void Upload::CreateAnswer() { - size_t loc = TemplatesFunctions::locale.GetCurLang(); - Ezc::Pattern * pat = TemplatesFunctions::patterns.Get(template_index, loc); + Request & req = *cur->request; + req.info.name = L"infospace"; // 'infospace' will be serialized to an array - if( pat ) + for(size_t i=0 ; iGenerate(*pat); - cur->request->page_generated = true; - cur->request->use_html_filter = false; + PT::Space & file = req.info.AddSpace(L""); + + file.Add(L"name", req.item_tab[i].url); + file.Add(L"size", req.item_tab[i].file_size); + + std::wstring & link = file.Add(L"url", L""); + system->CreateItemLink(req.item_tab[i], link); + + std::wstring & del_url = file.Add(L"delete_url", link); + del_url += L"/rm/jquery_upload"; + + file.Add(L"delete_type", L"POST"); + + if( req.item_tab[i].file_type == WINIX_ITEM_FILETYPE_IMAGE ) + { + std::wstring & thumb = file.Add(L"thumbnail_url", link); + + if( req.item_tab[i].has_thumb ) + thumb += L"/-/thumb"; + } } + + cur->request->return_json = true; + cur->request->return_info_only = true; + cur->request->info_serializer = &json_serializer; } @@ -280,7 +307,7 @@ void Upload::MakeGet() db->GetItems(cur->request->item_tab, query); - CreateJSON(); + CreateAnswer(); } } diff --git a/functions/upload.h b/functions/upload.h index d428eb4..bf32840 100755 --- a/functions/upload.h +++ b/functions/upload.h @@ -2,7 +2,7 @@ * This file is a part of Winix * and is not publicly distributed * - * Copyright (c) 2010, Tomasz Sowa + * Copyright (c) 2010-2013, Tomasz Sowa * All rights reserved. * */ @@ -11,7 +11,7 @@ #define headerfile_winix_functions_upload #include "functionbase.h" - +#include "space/spacetojson.h" namespace Fun @@ -35,6 +35,13 @@ private: DbItemQuery query; bool is_jquery_upload; + // this object is used in App at the end of a request + // for serializing Request::info to JSON + // this will make a problem if in the future we'll use multithread requests + PT::SpaceToJSON json_serializer; + + void Init(); + bool HasAccess(const Item & item); bool UploadSaveStaticFile(const Item & item, const std::wstring & tmp_filename); bool FunUploadCheckAbuse(); @@ -42,7 +49,7 @@ private: void UploadSingle(); void ResizeImage(Item & item); void CreateThumb(Item & item); - void CreateJSON(); + void CreateAnswer(); }; diff --git a/html/index_ajaxcontent.html b/html/index_ajaxcontent.html deleted file mode 100755 index f972084..0000000 --- a/html/index_ajaxcontent.html +++ /dev/null @@ -1 +0,0 @@ -[content] diff --git a/html/index_rawcontent.html b/html/index_rawcontent.html deleted file mode 100755 index f972084..0000000 --- a/html/index_rawcontent.html +++ /dev/null @@ -1 +0,0 @@ -[content] diff --git a/templates/templates.cpp b/templates/templates.cpp index 7065c61..41f111c 100755 --- a/templates/templates.cpp +++ b/templates/templates.cpp @@ -20,13 +20,11 @@ namespace TemplatesFunctions size_t pat_index; // main index pattern size_t pat_index_fullscreen; // an empty pattern (without menus etc. but with all rest html tags, used for ckeditor images browser) -size_t pat_index_rawcontent; // completly empty pattern (only content, without html tags such as , ) -size_t pat_index_ajaxcontent; // ajax pattern (only content, similar as pat_index_rawcontent) size_t pat_err_404; // 404 error size_t pat_err_per_denied; // permission denied error Patterns patterns; // all html patterns -IndexPatterns index_patterns; // patterns for main index template (those from mountpoint) +IndexPatterns index_patterns; // patterns for main index templates (those from mountpoint) // index_patterns uses patterns as a storage ChangePatterns change_patterns; // patterns for change_template mount option (storage is in 'patterns' too) PatternCacher pattern_cacher; // patterns for user items (files with an executable bit set) @@ -822,8 +820,6 @@ using namespace TemplatesFunctions; pat_index = patterns.Add(config->templates_index); pat_index_fullscreen = patterns.Add(L"index_fullscreen.html"); - pat_index_rawcontent = patterns.Add(L"index_rawcontent.html"); - pat_index_ajaxcontent = patterns.Add(L"index_ajaxcontent.html"); pat_err_404 = patterns.Add(L"err_404.html"); pat_err_per_denied = patterns.Add(L"err_per_denied.html"); @@ -910,12 +906,6 @@ using namespace TemplatesFunctions; Ezc::Pattern * index = 0; - if( cur->request->ajax_serializer ) - index = patterns.Get(pat_index_ajaxcontent, locale.GetCurLang()); - else - if( cur->request->IsParam(L"rawcontent") ) - index = patterns.Get(pat_index_rawcontent, locale.GetCurLang()); - else if( cur->request->IsParam(L"fullscreen") ) index = patterns.Get(pat_index_fullscreen, locale.GetCurLang()); else @@ -954,7 +944,7 @@ using namespace TemplatesFunctions; generator.SkipNewLine(gen_skip_new_line); generator.RecognizeSpecialChars(gen_use_special_chars); generator.SetMax(config->ezc_max_elements, config->ezc_max_loop_elements); - generator.Generate(cur->request->page, *index); + generator.Generate(cur->request->out_streams, *index); } else { @@ -971,7 +961,10 @@ using namespace TemplatesFunctions; if( !empty_pars.empty() ) empty_pars.clear(); - Info info(cur->request->page, empty_pars, empty_string, empty_stream); + // !! FIX ME + // at the moment stream 0 is used + // here should be something other + Info info(cur->request->out_streams[0], empty_pars, empty_string, empty_stream); info.iter = 0; info.res = false; @@ -988,7 +981,7 @@ using namespace TemplatesFunctions; generator.SkipNewLine(gen_skip_new_line); generator.RecognizeSpecialChars(gen_use_special_chars); generator.SetMax(config->ezc_max_elements, config->ezc_max_loop_elements); - generator.Generate(cur->request->page, pattern); + generator.Generate(cur->request->out_streams, pattern); } diff --git a/templates/templates.h b/templates/templates.h index 00d1d38..84fc306 100755 --- a/templates/templates.h +++ b/templates/templates.h @@ -37,9 +37,7 @@ class Functions; namespace TemplatesFunctions { extern size_t pat_index; - extern size_t pat_index_ajaxcontent; extern size_t pat_index_fullscreen; - extern size_t pat_index_rawcontent; extern size_t pat_err_404; extern size_t pat_err_per_denied;