Wicket: redirect to shared resource - redirect

i've got a wicket form, which when submitted should give users a file to download. the file is generated by an external servlet (based on the form), which writes generated content to response's output stream.
normally this can be done using getRequestCycle().setRequestTarget(new RedirectRequestTarget(redirectUrl); on form submit, where redirectUrl will be the external servlet's url with parameters.
however, redirectUrl shows up in browser's address bar, which is not good as users see parameter values, which they shouldn't.
in order to overcome that, i've implemented a custom DynamicWebResource, which fetches the servlet output as byte[] and is bound to a virtual url through usual wicket shared resource mechanism.
on form submit i do the following:
RequestParameters rps = new RequestParameters();
rps.setResourceKey(new ResourceReference("myResource").getSharedResourceKey());
getRequestCycle().setRequestTarget(new SharedResourceRequestTarget(rps));
and then rely on wicket's internal ways of handling.
when debugging i can clearly see that my shared resource is correctly invoked, the external servlet's response is correctly generated, fetched and then written to current response with all the headers and stuff, but nothing happens after that, no errors, just nothing.
when i call my shared resource directly specifying the url wicket has bound it to (like http://localhost:8080/webAppRoot/wicket/myResource?param1=value) - everything works, file is well-formed and downloadable.
is there something additional i have to do? it's most probably something stupid, but i've been banging my head agains the wall for a day already...

problem solved. the reason for the response not to be processed by the browser was the fact that the form was submitted using AJAX. changing submit type to plain solved the issue.

Related

How to redirect the url from nested site in pencilblue?

I want to 301 redirect the URLs from previous site that are nested, as pencilblue doesn’t support them,
e.g. a/b to page/b
For this I have been experimenting in include/http/request_handler.js but facing some issues.
Call never comes inside RequestHandler.prototype.handleRequest or even RequestHandler.prototype.onSessionRetrieved (seems these methods are not being called from anywhere)
Therefore I placed the code in RequestHandler and after confirming that req is not for public resource or api, I create a new url and execute
return this.doRedirect(newUrl, 301)
This actually works but at the same time I receive
Can’t render headers after they are sent error
#1075 has not helped me much as I’m not sure which specific controller I should modify. I need to catch the req as early as possible and see if it’s a page then redirect to page prefixed url.
Thanks in advance.
There are couple of ways to do redirects. You can do them from a controller or from middleware. You are correct in that, some of the functions in the request handler are not called. These are deprecated despite the fact pencilblue team didn't mark them as such. They replaced a good deal of the request handler functionality with /include/http/router.js and include/http/middleware/index.js. Plugins can register their own middleware to hijack the request pipeline.
See Advanced Routing on wiki for more info about creating your own middleware.
Using the routing framework your plugin would be able to register middleware that would be able to inspect the request and then redirect based on your specific criteria. The Router will be accessible from req.router and from there you could call req.router.redirect (Source).
Reference: #1224

Action POST/GET in form submitting

GET is used to retrieve remote data, and POST is used to insert/update remote data
But when we use <form> to send data we can put in action either POST or GET and in both cases data will be sent. In this case data will not be retrieved or inserted just will be sent to the server.
Do these GET and POST methods in the <form> are not the same as GET and POST from the description above?
The form action will tell your browser how to send the form data.
In case of GEt the form data will be present as query string arguments, in case of POST as a multipart/form-data body. And, of course, this will also alter the method of the query (as GET or POST).
This is for the client part of the protocol.
Now, on the server side, GET and POST SHOULD not behave in the same way.
GET is indempotent
POST is not
It means the server (or the server chain, you could have a Reverse Proxy Cache in the chain) MUST expect that a POST is doing something to the application data, so the application or state is not the same after the POST (maybe you now have a session, or you've just deleted something, or added something). End this means you cannot re-play a POST two times without risks. In fact nobody should never replay the POST, that's one action.
If your form is posted as a GET that's a diffrent story. Your just asking for an url (wich contains your form data in the query string of the url), and you get a result, but replaying the same url several times SHOULD NOT be a problem, we could also cache the result and reuse this cached result for someone requesting the same url (so having the same elements in the form, which are now in the url).
So your application MUST NOT perform data alteration if the method is GET. Not deleting something, not creating something, etc.
So why would you send a form as GET? Maybe just to obtain a filtered page result where everybody should obtain the same page result with the same filters. But certainly not to post a registration form (or an admin-level-delete-this-user action).

Check if Sailjs backend is getting a legit req from the frontend without any authentication system

I do not want my users to authenticate. But I do not anyone to steal my data. So my goal is to only serve the people who make a req from the front end of the app. How can I do this ?
Is there a built in function that I'm missing ? I know that there are session id generated, but not sure how to incorporate the session id to this situation.
Thanks
By using the term "front end" I would assume that you have a client requesting data in the form of JSON/XML or HTML templates. My first suggestion to get your answer is to be much more descriptive in your question. It is very hard to answer without knowing how your client is designed.
Assuming your client is written in html/js and run in a browser then I would suggest that you serve a static file (in the form of a .js file or a <script></script> tag inside an html file) that generates a token. You can pass this token back to your server for validation on every request for data. This means that only your app (front-end) can be the only thing that requests data from your api (back-end).

Form Conversion from doPost to doGet

I have developed one application and facing issue with security stuff.
My application is running in doPost method which doesn't explicit the URL in browser. If I'm trying to change the doPost to doGet (using webdeveloper tools-->Forms), my application's URL will be displaying explicitly. So I need to throw an error/stop app response, If user tries to change the forms from doPost to doGet ?
I suppose the question here is: Why do you regard it as a security issue, that the URL might be displayed in the browser?
In case you don't want the user to have access to the URL or other request data, you probably have fundamental design problem, as the user can track the post request using the developer tools.
In case you don't want somebody else than the user to see the URL and thus think it should not be displayed in the browser, I would not worry, as the user has to actively and consciously "mess" with your application to achieve this behavior.
In general it is probably a good idea to throw errors and prevent the request from being processed if your front end does not behave as expected.

How do you implement resource "edit" forms in a RESTful way?

We are trying to implement a REST API for an application we have now. We want to expose read/write capabilities for various resources using the REST API. How do we implement the "form" part of this? I get how to expose "read" of our data by creating RESTful URLs that essentially function as method calls and return the data:
GET /restapi/myobject?param=object-id-maybe
...and an XML document representing some data structure is returned. Fine.
But, normally, in a web application, an "edit" would involve two requests: one to load the current version of the resources and populate the form with that data, and one to post the modified data back.
But I don't get how you would do the same thing with HTTP methods that REST is sort of mapped to. It's a PUT, right? Can someone explain this?
(Additional consideration: The UI would be primarily done with AJAX)
--
Update: That definitely helps. But, I am still a bit confused about the server side? Obviously, I am not simply dealing with files here. On the server, the code that answers the requests should be filtering the request method to determine what to do with it? Is that the "switch" between reads and writes?
There are many different alternatives you can use. A good solution is provided at the microformats wiki and has also been referenced by the RESTful JSON crew. As close as you can get to a standard, really.
Operate on a Record
GET /people/1
return the first record
DELETE /people/1
destroy the first record
POST /people/1?_method=DELETE
alias for DELETE, to compensate for browser limitations
GET /people/1/edit
return a form to edit the first record
PUT /people/1
submit fields for updating the first record
POST /people/1?_method=PUT
alias for PUT, to compensate for browser limitations
I think you need to separate data services from web UI. When providing data services, a RESTful system is entirely appropriate, including the use of verbs that browsers can't support (like PUT and DELETE).
When describing a UI, I think most people confuse "RESTful" with "nice, predictable URLs". I wouldn't be all that worried about a purely RESTful URL syntax when you're describing web UI.
If you're submitting the data via plain HTML, you're restricted to doing a POST based form. The URI that the POST request is sent to should not be the URI for the resource being modified. You should either POST to a collection resource that ADDs a newly created resource each time (with the URI for the new resource in the Location header and a 202 status code) or POST to an updater resource that updates a resource with a supplied URI in the request's content (or custom header).
If you're using an XmlHttpRequest object, you can set the method to PUT and submit the data to the resource's URI. This can also work with empty forms if the server supplies a valid URI for the yet-nonexistent resource. The first PUT would create the resource (returning 202). Subsequent PUTs will either do nothing if it's the same data or modify the existing resource (in either case a 200 is returned unless an error occurs).
The load should just be a normal GET request, and the saving of new data should be a POST to the URL which currently has the data...
For example, load the current data from http://www.example.com/record/matt-s-example and then, change the data, and POST back to the same URL with the new data.
A PUT request could be used when creating a new record (i.e. PUT the data at a URL which doesn't currently exist), but in practice just POSTing is probably a better approach to get started with.