cppcms-users Mailing List for CppCMS C++ Web Framework (Page 117)
Brought to you by:
artyom-beilis
You can subscribe to this list here.
2009 |
Jan
|
Feb
(22) |
Mar
|
Apr
(3) |
May
|
Jun
(4) |
Jul
|
Aug
|
Sep
|
Oct
(15) |
Nov
(16) |
Dec
(13) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2010 |
Jan
(4) |
Feb
|
Mar
(8) |
Apr
(8) |
May
(8) |
Jun
(36) |
Jul
(63) |
Aug
(126) |
Sep
(47) |
Oct
(66) |
Nov
(46) |
Dec
(42) |
2011 |
Jan
(87) |
Feb
(24) |
Mar
(54) |
Apr
(21) |
May
(22) |
Jun
(18) |
Jul
(22) |
Aug
(101) |
Sep
(57) |
Oct
(33) |
Nov
(34) |
Dec
(66) |
2012 |
Jan
(64) |
Feb
(76) |
Mar
(73) |
Apr
(105) |
May
(93) |
Jun
(83) |
Jul
(84) |
Aug
(88) |
Sep
(57) |
Oct
(59) |
Nov
(35) |
Dec
(49) |
2013 |
Jan
(67) |
Feb
(17) |
Mar
(49) |
Apr
(64) |
May
(87) |
Jun
(64) |
Jul
(93) |
Aug
(23) |
Sep
(15) |
Oct
(16) |
Nov
(62) |
Dec
(73) |
2014 |
Jan
(5) |
Feb
(23) |
Mar
(21) |
Apr
(11) |
May
(1) |
Jun
(19) |
Jul
(27) |
Aug
(16) |
Sep
(5) |
Oct
(37) |
Nov
(12) |
Dec
(9) |
2015 |
Jan
(7) |
Feb
(7) |
Mar
(44) |
Apr
(28) |
May
(5) |
Jun
(12) |
Jul
(8) |
Aug
|
Sep
(39) |
Oct
(34) |
Nov
(30) |
Dec
(34) |
2016 |
Jan
(66) |
Feb
(23) |
Mar
(33) |
Apr
(15) |
May
(11) |
Jun
(15) |
Jul
(26) |
Aug
(4) |
Sep
(1) |
Oct
(30) |
Nov
(10) |
Dec
|
2017 |
Jan
(52) |
Feb
(9) |
Mar
(24) |
Apr
(16) |
May
(9) |
Jun
(12) |
Jul
(33) |
Aug
(8) |
Sep
|
Oct
(1) |
Nov
(2) |
Dec
(6) |
2018 |
Jan
(5) |
Feb
|
Mar
|
Apr
|
May
(14) |
Jun
(1) |
Jul
(9) |
Aug
(1) |
Sep
(13) |
Oct
(8) |
Nov
(2) |
Dec
(2) |
2019 |
Jan
(1) |
Feb
(1) |
Mar
(3) |
Apr
(3) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
|
2020 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
(9) |
Jul
(6) |
Aug
(25) |
Sep
(10) |
Oct
(10) |
Nov
(6) |
Dec
|
2021 |
Jan
|
Feb
|
Mar
(7) |
Apr
(1) |
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
(9) |
Oct
(1) |
Nov
|
Dec
|
2022 |
Jan
|
Feb
|
Mar
|
Apr
(3) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: augustin <aug...@ov...> - 2011-03-11 06:11:36
|
On Thursday 10 March 2011 08:20:09 pm Artyom wrote: > > new widget in my content's form element, like this: > > cppcms::widgets::checkbox c.form.check = cppcms::widgets::checkbox(); > > where c.form is the base form, but I get the compile error: > > error: expected initializer before ‘.’ token > > > > See, C++ is not dynamically typed language, you can't add member > to structure dynamically. Oh! Of course I knew about strong types in C++ yet I still overlook some of the consequences of that. Old PHP habits die hard ;-/ Thank you for pointing this out to me. Blessings, Augustin. -- Friends: http://www.reuniting.info/ My projects: http://astralcity.org/ http://3enjeux.overshoot.tv/ http://linux.overshoot.tv/ http://overshoot.tv/ http://charityware.info/ http://masquilier.org/ http://openteacher.info/ http://minguo.info/ http://www.wechange.org/ http://searching911.info/ . |
From: Artyom <art...@ya...> - 2011-03-10 12:20:16
|
> Instead of using a std::list, I don't declare any checkbox widgets in the form > > struct, i.e. I don't declare them in the header file. > Instead, I try to introduce new form elements in the .cpp file by declaring a > new widget in my content's form element, like this: > cppcms::widgets::checkbox c.form.check = cppcms::widgets::checkbox(); > where c.form is the base form, but I get the compile error: > error: expected initializer before ‘.’ token > See, C++ is not dynamically typed language, you can't add member to structure dynamically. Artyom |
From: Artyom <art...@ya...> - 2011-03-10 12:09:22
|
Hello, First of all all widgets are not copyable so you can't put them to STL containers! The simplest way is to call form::attach(...) and add them dynamically to the form as pointers (ownership is transferred to the form object) Then you can render them as <% foreach box in my_form.list_of_pointers_to_checkboxes %> <ul> <% item %> <li><% form as_space *box %></li> <% end %> </ul> <% end %> Each one independently or you can use a sub form that you add all dynamic widgets to it and render them in one command <% from as_ul my_form.chckboxes_subform %> For example: class my_form : public cppcms::form{ cppcms::form checkboxes; // Subform std::vector<cppcms::widgets::checkox *> boxes; my_form() { add(checkboxes); // register to parent for(int i=0;i<n;i++) { cppcms::widgets::checkox *box = new cppcms::widgets::checkox(); checkboxes.attach(box); // transfer ownership and register to parent box->message(...) boxes.push_back(box); } } } Rendering <% from as_ul my_form.checkboxes %> Take a look on this as example: http://cppcms.svn.sourceforge.net/viewvc/cppcms/blog/trunk/views/admin/post.tmpl?revision=1690&view=markup http://cppcms.svn.sourceforge.net/viewvc/cppcms/blog/trunk/data/admin/post.h?revision=1690&view=markup http://cppcms.svn.sourceforge.net/viewvc/cppcms/blog/trunk/apps/admin/post.cpp?revision=1691&view=markup Artyom ----- Original Message ---- > From: augustin <aug...@ov...> > To: cpp...@li... > Sent: Thu, March 10, 2011 9:37:25 AM > Subject: [Cppcms-users] rendering list of widgets::checkbox > > > Hello Artyom, > > I have a form with a series of checkboxes. The number of checkboxes is > variable and know at run time. > > I figured I could use a std::list of widgets::checkbox, and declare that >within > > my form struct, but I am wondering how to render this in the template: > http://art-blog.no- > ip.info/wikipp/en/page/cppcms_1x_templates_comm#Rendering.Forms > > Will cppcms iterate itself over any STL class like a list or a map? > A form containing simple widgets is easy enough to render: > <% form as_p info %> > but how would that look like if the form includes a std::list of widgets? > > Thanks, > > Augustin. > > > > > > -- > Friends: http://www.reuniting.info/ > My projects: > http://astralcity.org/ http://3enjeux.overshoot.tv/ http://linux.overshoot.tv/ > > > http://overshoot.tv/ http://charityware.info/ http://masquilier.org/ > http://openteacher.info/ http://minguo.info/ > http://www.wechange.org/ http://searching911.info/ > > > > > > > > > > > > > . > > ------------------------------------------------------------------------------ > Colocation vs. Managed Hosting > A question and answer guide to determining the best fit > for your organization - today and in the future. > http://p.sf.net/sfu/internap-sfd2d > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users > |
From: augustin <aug...@ov...> - 2011-03-10 09:30:21
|
I thought maybe my approach was too complicated, so I tried another approach which I thought would be simpler, but in vain. Instead of using a std::list, I don't declare any checkbox widgets in the form struct, i.e. I don't declare them in the header file. Instead, I try to introduce new form elements in the .cpp file by declaring a new widget in my content's form element, like this: cppcms::widgets::checkbox c.form.check = cppcms::widgets::checkbox(); where c.form is the base form, but I get the compile error: error: expected initializer before ‘.’ token Attached is a patch against examples/forms/hello.cpp that shows what I'm trying to do. Bonus: the first hunk in the patch is for a typo fix. Thanks. Augustin. -- Friends: http://www.reuniting.info/ My projects: http://astralcity.org/ http://3enjeux.overshoot.tv/ http://linux.overshoot.tv/ http://overshoot.tv/ http://charityware.info/ http://masquilier.org/ http://openteacher.info/ http://minguo.info/ http://www.wechange.org/ http://searching911.info/ . |
From: augustin <aug...@ov...> - 2011-03-10 07:37:42
|
Hello Artyom, I have a form with a series of checkboxes. The number of checkboxes is variable and know at run time. I figured I could use a std::list of widgets::checkbox, and declare that within my form struct, but I am wondering how to render this in the template: http://art-blog.no- ip.info/wikipp/en/page/cppcms_1x_templates_comm#Rendering.Forms Will cppcms iterate itself over any STL class like a list or a map? A form containing simple widgets is easy enough to render: <% form as_p info %> but how would that look like if the form includes a std::list of widgets? Thanks, Augustin. -- Friends: http://www.reuniting.info/ My projects: http://astralcity.org/ http://3enjeux.overshoot.tv/ http://linux.overshoot.tv/ http://overshoot.tv/ http://charityware.info/ http://masquilier.org/ http://openteacher.info/ http://minguo.info/ http://www.wechange.org/ http://searching911.info/ . |
From: augustin <aug...@ov...> - 2011-02-16 10:15:55
|
On Wednesday 16 February 2011 12:11:17 am CN wrote: > It will save users much time if this behavior is documented. First, as Artyom pointed out, this is a SQL feature and it IS documented: check your SQL vendor documentation. Second, you and everyone else on this list are welcome to contribute what you can to the CPPCMS wiki. Registration is easy. The number of contributors in the wiki (including occasional contributors like myself) sadly is far from matching the number of CPPCMS users. CN: I am looking forward to your contributions in the wiki. Blessings, Augustin. -- Friends: http://www.reuniting.info/ http://activistsolutions.org/ My projects: http://astralcity.org/ http://3enjeux.overshoot.tv/ http://linux.overshoot.tv/ http://overshoot.tv/ http://charityware.info/ http://masquilier.org/ http://openteacher.info/ http://minguo.info/ http://www.wechange.org/ http://searching911.info/ . |
From: Artyom <art...@ya...> - 2011-02-15 16:30:57
|
> Subject: Re: [Cppcms-users] cppdb::statement.affected() usage? > > Thank you a lot for the clarification! > > > Yes, number of affected rows is number of rows affected by > > statements like DELETE or UPDATE, the behavior of affected() > > when using queries (like SELECT) is undefined and may cause > > exceptions. > > It will save users much time if this behavior is documented. > It is documented the term "affected" is something known in general for SQL handling. > Also, it will be handy if the number of selected rows (returned by libpq's > PQntuples()) is implemented in either cppdb::statement or cppdb::result. > Without this feature, it seems that iterating cppdb::result (by calling > next()) is the only available way to know the number of selected rows. > Wrong? > The problem is this is not always known as you get the data by iterating over it so in some backends like sqlite3 you can know this only after fully iterating the entire data set and somethimes it is not so good idea. So this option is not supported as in some cases the data is not fetched in whole. Artyom |
From: CN <cn...@gr...> - 2011-02-15 16:12:41
|
Thank you a lot for the clarification! > Yes, number of affected rows is number of rows affected by > statements like DELETE or UPDATE, the behavior of affected() > when using queries (like SELECT) is undefined and may cause > exceptions. It will save users much time if this behavior is documented. Also, it will be handy if the number of selected rows (returned by libpq's PQntuples()) is implemented in either cppdb::statement or cppdb::result. Without this feature, it seems that iterating cppdb::result (by calling next()) is the only available way to know the number of selected rows. Wrong? Regards, CN |
From: Artyom <art...@ya...> - 2011-02-15 15:11:58
|
> Hello! > > The following SELECT gets one tuple: > > cppdb::statement st=session << "SELECT 1 FROM t1"; > cppdb::result r=st.row(); > > Now, r.empty() returns false, which is correct, but st.affected() returns > 0. > > cppdb::statement.affected() is supposed to return the selected number of > tuples, which is 1 in this case, not 0. > > Do I misunderstand its usage? > Yes, number of affected rows is number of rows affected by statements like DELETE or UPDATE, the behavior of affected() when using queries (like SELECT) is undefined and may cause exceptions. Artyom ____________________________________________________________________________________ Need Mail bonding? Go to the Yahoo! Mail Q&A for great tips from Yahoo! Answers users. http://answers.yahoo.com/dir/?link=list&sid=396546091 |
From: CN <cn...@gr...> - 2011-02-15 14:12:41
|
Hello! The following SELECT gets one tuple: cppdb::statement st=session << "SELECT 1 FROM t1"; cppdb::result r=st.row(); Now, r.empty() returns false, which is correct, but st.affected() returns 0. cppdb::statement.affected() is supposed to return the selected number of tuples, which is 1 in this case, not 0. Do I misunderstand its usage? Thank you in advance! Regards, CN |
From: Artyom <art...@ya...> - 2011-02-12 14:11:16
|
> > ===Template follows:=== > <input type="checkbox" checked="checked" name="agree "/>Agree our > terms?</label> You need a value="y" which is default for CppCMS. 1. checkbox tests both name and value to match so you can have different checkboxes with same name. 2. If you don't like the default form rendering you may use 1. Render by smaller parts - like indivisual widgets 2. Render at least input using <% form input checkbox %> so it takes details for you. In your case I'd recommend rendering entire form or simplt form in subforms and render them each in its kind. 3. Automatic rendering solves all problems with manual naming of widgets. So in your case I would write <table> <% form as_table some_form.inputs %> </table> <% form as_space some_form.agree %> <table> <tr> <td><input type="submit" value="Register"/></td> <td></td> </tr> </table> </form> struct form_register : public cppcms::form { form_register(cppcms::session_interface &); cppcms::widgets::email account; cppcms::widgets::password password1; cppcms::widgets::password password2; cppcms::widgets::checkbox agree; cppcms::form inputs; bool validate(); cppcms::session_interface &cppcms_sess; }; form_register() { account.message("Name"); account.non_empty(); password1.message("Password"); password1.non_empty(); password2.message("Confirm"); password2.non_empty(); password2.check_equal(password1); agree.message("Agree to terms"); inputs.add(account); inputs.add(password1); inputs.add(password2); // one redneting group add(inputs); // 2nd redneting group add(agree) } Something like that. > ===pages.cpp follows=== > > bool form_register::validate() > { > return form::validate(); > } > Don't need this, overload validate just if you need special validation. > form_register::form_register(cppcms::session_interface &se) : > cppcms_sess(se) > { > account.name("em"); > account.non_empty(); > password1.name("pw"); > password1.non_empty(); > password2.name("cfpw"); > password2.non_empty(); > password2.check_equal(password1); > agree.name("agree"); need also agree.identifiction("something") same value="something" in the form/ > *this+account+password1+password2+agree; > } > But it is much better not to give names, they generated automatically and this approach less error prone > ===application follows=== > > content_register page(session()); > if(request().request_method() == "GET"){ > render("view_register",page); > } > else{ > page.form.load(context()); > if(page.form.validate()){ > BOOSTER_LOG(debug,"account") << page.form.account.value(); //good > BOOSTER_LOG(debug,"agree") << page.form.agree.value(); //"0" > } > } > Artyom |
From: CN <cn...@gr...> - 2011-02-12 13:49:39
|
Many thanks for help! > Show your code... > > 1. How do you configure your form (full code) > 2. How do you load data to your form > 3. How do you render your form ===Template follows:=== <% c++ #include "pages.h" %> <% xhtml %> <% skin namespace_skin %> <% view view_register uses content_register %> <% template render() %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <link rel="stylesheet" type="text/css" href="http://example.com/css/register.css"/> <title>Register As A Member</title> </head> <body> <form method="post" action="/cgi/s/register"> <table> <tr> <td><label for="em">EMail</label></td> <td><input type="text" id="em" name="em" value="" size="40"/></td> </tr> <tr> <td><label for="pw">Password:</label></td> <td><input type="password" id="pw" name="pw" value="" size="40"/></td> </tr> <tr> <td><label for="cfpw">Confirm Password</label></td> <td><input type="password" id="cfpw" name="cfpw" value="" size="40"/></td> </tr> </table> <label><input type="checkbox" checked="checked" name="agree"/>Agree our terms?</label> <table> <tr> <td><input type="submit" value="Register"/></td> <td></td> </tr> </table> </form> </body> </html> <% end template %> <% end view %> <% end skin %> ===pages.h follows=== struct form_register : public cppcms::form { form_register(cppcms::session_interface &); cppcms::widgets::email account; cppcms::widgets::password password1; cppcms::widgets::password password2; cppcms::widgets::checkbox agree; bool validate(); cppcms::session_interface &cppcms_sess; }; struct content_register : public content_master { content_register(cppcms::session_interface &se) : form(se){}; form_register form; }; ===pages.cpp follows=== bool form_register::validate() { return form::validate(); } form_register::form_register(cppcms::session_interface &se) : cppcms_sess(se) { account.name("em"); account.non_empty(); password1.name("pw"); password1.non_empty(); password2.name("cfpw"); password2.non_empty(); password2.check_equal(password1); agree.name("agree"); *this+account+password1+password2+agree; } ===application follows=== content_register page(session()); if(request().request_method() == "GET"){ render("view_register",page); } else{ page.form.load(context()); if(page.form.validate()){ BOOSTER_LOG(debug,"account") << page.form.account.value(); //good BOOSTER_LOG(debug,"agree") << page.form.agree.value(); //"0" } } ============= Best Regards CN |
From: Artyom <art...@ya...> - 2011-02-12 10:10:23
|
Hello, Show your code... 1. How do you configure your form (full code) 2. How do you load data to your form 3. How do you render your form Because I use checkbox on daily basis and it is covered by unit test. > > Checkbox is defined like this: > > cppcms::widgets::checkbox agree; > > Now check the posted form values: > > if(request().post().find("agree") != request().post().end()) > BOOSTER_LOG(debug,"agree") << request().post().find("agree")->second; > > and I see "on" in the log, but agree.value() always returns "0". > > Any idea? 1. All CppCMS 1.x.x widgets have automatic naming that are rendered and tested in form so basically if you use request().post().find("agree") != request().post().end() Then it seems that you do not create form by <% form ... %> tag. and you write your own code. In such case you should provide a name for checkbox: agree.name("agree"); 2. In addition it is also may be that you do not put all widgets in a single form and then they not get loaded. Take a look once again on the CppCMS sources examples/form/ On how do you render and configure the form. Artyom P.S.: Which reminds me there is need for up-to-date tutorial for CppCMS forms. |
From: CN <cn...@gr...> - 2011-02-12 09:35:39
|
Hello! Please refer to documentation: http://cppcms.sourceforge.net/cppcms_ref_v0_99/classcppcms_1_1widgets_1_1checkbox.html#6e0e8154193ff93fb6a591263b815c04 Checkbox is defined like this: cppcms::widgets::checkbox agree; Now check the posted form values: if(request().post().find("agree") != request().post().end()) BOOSTER_LOG(debug,"agree") << request().post().find("agree")->second; and I see "on" in the log, but agree.value() always returns "0". Any idea? Best Regards, CN |
From: Artyom <art...@ya...> - 2011-02-10 15:20:38
|
Hello, It is a bug. Please open a bug report (so I will not forget to fix it), It is because you are using multiple HTTP acceptors or using services lis) rather then single service and HTTP api takes this settings instead if its private ones. Artyom ----- Original Message ---- > From: Cristian Oneț <one...@gm...> > To: cppcms-users <cpp...@li...> > Sent: Thu, February 10, 2011 5:13:06 PM > Subject: [Cppcms-users] cppcms::http::request::server_port() returns the >default 8080 when api is http > > Hi Artyom, > > I've found that if an application is run with the http api using a > service list the server_port method will always return 8080. > > Regards, > Cristian Oneț > > ------------------------------------------------------------------------------ > The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE: > Pinpoint memory and threading errors before they happen. > Find and fix more than 250 security defects in the development cycle. > Locate bottlenecks in serial and parallel code that limit performance. > http://p.sf.net/sfu/intel-dev2devfeb > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users > |
From: Cristian O. <one...@gm...> - 2011-02-10 15:13:07
|
Hi Artyom, I've found that if an application is run with the http api using a service list the server_port method will always return 8080. Regards, Cristian Oneț |
From: Pavel K. <un...@fu...> - 2011-02-06 00:27:47
|
thank you for your quick reply, shame on me that i didn't figure it out myself. works as expected :). pavel. |
From: Artyom <art...@ya...> - 2011-02-05 10:42:44
|
>i would like to ask if there is a clean way to >* render only part(s) of a template, for example determined by tag ><% template foo() %>...<% end template %> If you have a foo template in view bar that uses bar_content You can create a small and simple view like <% view foo_caller uses bar_content extends bar %> <% template render() %><% include foo() %><% end %> <% end view %> And then call render("foo_caller",some_content) >* encapsulate them in json object and send it to browser > background> i would like to (optionally) enable ajax support for this >scenario: > > send form, process it, show page with form and changed parts of the page >again. > > with ajax i would like to asynchronously send form, process, send back html > "snippets" & then redraw only corresponding parts of the page. You can use render(std::string template_name,std::ostream &,base_content &) See: http://art-blog.no-ip.info/cppcms_ref_v0_99/classcppcms_1_1application.html#58581e959b24512b24bd1ba8329fefb5 But you should remember to use correct locale in the stream std::ostringstream ss; ss.imbue(context().locale()); // important for translations, filters, formatting render("foo_caller",ss,foo_content); my_json_object["html"]=ss.str(); > >second question> do you have favourite libs for generating captcha You can use image magic to create ones, I've written one once. Feel free to use it: http://art-blog.no-ip.info/files/captcha.zip Note it is quite hard captcha to use for "human being" It is not so fast even when you reuse the same captcha generating object that uses letters cache (5ms for at Athlon XP 3000) > or sending emails from cppcms? > system("sendmail ... " ) ? or other command line tool. > > > >pavel. Artyom |
From: Pavel K. <un...@fu...> - 2011-02-05 01:48:22
|
hello Artyom and all, i would like to ask if there is a clean way to * render only part(s) of a template, for example determined by tag <% template foo() %>...<% end template %> * encapsulate them in json object and send it to browser background> i would like to (optionally) enable ajax support for this scenario: send form, process it, show page with form and changed parts of the page again. with ajax i would like to asynchronously send form, process, send back html "snippets" & then redraw only corresponding parts of the page. second question> do you have favourite libs for generating captcha or sending emails from cppcms? pavel. |
From: CN <cn...@gr...> - 2011-02-02 16:09:35
|
Indeed, I appeared to be comparing apples and oranges. Perhaps it's time for me to take some rest before I proceed. Thank you for your time! Regards, CN |
From: Artyom <art...@ya...> - 2011-02-02 08:59:30
|
> > Back to my point... I am able to proceed my work now. However, there is > still one thing I don't understand: > > { > dispatcher().assign("^ps$",&async_app::catch_all,this); > } > >s.applications_pool().mount(cppcms::applications_factory<sync_app>(),cppcms::mount_point("/s/(.*)",1)); > > s.applications_pool().mount(e,cppcms::mount_point("/as/(.*)",1)); Lets start: Quoting Documentation: > cppcms::mount_point::mount_point(std::string const & path,int group) > > Create a mount point that checks PATH_INFO only and passes matched group for >dispatching > That means that PATH_INFO is matched so PATH_INFO = /as/ps Matched agains: /as/(.*) And then "ps" is selected and passed to main of application that on "^ps$" gets matched. What does not match the documentation? > cppcms::mount_point::mount_point(std::string const &script) > > Create a mount point that checks SCRIPT_NAME, and passes PATH_INFO for >dispatching > Now this is fo case where we have for exaple foo.cgi bar.cgi And you want to match them So for URL foo.cgi/beep SCRIPT_NAME=foo.cgi PATH_INFO=/beep foo.cgi would be matched by mount_point("foo.cgi") and then "/beep" would passed to main of the application for dispatching ... > cppcms::mount_point::mount_point() > > Create default mount point, it uses PATH_INFO for url-dispatching and gives no >restriction on URL > This case - the default mount point when you use just a one application it passes all PATH_INFO for URL dispatching. > Please take special note of these two lines in the log: > > 2011-02-02 02:30:07 GMT; ENV, debug: PATH_INFO:/as/ps (cgi.cpp:114) > 2011-02-02 02:30:07 GMT; ENV, debug: SCRIPT_NAME:/cgi (cgi.cpp:114) > > The description for the overloaded function > > cppcms::mount_point::mount_point(std::string const &script) > > is > > "Create a mount point that checks SCRIPT_NAME, and passes PATH_INFO for > dispatching the version of mount_point() among the overloads" > > Refer to: > > http://cppcms.sourceforge.net/cppcms_ref_v0_99/classcppcms_1_1mount__point.html > > My understanding is that the following code should match nothing: > > s.applications_pool().mount(e,cppcms::mount_point("/as/(.*)",1)); > No. It is matched against PATH_INFO that is the usual case > because according to the log, the incoming SCRIPT_NAME is "/cgi". However, > the reality is that it matches! On the contrary, this version fails to > match: > > s.applications_pool().mount(e,cppcms::mount_point("/cgi/(.*)",1)); > > Is this a descrepancy between CppCMS documentation and the library itself? No, you just should read documentation more carefully. Different mount points constructors have different semantics allowing to both use script_name and path_info for dispatching, however every mount point should extract something to pass to application's main. Artyom |
From: CN <cn...@gr...> - 2011-02-02 04:01:02
|
This morning this program all a sudden begins to match requested URI. The possible reason for being not working last night most likely is because the browser did not fully reload java script and/or the web page from web server (because of its caching mechanism?) even I clicked its refresh button. I had this experience before and wasted hours looking for the cause of unexpected behavior. If people start to get the similar weird result, please try closing the tab from your browsers and then locate the URI again, or even restart it. Back to my point... I am able to proceed my work now. However, there is still one thing I don't understand: class async_app : public cppcms::application { public: async_app(cppcms::service &srv) : cppcms::application(srv) { dispatcher().assign("^ps$",&async_app::catch_all,this); } void catch_all() { BOOSTER_LOG(debug,"async app is fired"); std::map<std::string,std::string> env=request().getenv(); std::map<std::string,std::string>::const_iterator i; for(i=env.begin();i != env.end();++i) BOOSTER_LOG(debug,"ENV") << (*i).first << ":" << (*i).second; } } int main(int argc,char **argv) { cppcms::service s(argc,argv); s.applications_pool().mount(cppcms::applications_factory<sync_app>(),cppcms::mount_point("/s/(.*)",1)); booster::intrusive_ptr<async_app> e=new async_app(s); s.applications_pool().mount(e,cppcms::mount_point("/as/(.*)",1)); s.run(); return 0; } The excerpted log follows: 2011-02-02 02:30:07 GMT; ENV, debug: DOCUMENT_ROOT:/var/www/example (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: GATEWAY_INTERFACE:CGI/1.1 (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: HTTP_ACCEPT:text/html, */* (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: HTTP_ACCEPT_CHARSET:iso-8859-1, utf-8, utf-16, *;q=0.1 (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: HTTP_ACCEPT_ENCODING:deflate, gzip, x-gzip, identity, *;q=0 (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: HTTP_CONNECTION:Keep-Alive, TE (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: HTTP_HOST:www.example.com (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: HTTP_REFERER:http://www.example.com/test.html (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: HTTP_TE:deflate, gzip, chunked, identity, trailers (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: HTTP_USER_AGENT:Opera/9.80 (X11; Linux i686; U; en) Presto/2.7.62 Version/11.00 (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: HTTP_X_REQUESTED_WITH:XMLHttpRequest (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: PATH_INFO:/as/ps (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: PATH_TRANSLATED:/var/www/example/as/ps (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: QUERY_STRING: (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: REDIRECT_STATUS:200 (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: REMOTE_ADDR:127.0.0.1 (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: REMOTE_PORT:41362 (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: REQUEST_METHOD:GET (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: REQUEST_URI:/cgi/as/ps (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: SCRIPT_FILENAME:/var/www/example/cgi (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: SCRIPT_NAME:/cgi (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: SERVER_ADDR:127.0.0.1 (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: SERVER_NAME:www.example.com (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: SERVER_PORT:80 (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: SERVER_PROTOCOL:HTTP/1.1 (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: SERVER_SOFTWARE:lighttpd/1.4.28-devel-485M (cgi.cpp:114) Please take special note of these two lines in the log: 2011-02-02 02:30:07 GMT; ENV, debug: PATH_INFO:/as/ps (cgi.cpp:114) 2011-02-02 02:30:07 GMT; ENV, debug: SCRIPT_NAME:/cgi (cgi.cpp:114) The description for the overloaded function cppcms::mount_point::mount_point(std::string const &script) is "Create a mount point that checks SCRIPT_NAME, and passes PATH_INFO for dispatching the version of mount_point() among the overloads" Refer to: http://cppcms.sourceforge.net/cppcms_ref_v0_99/classcppcms_1_1mount__point.html My understanding is that the following code should match nothing: s.applications_pool().mount(e,cppcms::mount_point("/as/(.*)",1)); because according to the log, the incoming SCRIPT_NAME is "/cgi". However, the reality is that it matches! On the contrary, this version fails to match: s.applications_pool().mount(e,cppcms::mount_point("/cgi/(.*)",1)); Is this a descrepancy between CppCMS documentation and the library itself? Best Regards, CN |
From: Artyom <art...@ya...> - 2011-02-01 15:52:23
|
> > - > > http://art-blog.no-ip.info/cppcms_ref_v0_99/classcppcms_1_1mount__point.html > > > > Now I am trying to also provide mount() parameter mount_point but have > trouble with the matching: First of all read once again this: http://art-blog.no-ip.info/cppcms_ref_v0_99/classcppcms_1_1mount__point.html Most likely you are looking for: http://art-blog.no-ip.info/cppcms_ref_v0_99/classcppcms_1_1mount__point.html#8aed02e81a2442db463910d47ac8d27a Basically you are probably looking for s.applications_pool().mount(cppcms::applications_factory<sync_app>(), cppcms::mount_point("/s/(.*)",1)); s.applications_pool().mount(as_app, cppcms::mount_point("/as/(.*)",1)); When you mount with one parameter you are using SCRIPT_NAME variable and PATH_INFO passed to the main(url) When you mount with string parameter and integer parameter you are using PATH_INFO and match against url and then pass matched part to main I don't know what is your web server configuration (or script names) so I can't tell you what happens, best is to match against PATH_INFO Artyom |
From: CN <cn...@gr...> - 2011-02-01 15:47:06
|
My brain starts to malfunction due to late hour here. Sorry for the previous incorrect code. Please use this one instead. The unexpected results mentioned in last post remain unresolved. //code begin class sync_app:public cppcms::application{ .... } class async_app:public cppcms::application { async_app(cppcms::service &srv) : cppcms::application(srv) { dispatcher().assign("(.*)",&async_app::catch_all,this,1); } void catch_all(std::string url) { BOOSTER_LOG(debug,"URL") << url; } } int main(int argc,char **argv) { cppcms::service s(argc,argv); s.applications_pool().mount(cppcms::applications_factory<sync_app>(),cppcms::mount_point("/s/a")); booster::intrusive_ptr<async_app> as_app=new async_app(s); //typo error //Watch the match string in the next line! s.applications_pool().mount(as_app,cppcms::mount_point("/as/a")); s.run(); } //code end Browser accesses to URL "/as/a". The match strings and logs follows: match string log --------------- /as (none) .* /as/a as (none) a (none) /a (none) /as/a (none) That being said, only provided with script ".*" will mount_point() fire application "async_app": s.applications_pool().mount(as_app,cppcms::mount_point(".*")); Regards, CN |
From: CN <cn...@gr...> - 2011-02-01 15:29:47
|
Many thanks for the quick help! > you should provide a mount point > that would distinguish between them: > > See: > > - > http://art-blog.no-ip.info/cppcms_ref_v0_99/classcppcms_1_1applications__pool.html > > - > http://art-blog.no-ip.info/cppcms_ref_v0_99/classcppcms_1_1mount__point.html > Now I am trying to also provide mount() parameter mount_point but have trouble with the matching: //code begin class sync_app:public cppcms::application{ .... } class async_app:public cppcms::application { async_app(cppcms::service &srv) : cppcms::application(srv) { dispatcher().assign("(.*)",&async_app::catch_all,this,1); } void catch_all(std::string url) { BOOSTER_LOG(debug,"URL") << url; } } int main(int argc,char **argv) { cppcms::service s(argc,argv); s.applications_pool().mount(cppcms::applications_factory<sync_app>(),cppcms::mount_point("/s/a")); booster::intrusive_ptr<async_app> as_app=new interaction(s); //Watch the match string in the next line! s.applications_pool().mount(as_app,cppcms::mount_point("/as/a")); s.run(); } //code end Browser accesses to URL "/as/a". The match strings and logs follows: match string log --------------- /as (none) .* /as/a as (none) a (none) /a (none) /as/a (none) That being said, only provided with script ".*" will mount_point() fire application "async_app": s.applications_pool().mount(i,cppcms::mount_point(".*")); Any idea what mistake I have made? Regards, CN |