RestClient POST doesn't display status on header-only response - ruby

I have a Rails action which responds with head :ok, rather than rendering any content. I'm calling this action using RestClient, like so:
resp = RestClient.post("#{api_server_url}/action/path", {:param_1 => thing, :param_2 => other_thing}, :authorization => auth)
The Rails server log shows that this worked as expected:
Completed 200 OK in 78ms (ActiveRecord: 21.3ms)
However, the resulting value of resp is the string " ", rather than an object I can examine (to see what its status code is, for instance).
I tried changing the action to use head :created instead, just to see if it produced a different result, but it's the same: " ".
How can I get the status code of this response?

RestClient.post returns an instance of the class RestClient::Response that inherits from the String class.
You can still check the return code by calling the method code resp.code. Other methods are for example resp.headers and resp.cookies.

Related

Why is my AJAX request failing?

I'm trying to learn to use AJAX with Rails.
Here is my client side coffeescript code:
$(document).ready ->
$("#url").blur ->
$.get("/test_url?url=" + $(this).val(), (data) ->
alert("Response code: " + data)
).fail( () ->
alert("Why am I failing?")
)
Here is my server-side Ruby code:
def url_response
url = URI.parse(params[:url])
Net::HTTP.get_response(url).code unless url.port.nil?
end
The Ruby code is being called and correctly returns the HTTP response code, but I can't do anything with the data because the client-side script says the call has failed. As far as I can see, it is not failing. url_response is being called and it is returning a value, so what exactly is failing here?
The problem was I removed the line that rendered the response. I previously had in, but thanks to Frederick Cheung's hint to check if the URL works directly in the browser, I realised that it no longer worked in the browser as it did previously, which is why I didn't think to check again!
The code below got everything working again.
def url_response
url = URI.parse(params[:url])
render :text => Net::HTTP.get_response(url).code unless url.port.nil?
end

(REDDIT) Error trying to subscribe to subreddits via API

I know that Snoo seems to be unmaintained, but I wanted to use a ruby framework since I'm trying to improve my Ruby skill.
I'm trying to add some functionality starting with subscribing and unsubscribing to subreddits. Link to API doc.
My first attempt was with the built-in post method which returned a 404 error
def subscribe(subreddit)
logged_in?
post('/api/subscribe.json',body:{uh: #modhash, action:'sub', sr: subreddit, api_type: 'json'})
end
Since the built-in post method was giving me a 404 I decided to try the HTTParty post method:
def subscribe(subreddit)
logged_in?
HTTParty.post('http://www.reddit.com/api/subscribe.json',body:{uh: #modhash, action:'sub', sr: subreddit, api_type: 'json'})
end
That returns this:
pry(main)> reddit.subscribe('/r/nba')
=> {"json"=>{"errors"=>[["USER_REQUIRED", "please login to do that", nil]]}}
Does anyone know if I need to pass more info in the body or if I'm just sending a badly formed request? Thanks!
Also, before running "reddit.subscribe" I have verified that I'm logged in with with a cookie, a modhash, can access my account info, etc.
Solution found:
def subscribe(subreddit)
#query the subreddit for it's 'about' info and get json back
subreddit_json = self.subreddit_info(subreddit)
#build the coded unique identifier for the targeted subreddit
subreddit_id = subreddit_json['kind'] + "_" + subreddit_json['data']['id']
#send post request to server
server_response = self.class.post('/api/subscribe.json',
body:{uh:#modhash, action:'sub', sr: subreddit_id, api_type:'json'})
end
The Reddit API doesn't accept the subreddit name as the value passed with 'sr', (e.g. sr:'/r/funny'). It requires the subreddit "type" (which is always 't5' for subreddits) and unique forum id. The parameter passed would look something like: sr: "t5_2qo4s". This information is available if you go to your target subreddit and add about.json, e.g., www.reddit.com/r/funny/about.json

Is their a way to create Dummy Response with 500 code in HTTParty

Here my HTTParty code
response = HTTParty.post(api_url,body: form_data,timeout: 5)
rescue Timeout::Error
## create dummy response with 500 error code
response = HTTParty::Response.new()
ensure
response
all I'm trying to do is ensure If the HTTParty is unable to connect the given website create a dummy response body objec
But when I try to create a dummy Response object like this
## response = HTTParty::Response.new(Rack::Request.new(api_url),Rack::Response.new('TimeOut Error',500),'TimeOutError')
but this does not work because my response object does not respond_to to_hash
Can anyone suggest a better way to accomplish the same
In case anybody comes looking after 4 years, one could try the following:
httparty_req = HTTParty::Request.new Net::HTTP::Get, '/'
nethttp_resp = Net::HTTPInternalServerError.new('1.1', 500, 'Internal Server Error')
response = HTTParty::Response.new(httparty_req, nethttp_resp, lambda {''}, body: '')

Ruby's Net::HTTP doesn't get the right answer from google OAuth server

I'm writing a small cli tool, that should check my calendar and do some stuff according to my appointments.
I'm struggling a little bit with the OAuth2 authentication. I've checked the scope and the client_id with the curl tool like this:
curl -d "client_id=12345...&scope=scope=https://www.googleapis.com/auth/calendar.readonly" https://accounts.google.com/o/oauth2/device/code
This way, I get the right response.
{
"device_code" : "somestuff",
"user_code" : "otherstuff",
"verification_url" : "http://www.google.com/device",
"expires_in" : 1800,
"interval" : 5
}
But, when I try to use Net::HTTP in Ruby I just get HTTP state 200. I've done it this way:
res = Net::HTTP.post_form(uri, {'client_id' =>'1234....apps.googleusercontent.com', 'scope' => 'https://www.googleapis.com/auth/calendar.readonly' })
If I check the res variable afterwards I get the state 302, but I guess this is correct.
Can someone tell me what I'm, doing wrong so I don't get the JSON response? Should I try something different than Net::HTTP?
res is a variable containing all the response data, not just the text of the response. If you puts res.body after your post_form() call, you should find your JSON (which you can parse with the JSON module).

How to parse HTTP response using Ruby

I've written a short snippet which sends a GET request, performs auth and checks if there is a 200 OK response (when auth success). Now, one thing I saw with this specific GET request, is that the response is always 200 irrespective of whether auth success or not.
The diff is in the HTTP response. That is when auth fails, the first response is 200 OK, just the same as when auth success, and after this then there is a second step. The page gets redirected again to the login page.
I am just trying to make a quick script which can check my login user and pass on my web application and tell me which auth passed and which didn't.
How should I check this? The sample code is like this:
def funcA(u, p)
print_A("#{ip} - '#{u}' : '#{p}' - Pass")
end
def try_login(u, p)
path = '/index.php?uuser=#{u}&ppass=#{p}'
r = send_request_raw({
'URI' => 'path',
'method' => 'GET'
})
if (r and r.code.to_i == 200)
check = true
end
if check == true
funcA(u, p)
else
out = "#{ip} - '#{u} - Fail"
print_B(out)
end
return check, r
end
end
Update:
I also tried adding a new check for matching a 'Success/Fail' keyword coming in HTTP response. It didn't work either. But I now noticed that the response coming back seems to be in a different form. The Content-Type in response is text/html;charset=utf-8 though. And I am not doing any parsing so it is failing.
Success Response is in form of:
{"param1":1,"param2"="Auth Success","menu":0,"userdesc":"My User","user":"uuser","pass":"ppass","check":"success"}
Fail response is in form of:
{"param1":-1,"param2"="Auth Fail","check":"fail"}
So now I need some pointers on how to parse this response.
Many Thanks.
I do this with with "net/http"
require 'net/http'
uri = URI(url)
connection = Net::HTTP.start(uri.host, uri.port)
#response = Net::HTTP.get_response(URI(url))
#httpStatusCode = #response.code
connection.finish
If there's a redirect from a 200 then it must be a javascript or meta redirect. So just look for that in the response body.

Resources