Thread: Re: [Cppcms-users] Problem with cppcms::application::add() method
Brought to you by:
artyom-beilis
From: Artyom <art...@ya...> - 2010-11-11 20:39:30
|
> >void application::add(application &app,std::string regex,int part) >{ > add(app); > url_dispatcher().mount(regex,app,part); >} > >The code above has an error, the correct code is: >dispatcher().mount(regex,app,part); > add or attach member functions do only one thing - they share the http::context class between all connected applications. Otherwise you'll just have an exception trying to access anything like request() or response() of any class that wasn't added. On the other hand url_dispatching is just a simple way to "split" your main function according to requests between its own member function and other sub applications. There are different tasks and they both required (unless you wan't to do something on your own in main rather then standard URL-dispatching) > Second problem: > > When I attach or add an application B to an application A, > the method "void B::main(std::string url)" is never > called on url dispatch stage. When you mount a sub application you just extract sub expression and pass it to mounted application. I.e. add(users_app) add(uploads) urd_dispatched().mount("/users(/.*)",users_app,1); urd_dispatched().mount("/uploads(/.*)",uploads,1); And then in constructor of users you mount url_dispatcher().attach("/login",&users_class::login,this); when you hit /users/login /users/login is matched against "/users(/.*)" regex and passed to users_app.main() with parameter "/login" then it matched by users_app's url_disptacher against "/login" regex and passed to login member function of users_app instance. So you need both steps and understand how they work. > This behaviour causes problems when adding cppcms::rpc::json_rpc_server > application because the parsing of the request is made in json_rpc_server::main > > method. > The result is that the application does not work. adding application has nothing to do with URL dispatching, url_disptaching just allows you to forward request to other app's main function. > in cppcms::rpc::json_rpc_server application: URL mapping with > dispatcher().assign() method does not work because main method overwriting. When you develop json_rpc server you suppose to rather bind member function by remote procedure functions (i.e. RPC service function = member function) rather then using URL-dispatching method suitable for ordinary web applications. So it is done by design. Artyom |
From: Daniel V. <chi...@gm...> - 2010-11-12 00:03:52
|
Hello. I use the latest cppcms revision. I answer between the lines below. Thanks. On Thu, 2010-11-11 at 12:39 -0800, Artyom wrote: > > > >void application::add(application &app,std::string regex,int part) > >{ > > add(app); > > url_dispatcher().mount(regex,app,part); > >} > > > >The code above has an error, the correct code is: > >dispatcher().mount(regex,app,part); > > You write "url_dispatcher()" in the above method definition. As you know url_dispatcher() makes an anonymous instance of cppcms::url_dispatcher class. I suspect that your intentions are to call dispatcher() method instead. > > add or attach member functions do only one thing - they share the http::context > class between all connected applications. > > Otherwise you'll just have an exception trying to access anything like request() > > or response() of any class that wasn't added. > > On the other hand url_dispatching is just a simple way to "split" your main > function according to requests between its own member function and other sub > applications. > > There are different tasks and they both required (unless you wan't to do > something on > your own in main rather then standard URL-dispatching) They are diferent task, I understand, but the method add(application &app,std::string regex,int part) makes these two tasks. > > > Second problem: > > > > When I attach or add an application B to an application A, > > the method "void B::main(std::string url)" is never > > called on url dispatch stage. > > When you mount a sub application you just extract sub expression and > pass it to mounted application. I.e. > > add(users_app) > add(uploads) > urd_dispatched().mount("/users(/.*)",users_app,1); > urd_dispatched().mount("/uploads(/.*)",uploads,1); I can't use that interface because the mount() method is private. The code add(users_app); dispatcher().mount("/users(/.*)",u,1); raise the error cppcms/url_dispatcher.h:160: error: ‘void cppcms::url_dispatcher::mount(std::string, cppcms::application&, int)’ is private main.cpp:30: error: within this context For that reason I use the shortcut method add(application &app,std::string regex,int part). > And then in constructor of users you mount > > url_dispatcher().attach("/login",&users_class::login,this); > > when you hit /users/login > > /users/login is matched against "/users(/.*)" regex and passed to > users_app.main() > with parameter "/login" > > then it matched by users_app's url_disptacher against "/login" regex and passed > to login > member function of users_app instance. > > So you need both steps and understand how they work. > > > This behaviour causes problems when adding cppcms::rpc::json_rpc_server > > application because the parsing of the request is made in json_rpc_server::main > > > > method. > > The result is that the application does not work. > > adding application has nothing to do with URL dispatching, url_disptaching just > allows > you to forward request to other app's main function. I wrote an small example that reproduces the issue: #include <cppcms/application.h> #include <cppcms/service.h> #include <cppcms/applications_pool.h> #include <cppcms/url_dispatcher.h> #include <cppcms/http_response.h> #include <iostream> class users : public cppcms::application { public: users(cppcms::service& srv): application(srv) { dispatcher().assign("/login$", &users::login, this); } void main(std::string url) { response().out() << "into users::main(\""<< url <<"\")\n"; cppcms::application::main(url); } void login() { response().out() << "into users::login()\n"; } }; class main_app : public cppcms::application { public: main_app(cppcms::service& srv) : application(srv), u(srv) { add(u,"/users(/.*)",1); //add(u); //dispatcher().mount("/users(/.*)",u,1); } void main(std::string url) { response().out() << "into main_app::main(\""<< url <<"\")\n"; cppcms::application::main(url); } private: users u; }; int main(int argc, char **argv) { try { cppcms::service srv(argc, argv); srv.applications_pool().mount( cppcms::applications_factory<main_app>()); srv.run(); } catch(std::exception const &e) { std::cerr << e.what() << std::endl; return 1; } return 0; } Test cases: A - Test url: .../users/login result: "into users::login()" That's ok. B - Test url: .../users/foo result: "into main_app::main("/users/foo")" That's no ok, because the espected result is "into users::main("/foo")". The users::main() method is never called. Am I wrong? If you don't change "url_dispatcher()" to "dispatcher()" in add(application &app,std::string regex,int part) definition then the A test also fails. > > in cppcms::rpc::json_rpc_server application: URL mapping with > > dispatcher().assign() method does not work because main method overwriting. > > When you develop json_rpc server you suppose to rather bind member function > by remote procedure functions (i.e. RPC service function = member function) > rather then using URL-dispatching method suitable for ordinary web applications. > > So it is done by design. > > Artyom > > > > > > ------------------------------------------------------------------------------ > Centralized Desktop Delivery: Dell and VMware Reference Architecture > Simplifying enterprise desktop deployment and management using > Dell EqualLogic storage and VMware View: A highly scalable, end-to-end > client virtualization framework. Read more! > http://p.sf.net/sfu/dell-eql-dev2dev > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users |