Redirecting a GET request to another app's POST request in a rails controller - ruby-on-rails

I have a controller action that is triggered by a GET route, which under some conditions, I want to redirect to the POST route of another app on another server.
I'm aware of redirect_to "http://somewhere.com/thing_to_post_to" but there doesn't seem to be a way of specifying the http method. This intended for AJAX requests not pages, so it isn't acceptable to return a javascript to direct the browser.
Is this possible?

redirect_to uses HTTP status code to make the redirection, so it would likely be a GET, here's antoher explanation to use 307 status code
Response.Redirect with POST instead of Get?
but is not very well implemented among all browsers, so i suggest using a session variable to pass parameters among the views or something similar.

Related

Which RESTful action should I use to redirect to another site?

I have an app where I try to adhere to REST.
The app receives requests for external links that don't belong to the app, so the sole purpose of the action is to redirect the request to the external URL.
My suggestion is to have the following controller/action: redirects_controller#create.
Is my thinking correct or should it be the show action instead?
REST (apart from Rails) is about using the correct HTTP method for the correct action. The Rails part is just using the conventional controller action for a given HTTP method.
So, if you're doing a 301 or 302 redirect to another page, which browsers handle by issuing a GET request to the URL in the redirect response's Location header, do it in a show action. This will allow the user's browser to cache the other page when appropriate, and to not notify the user before redirecting.
(There is a way to redirect POSTs, but you didn't mention it so I expect you're talking about regular 301/302 redirects.)
Coming from a Java background, the REST actions must be related to CRUD operations. Requests that do not change the resource like in your case where the intent is to redirect to another page must be tied to a GET verb or show in your example.
If you were to create a new resource you would use POST.
A more detailed explanation can be found in Richardson's rest maturity model level 2

How send redirect as post request. Spring Security

i have my own AuthenticationSuccessHandler and overriding method onAuthenticationSuccess, where i need to redirect to some page with parameters from request before authenticate (i hope you understand what i mean, sorry for my english)
getRedirectStrategy().sendRedirect(request, response, targetUrl);
How can i do this with POST method (by default it is GET method)
You may do it without sendRedirect method using HTTP1.1 307 Temporary Redirect status code.
But AFAIK this is not a common practice and not all web browsers may support this.
Maybe server-side forward will suit your case.
Update:
If you want to send POST-redirect using spring-security API you may implement your own RedirectStrategy.
DefaultRedirectStrategy uses response.sendRedirect that will result in 302 response code sending by servlet container (I'm not sure about every container, at least tomcat sends 302).
Update 2:
You may send 307 back setting response status and "Location" header yourself:
resp.setStatus(SC_TEMPORARY_REDIRECT);
resp.setHeader("Location", absoluteRedirectUrl);
User-agent receiving this response must do next request using the same method that was used in previous request. So if first request was POST redirected request also will be POST.

asp.net mvc 2 -- losing authorization when RedirectToAction with JSON data

I'm refactoring some MVC code that originally used POST'ed form data. The form's fields are serialized using jquery's serialize() method and sent to an MVC controller Save Action that checks things out and redirects as appropriate (if errors in form values, redirect to the Edit Action, if fine then save and redirect to the Display Action). All actions are invoked via AJAX and return Partial Views. Everything works grand. Note: The site uses AD-based authorization, so users are prompted for their windows credentials upon first loading the site, but are never prompted again.
However, I'm now looking to interact with the server via JSON objects instead of form fields. Granted, I serialize the JSON object on the client and, with the aid of an imported MVC2 Futures/MVC3 class JsonValueProviderFactory, am able to correctly model bind the sent JSON object to a C# class in the Controller's parameters.
I maintain the same logic, but things start to blow up when I try to return a RedirectToAction ActionResult when the Controller accepts JSON objects. I lose authentication, the user is prompted for their credentials again, and I find myself in a infinite loop on the originally requested Action (save). Every time the user is prompted for credentials and simply runs through the Save Action again. The end result for the user is an unending alerts prompting for login credentials. Neither of the actions specified in the RedirectToAction calls are ever hit.
Can the fact that the original request uses a JSON contentType be interfering with the behavior of RedirectToAction? That's the only thing I can think of as it works fine when I don't use JSON to post and it works fine when I return PartialViews instead of using RedirectToAction. The infinite repeat of the Controller Action and continual loss of authorization credentials seems to suggest that RedirectToAction is not the way to go in this situation.
I can post code on request. I am also successfully handling stuff like copying the ModelState over to TempData and other RedirectToAction tricks. Again, it DOES work when using a non-JSON solution. Any insight is greatly appreciated!!
EDIT WITH FOLLOW-UP INFO:
Turns out, I get an "Unauthorized" error even when I completely disable NTLM authentication/authorization for the site. IIS server doesn't look for any authorization, web site doesn't look for any authorization, yet the error when trying to Redirect with JSON contentType request still occurs and complains of being "Unauthorized". This is WEIRD.
To update everyone, I haven't found a solution nor do I know for-sure what the situation is. However, I'm willing to bet it has to do with the fact that RedirectToAction issues http GET requests and the action I'm redirecting to only accepts POSTs. Even if I remove the restriction, it's still sending JSON data and it still needs to be done by POST.
In short, RedirectToAction with JSON data appears to be fundamentally undoable. You need to POST JSON data but RedirectToAction emits GET requests. That's my going theory, at least. =)

Ruby on Rails POST parameters on redirect_to

I have to make a call to a different url in one of my controllers on my site. The problem is that with all the parameters the other site requires I'm overflowing the url. Is there anyway to call another url from the controller and send all of the parameters using a POST?
I'm not expecting a response from the other site. Also, I think there's a way to do this using the Net::HTTP library thought I'm not sure how.
Thanks
You can't do a redirect and send POST data at the same time in the HTTP spec. Redirects are implemented by sending a simple Location: otherlocation.html header. POST data doesn't fit anywhere into that system.
Do you want the user to go to this page, or do you want to just send the data to the application yourself? If you want to send the data and not send the user there, use Ruby's Net::HTTP module. If you want to send the user, you may be forced to output a view with a form, and submit it automatically with Javascript. (Don't forget to degrade gracefully by offering a submit button in noscript tags.)
This is from the ruby docs:
require 'net/http'
require 'uri'
result = Net::HTTP.post_form(URI.parse('http://www.example.com/search.cgi'),
{'q'=>'ruby', 'max'=>'50'})
As you can see, you pass the params in as a convenient hash, unlike other languages that make you mess with http formatting.
You can also use the flash to transfer the information.
http://guides.rubyonrails.org/action_controller_overview.html#the-flash

Is it possible to make caches_action work for a rails controller method accessed via HTTP POST?

I have a controller action which could benefit from caching. However, when I turn on action caching via the usual:
caches_action :myaction, :expires_in=>15.minutes
...caching doesn't get invoked. It looks like this is because the action is invoked using an HTTP POST. For similar actions invoked using HTTP GET, caching works fine.
I realise using a POST for this action is probably not great style and breaks resource routing conventions - presumably this is also why the response isn't being cached, even though it could be. However for now I'm stuck with it as this is what the client currently does and I can't change it easily.
So, is there a way to force caching for this method even though it is accessed via POST?
edit: I should clarify perhaps that the POST has no side effects, so it is safe to cache the action. It really should have been a GET in the first place, it just isn't and can't easily be changed for now. Also it does not matter for this that browsers or proxies won't cache the response.
Are the contents of the post data the same every post? I suspect they arent and this is why the action wont cache.
A couple of ways to deal with this:
1) Forget about caches_action and use Rails.cache easily inside your controller to cache the expensive parts of your controller code
2) Use Rack Middleware/ Metal Endpoint to receive the post data from the other application and shoehorn the data to the shape you want.
edit:
Im running Rails 2.3.3 and i can confirm that it does cache POST requests
For the purpose of checking while your developing make sure you have set perform_caching to true in development.rb :
config.action_controller.perform_caching = true
Also make sure its the same in production.rb
I tested this scenario with the following in my controller :
caches_action :index
def index
#listings = Listing.find(:all)
end
Using both GET and POST requests this cached as expected.
Also i tried setting the http headers Cache-Control: no-cache on my post client and the action still cached
If you're running OSX use this awesome tool http://ditchnet.org/httpclient/ to create GET and POST requests

Resources