I am trying to implement a simple server in Ruby, but somehow I can't get the data from a put request.
curl request that I am making:
curl -v -X PUT localhost:2016/api/kill -d {"connId" : 1}
The server seems to be reading the request alright.
The code:
while line = socket.gets
puts line.chomp
request << line.chomp
break if line =~ /^\s*$/
end
produces the output:
PUT /api/kill HTTP/1.1
User-Agent: curl/7.35.0
Host: localhost:2016
Accept: */*
Content-Length: 7
Content-Type: application/x-www-form-urlencoded
But I don't see the data anywhere?
Am I supposed to see it?
Is something wrong with the curl request?
You need single quotes around the body.
curl -v -X PUT localhost:2016/api/kill -d '{"connId" : 1}'
Related
I am trying to call an API using Curl. The request was timing out after 60 secs due to TCP Timeout. I added "-H "Connection: keep-alive" -H "Keep-Alive: timeout=90, max=100" to the existing code.
curl -s -X POST -u $regressionTestAuthToken -H Content-Type: application/json -H Accept: application/json -H "Connection: keep-alive" -H "Keep-Alive: timeout=90, max=100" $URL -d#"${WORKSPACE}"/tmp.json > "${WORKSPACE}"/out.json
After adding the Connection Keep-Alive, I am getting a parse error
parse error: Invalid numeric literal at line 1, column 7
Can someone help me to triage this issue?
I am writing shell scripts in macOS 11.1 Big Sur to test several endpoints thru cUrl request. To improve my scripts, I would love to do the following:
send the curl request
store the response code to a variable in an array
store part of the response payload to another variable
I can not share the exact endpoint since that would be a security breach for others to test their solutions, unfortunately.
In example, using a modified request from one of my scripts:
#!/bin/sh
EMAIL_USERNAME=`date "+%Y%m%d%H%M%S"`
curl -iX POST 'http://test.someclientcloud.com/api/online/customer/register' -H 'Connection: keep-alive' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache' -H 'Authorization: XXXXXXXXXXXXXXX' -H 'Accept: application/json' -H 'X-Origin-Source: WWW' -H 'Content-Type: application/json' -H 'Accept-Language: en-US,en;q=0.9,pt;q=0.8' --data-binary $'{ "emailAddress": "'$EMAIL_USERNAME'#xxxxxx.com", "firstName": "Terminate", "lastName": "ME", "opt": true, "password": "Password7654!", "phoneNumber": "555229'$TODAY'", "regCity": "Anytown", "regCountryCode": "1", "regState": "TX", "regZip": "86753", "username": "'$EMAIL_USERNAME'#xxxxx.com" }'
The curl response is:
HTTP/1.1 201 Created
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: close
Date: Wed, 06 Jan 2021 18:40:38 GMT
Pragma: no-cache
Transfer-Encoding: chunked
Location: /api/customer/354190751
Expires: 0
requestDuration: 67
X-Frame-Options: DENY
X-Origin-Source: WWW
X-Content-Type-Options: nosniff
proxyUser: WWW
X-XSS-Protection: 1; mode=block
X-Application-Context: application:production
The two things I would like from that response are 201 for the response code, from the first line of the response.
And 354190751 from the end of line 7 of the response above.
I can use these responses to form a report at the end of the script of each response per request. And I can use the newly created customer number in further tests within the script to modify the account further or delete the account for clean up at the end of the test.
I suspect this can be done with clever regex? My regex level is only moderately dangerous.
To be clear, I will mention, this is Apple Shell Scripting in macOS 11.1 Big Sur. Variants of shell scripting are many.
Hopefully the question was clear, thank you for your help.
Added that this is macOS 11.1 Big Sur
Unfortunately, while curl lets you ask it to directly write the status code, that doesn't extend to individual headers -- so you need to do the pattern matching yourself. One way to do that is as follows (note the use of process substitution syntax to avoid the issues discussed in BashFAQ #24, which makes this incompatible with /bin/sh; that said, because your code uses ANSI C-like string syntax, aka $'', it isn't compliant with the sh standard regardless):
#!/usr/bin/env bash
# put your actual curl code here; using a stub here so others can test
getCurlOutput() {
cat <<'EOF'
HTTP/1.1 201 Created
Transfer-Encoding: chunked
Location: /api/customer/354190751
Expires: 0
EOF
}
code=
customer=
{
read _ code _
prefix="Location: /api/customer/"
while IFS= read -r line; do line=${line%$'\r'}
case $line in
"$prefix"*) customer=${line#$prefix};;
esac
done
} < <(getCurlOutput)
echo "Retrieved exit status $code"
if [ -n "$customer" ]; then
echo "Customer id retrieved is $customer"
fi
This question already has answers here:
Does a `+` in a URL scheme/host/path represent a space?
(6 answers)
Closed 3 years ago.
I am having some issues with Ruby's OpenURI follow redirect functionality.
When going to a URL that contains %20 in it, and that redirects with a 30x, Ruby's OpenURI fails.
The exact same URL, with a + instead of %20 works.
Both the %20 and + versions work properly with curl -L (follow).
Code
require 'open-uri'
base = "http://software-engineering-handbook.com/Handbook"
puts "===> PASS: URI Open +"
result = open "#{base}/Video+Series"
p result.status
puts "===> PASS: Curl +"
puts `curl -LIsS "#{base}/Video+Series" | grep HTTP`
puts "===> PASS: Curl %20"
puts `curl -LIsS "#{base}/Video%20Series" | grep HTTP`
puts "===> FAIL: URI Open %20"
begin
result = open "#{base}/Video%20Series"
p result.status
rescue => e
puts "#{e.class} #{e.message}"
end
Output
===> PASS: URI Open +
["200", "OK"]
===> PASS: Curl +
HTTP/1.1 200 OK
===> PASS: Curl %20
HTTP/1.1 303 See Other
HTTP/1.1 200 OK
===> FAIL: URI Open %20
OpenURI::HTTPError 302 Found (Invalid Location URI)
I am not sure what is going on here. Tried HTTParty (although I know it is just a wrapper), hoping to see a different behavior, but it also fails.
The server is responding with an redirect to an invalid URI. curl is being lax about it, but Ruby is being strict.
If we print out the e.cause we get more information.
#<URI::InvalidURIError: bad URI(is not URI?): "http://software-engineering-handbook.com/Handbook/Video Series/">
And also by looking at the headers from curl -I 'http://software-engineering-handbook.com/Handbook/Video%20Series'...
HTTP/1.1 303 See Other
Server: Cowboy
Date: Sat, 28 Dec 2019 21:41:28 GMT
Connection: keep-alive
Content-Type: text/html;charset=utf-8
Location: http://software-engineering-handbook.com/Handbook/Video Series/
And, indeed, the server is returning an invalid URI. Spaces are not allowed in a URI path. Ruby's URI class will not parse it.
> URI("http://software-engineering-handbook.com/Handbook/Video Series/")
URI::InvalidURIError: bad URI(is not URI?): "http://software-engineering-handbook.com/Handbook/Video Series/"
from /Users/schwern/.rvm/rubies/ruby-2.6.5/lib/ruby/2.6.0/uri/rfc3986_parser.rb:67:in `split'
I am calling the same curl command once from terminal and once from Shellscript - but the outcome is different:
#!/usr/bin/env bash
url="dev.test.ch"
http="http://"
test="192.168.178.107"
curl -H "'Host: $url'" "$http$test"
echo "'Host: $url'" "$http$test"
and
curl -H 'Host: dev.test.ch' http://192.168.178.107
Once I get the NGINX Startpage (from Shellscript) and once the right response (HTML Page from my App)
Any ideas?
Stupid me -
curl -H 'Host: '$newline "$http$test"
the braces were the problem.
You can use curl with -v option to see what exactly HTTP request was sent to server. Problem that in your script you curl adds 'Host header.
With this line curl -H "'Host: $url'" "$http$test" it sends
> GET http://192.168.178.107/ HTTP/1.1
> Host: 192.168.178.107
> User-Agent: curl/7.49.1
> Accept: */*
> 'Host: dev.test.ch'
If you remove single qoutes curl -v -H "Host: $url" "$http$test" it will send proper request:
> GET http://192.168.178.107/ HTTP/1.1
> Host: dev.test.ch
> User-Agent: curl/7.49.1
> Accept: */*
I am sending the following curl request to my Ruby Driver
curl -i -X POST -H "Content-Type:application/json" -d '{ "firstName" : "Frodo", "lastName" : "Baggins" }' http://localhost:4567/new_document/?
This is the code for the POST operation in ruby.
post '/new_document/?' do
content_type :json
db = settings.mongo_db
result = db.insert_one params
db.find(:_id => result.inserted_id).to_a.first.to_json
end
I get the following response in the console.
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 43
X-Content-Type-Options: nosniff
Server: WEBrick/1.3.1 (Ruby/2.0.0/2013-11-22)
Date: Tue, 10 Nov 2015 18:38:59 GMT
Connection: Keep-Alive
{"_id":{"$oid":"564239c3e89bde194d000007"}}
As you can see the fields first and last name never get created. What am I doing wrong?
Figured it out! This creates the correct fields and their values.
curl -d 'name=adam&last=hoffman' http://localhost:4567/new_document/?