Re: [Cppcms-users] JSON-RPC dispatching together with Normal Web Page
Brought to you by:
artyom-beilis
From: Varstray Pl <var...@gm...> - 2020-11-10 22:32:41
|
Wow! Ok, so I took your information and ran with it, Jon. The information on CORS was definitely useful. Originally I thought I was going to have to set the necessary cors-compliant response headers in my webcomic.cpp code itself, but something was bugging me about it. My test environment is essentially from localhost:8080/webcomic, whereas the url given in the widgets.js getWidgets() method was just simply '/rpc'. So, to make absolutely sure that I wasn't engaging in any cross site scripting, I set the xmlhttprequest url to "http:localhost:8080/webcomic/rpc" . The response was actually a 404 status code, lol. Verifying the actual url that the browser tried to contact shed some light on the issue: It was "http:localhost:8080/webcomic/http:localhost:8080/webcomic/rpc". Aha! So the xml request was reaching the json_server backend after all! I didn't actually have much experience with the firefox developer console, but your information regarding how to manually trigger the getWidgets() method and view the response set me on the right track quickly. I was able to verify that the "Invalid JSON-RPC" string was actually coming from the response payload, indicating an issue in the CppCMS codebase itself. A quick bash command: for fd in `ls $SRCDIR`; do echo "In file: $fd" ; cat ./$fd | grep -e "JSON-RPC" ; done Revealed: In file: rpc_json.cpp throw call_error("Invalid JSON-RPC"); BOOSTER_DEBUG("cppcms") << "JSON-RPC Method call:" << method(); throw cppcms_error("JSON-RPC Request is not assigned to class"); Which led me to this snippet of code in rpc_json.cpp: if( request.type("method")!=json::is_string || request.type("params")!=json::is_array || request.type("id")==json::is_undefined) { throw call_error("Invalid JSON-RPC"); } Boom. That was the issue. My JSON request was originally {"method":"widgets"}, but it needed to be {"method":"widgets","params":[],"id":1}. Making the appropriate change and also updating the XMLHttpRequest url to "/webcomic/rpc" solved the issue 100%! Whew! Thank you very much for your help on this, Jon! I am DEEPLY grateful for all of this! Sincerely, VarstrayPl. On Mon, Nov 9, 2020 at 1:52 PM Jon Foster <jon...@jf...> wrote: > Glad to hear it. I've never actually used the C++CMS JSON RPC server class > because the docs leave too much unsaid, making it far simpler to write my > own handler. I think you might have to dig through the source to see what > its actually doing. I put together a test environment made from the > "clippings" you sent along and I'm not sure I made it as far as you did. > :-) What I'm seeing is the call dying in the CORS authentication phase > (OPTIONS req) my C++CMS app failing to respond with the appropriate > "allowed" response, in fact it says nothing and FF just drops the request. > > "CORS" is fairly recent pseudo-security feature. Its possible that C++CMS > is not prepared for it and a simple extension to the JSON RPC server class > may be needed. But I could be getting ahead of myself. > > The primary thing you need to do is fire up your browser's "dev tools". > The "console" section will allow you to call your javascript function, to > manually trigger requests to the server side. It should also log the > requests and responses made to your server. All XHR requests should come in > two phases the "OPTIONS" request to ask the server for permission, followed > by the actual JSON request you made, which would be a "POST" transaction. > Check the request and response to make sure your getting what you expect. > Often times what you see there will reveal the issue. > > I don't know your experience level so this page from MDN might be useful > in understanding CORS: > https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS > > Anyhow I have client needs to attend to or I'd drill the rest of the way > down. Use your browser's debugger and sprinkle "std::cerr << ..." stuff > liberally in your server side code to get a picture of what its doing. On > my setup I can call the RPC url with a generic client (browser, wget, curl, > ...) and get "invalid content type" so I know the request is getting > dispatched to the RPC handler. Yet an override of main() fails to show an > URL hit the application so the call must be getting blocked further up in > the class. maybe init()? Or I fat-fingered something? Like I said I'd have > to drill down on the source to figure out what its up to. > > I'll try to help out as I can. > > - Jon > > On 11/09/2020 09:29 AM, Varstray Pl wrote: > > Ah! Ok. So this is actually very helpful! > > I've decided to go with mounting the rpc server in the webcomic's url > space using the attach method you described above. The code for my webcomic > page constructor is as follows: > * * * > webcomic::webcomic(cppcms::service &srv) : cppcms::application(srv){ > attach(new json_service(srv), "rpc", "/rpc{1}", "/rpc(/(.*))?", 1); > //.. various dispatcher and mapper calls. > }; > *** > The browser now appears to be successfully calling the rpc server! Yay! > Unfortunately (there's always an unfortunately, isn't there? xD), I think I > haven't set up the handling of the rpc request properly within the server, > because instead of a proper response, the widgets panel is simply filled > with the text "Invalid JSON-RPC". I'm not sure where in the pipeline > things are going wrong, but here is how I've set up the rpc server. Maybe > you can see what I'm doing wrong? > > First, the basic class definition: > * * * > class json_service: public cppcms::rpc::json_rpc_server{ > public: > json_service(cppcms::service &srv); > > // Ajax Methods > void widgets(); > }; > * * * > > And then the implementation of the server constructor and the widgets > method: > * * * > json_service::json_service(cppcms::service &srv) : > cppcms::rpc::json_rpc_server(srv) > { > bind("widgets", cppcms::rpc::json_method(&json_service::widgets, > this),method_role); > } > > void json_service::widgets() > { > return_result("widgets via AJAX-RPC!!! Cool!"); > } > * * * > > Finally, this is how the request is set up on the client side via > javascript: > * * * > function getWidgets() { > var xhr = new XMLHttpRequest(); > xhr.open("post", '/rpc'); > > // Required by JSON-RPC over HTTP > xhr.setRequestHeader("Content-Type","application/json"); > > // Configure JSON-RPC request. > var request = '{"method":"widgets"}'; > > // Define our callback function. > xhr.onreadystatechange = function(){ > if (xhr.readyState === 4){ > var response; > > if (xhr.status === 200){ > response = xhr.responseText; > } else { > response = 'Invalid Status: ' + xhr.status; > } > > document.getElementById('widgets').innerHTML = response; > } > } > > xhr.send(request); > return false; > } > * * * > The javascript method is pretty much taken from the json-rpc tutorial on > the cppcms.com website. Although because this method doesn't take any > parameters(yet), I *think* perhaps the issue lies somewhere in the > modifications I made for sending a request for a non-parameter method, > whereas the tutorial method does take parameters. Also, up till this point, > diagnostic information on stderr and stdout has been very helpful, but now > there doesn't appear to be any stderr output at all, lol. > > I *can* verify that on the browser end the rpc call is actually being sent > to the rpc server, and because 'Invalid RPC-JSON' is different from > 'Invalid Status: bla bla', I think that the getWidgets() method is actually > getting a proper response from the rpc server. It's just clearly there's > something else going wrong somewhere. > * * * > > Thank you for your help, Jon, and sorry for any additional trouble. I'll > also keep searching on my end for an answer as well. ^^; > > > > > > > _______________________________________________ > Cppcms-users mailing lis...@li...https://lists.sourceforge.net/lists/listinfo/cppcms-users > > > -- > Sent from my Devuan Linux workstation -- https://devuan.org/ > "Init Freedom", Yeah! > > Jon Foster > JF Possibilities, In...@jf... > > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users > |