From Ruby to Perl, Post data is disappearing - ruby

I'm trying to mimic the following curl command that works perfectly:
curl -k -i -d #content.json -H "Content-Type: application/json" -H "Accept: applicaztion/json" https://localhost:909/api/authenticateUser
I'm mimicking the curl command in Ruby/rails. I'm using the rest-client gem. The target is an API written in old-style Perl. The problem is that the API does NOT "see" the payload that is sent in the new ruby code:
pload = '<string>'.to_json
response = RestClient::Request.execute(url: 'https://localhost:909/api/authenticateUser', method: :post, payload: pload, accept: :json, content_type: :json, verify_ssl: false)
What is going wrong? Is my Ruby code bad or is the Perl code "too stupid/old" to pick up the payload from ruby. This is the Perl code:
my $data = $cgi->param('POSTDATA') || "";
I tend to think the problem is with my ruby code since the old Perl code receives the payload properly from the curl command above and from some other old Perl code.
Thanks for the help.

For POSTDATA to be populated,
The request must have a Content-Length header
The value of the request's Content-Length header must be non-zero.
The request method must be POST.
The request must have a Content-Type header.
The value of the request's Content-Type header must not include any of the following:
application/x-www-form-urlencoded
multipart/form-data
application/xml
multipart/related

Related

How can one use CURL to send a shell script as the POST body to Tornado?

It is unclear to me how Tornado expects to parse body arguments for all content types. It makes sense for JSON, and maybe form data, but for other body content types it is unclear to me how to format the request with CURL to get it to work.
Question: How can one use CURL to send a shell script as the POST body to Tornado? What is the formatting for the body arguments?
What I've tried:
curl -X POST -H "Content-Type: application/x-sh" http://localhost:8888/ -d script='#!/bin/bash \necho "scale=500\; 4*a(1)" | bc -l'
What I would hope or expect this to do is for Tornado to process the HTTP body so that (1) the body argument is script, and (2) the value corresponding to it is the shell script to compute pi:
#!/bin/bash
echo "scale=500\; 4*a(1)" | bc -l
Instead I just get a 400: Bad Request error, and my debugging logs show that the value of self.request.body_arguments is an empty dictionary {}.
You're sending POST data with this header - Content-Type: application/x-sh. But Tornado only supports application/x-www-form-urlencoded to parse submitted form/POST data.
Just submit the data with Content-Type: application/x-www-form-urlencoded and Tornado will make the submitted data available in body_arguments.

How to transform a CURL query to OpenURI query with OATH

One of my projects returns token codes using an HTTP query so users easily can get and renew them if desired. I found one article where the author uses CURL queries to my host.
For example:
curl -k -H 'Authorization: Bearer SQ43OPLR79BIQQFN50PA6KI8MVJ77JT685V0S9TTRNNA6RO41DTA6FK7NR1H466C' -H 'User-Agent: api-test-agent' https://api.hh.ru/employers/2062418
It works and returns a JSON object.
I need an OpenURI-based query. How can I change this CURL command to a simple OpenURI call?
The equivalent request through open-uri is:
require 'open-uri'
puts open('https://api.hh.ru/employers/2062418',
'Authorization' => 'Bearer SQ43OPLR79BIQQFN50PA6KI8MVJ77JT685V0S9TTRNNA6RO41DTA6FK7NR1H466C',
'User-Agent' => 'api-test-agent'
).read

How to access *incoming* headers in Sinatra?

I'm sending a request to a Sinatra application by this:
curl -X POST --header "MyHeader: 123444" http://localhost:9292/test -d ""
How can I access it in the route? These don't work:
headers["MyHeader"]
request["MyHeader"]
request.env["MyHeader"]
They're all nil.
Have you tried adding HTTP to the header name? So it would be request.env["HTTP_ MyHeader"] This is part of the rack spec.

Ruby JSON.parse error

I am building a script that uses a cURL command against an API. I send the cURL command formatted as an application/json request and get the result, which I parse into a Ruby hash.
This works great when I use cURL POST commands, getting the correctly formatted JSON responses. However, when using cURL GET commands I am returned a JSON document that has headers:
puts r:
HTTP/1.1 200 OK
X-Compute-Request-Id: req-7e625990-068b-47d1-8c42-9d3dd3b27050
Content-Type: application/json
Content-Length: 1209
Date: Wed, 16 Jan 2013 20:47:41 GMT
{ <JSON DATA> }
When I try and do a JSON.parse(r) I get an unexpected token error at 'HTTP/1.1.'.
My method for this:
def list_flavors
r = %x(curl -s -k -D - -H \"X-Auth-Token: #{$token}\" -X 'GET' http://10.30.1.49:8774/v2/27e60c130c7748f48b0e3e9175702c30/flavors -H 'Content-type: application/json')
response = JSON.parse(r)
response
end
Is there a way to use regular expressions to pull the body out of the JSON doc and then parse?
Or am I going about this the wrong way when getting the response from cURL?
You'll need to find a way to cut out that header before passing the string into JSON.parse. JSON.parse expects valid json only.
Rather than curling and using the thing wholesale as a string, I'd suggest you use the very versatile ruby Net::HTTP and/or OpenURI libraries, which will allow you to easily access just your response's body without the header.

Cannot accept post in Sinatra using Curl

Just been tinkering with Sinatra and trying to get a bit of a restful web service going.
The error I'm getting at the moment is very specific though.
Take this example post method
post '/postMan/:someParam' do
#Edited here. This code can be anything. 411 is still the response
puts params[:someParam]
end
Seems simple enough. Take a param, make an object out of it, then go store it in whatever way the objects save method defines.
Heres what I use to post the data using Curl
$curl -I -X POST http://127.0.0.1/postman/123456
The only problem is, I'm getting 411 back and have no idea why.
To the best of my knowledge, 411 is length required. Here is the trace
HTTP/1.1 411 Length Required
Content-Type: text/html; charset=ISO-8859-1
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Fri, 02 Mar 2012 22:27:09 GMT
Content-Length: 303
Connection: close
I 'Cannot' change the curl message in any way. So might anyone have a way to set the content length to be ignored in sinatra? Or some fix which doesn't involve changing the curl request?
For the record, it doesn't matter whether I use the parameters in the Post method or not. I could have some crazy code inside it, it will still throw the same error
As others said above, WEBrick wrongly requires POST requests to have a Content-Length header. I just pass an empty body, because it's less typing than passing in the header:
curl -X POST -d '' http://webrickwhyyounotakeemptyposts.com/
Are you sure you're on port 80 for your app?
When I run:
ruby -r sinatra -e "post('/postMan/:someParam'){puts params[:someParam]}"
and curl it:
curl -I -X POST http://127.0.0.1:4567/postMan/123456
HTTP/1.1 200 OK
X-Frame-Options: sameorigin
X-XSS-Protection: 1; mode=block
Content-Type: text/html;charset=utf-8
Content-Length: 0
Connection: keep-alive
Server: thin 1.3.1 codename Triple Espresso
it's ok. Had to change the URL to postManthough, your example threw a 404because you had postman.
The output was also as expected:
== Sinatra/1.3.2 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.3.1 codename Triple Espresso)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:4567, CTRL+C to stop
123456
Ah. Try it without -I. It's probably sending a HEAD request and as such, not sending what you expect. Use -v if you want to show the headers.
curl -v -X POST http://127.0.0.1/postman/123456
curl -v -X POST -d "key=val" http://127.0.0.1/postman/123456
WEBrick erroneously requires POST requests to include the Content-Length header.
curl -H 'Content-Length: 0' -X POST http://example.com
Standardly, however, POST requests don't require a body and therefore don't require the Content-Length header.

Resources