Making a POST request with Chef - ruby

I need to post a .json file to a server with a rest API with a Chef recipe, following Chef's documentation I came up with this code:
http_request '/tmp/bpp.json' do
url 'http://localhost:8080/api/v1/blueprints/bpp'
headers ({
'AUTHORIZATION' => "Basic #{Base64.encode64(user)}",
'CONTENT-TYPE' => 'aplication/json'
})
action :post
end
For authorization token, user is a variable that contains 'user:password'
When I run this chef recipe I obtain the following response:
Error executing action `post` on resource 'http_request[POST /tmp/bpp.json]'
Net::HTTPServerException
------------------------
400 "Bad Request"
Prior to this I was just executing a curl call and it was working fine, but I need to change to the http_request resource. This was the old (working) curl request:
curl --user user:password -H 'X-Requested-By:My-cookbook' --data #/tmp/bpp.json localhost:8080/api/v1/blueprints/bpp
I am not very used with REST apis and seems like an uncharted territory to me.

You forget about message. Using file name as resource name won't send this file as data. Try adding:
...
message lazy { IO.read('/tmp/bpp.json') }
...
In your case only the resource name - /tmp/bpp.json, will be sent. Not a file content. As stated in linked doc:
The message that is sent by the HTTP request. Default value: the name of the resource block See “Syntax” section above for more information.

Related

Content-type header not supported

I am following this link for elasticsearch.
https://www.elastic.co/blog/a-practical-introduction-to-elasticsearch
I am trying following curl to post the json data.
curl -XPOST "http://localhost:9200/shakespeare/_bulk?pretty" --data-binary #D:\data\shakespeare.json
But I am getting error like below:
{
"error" : "Content-Type header [application/x-www-form-urlencoded] is not supported",
"status" : 406
}
You need to set the content type in the header to application/json:
curl -XPOST -H "Content-Type: application/json" "http://localhost:9200/shakespeare/_bulk?pretty" --data-binary #D:\data\shakespeare.json
I received the same error after updating from an older version to 6.x.x. I'm not using curl statements directly, I'm using python's elasticsearch plugin.
In my case, I needed to install the newer version of the plugin that corresponded to the updated elasticsearch server.
pip install elasticsearch==6.3.1
Make sure you run it in the same Python Environment that your code is executing in.
Hope this saves someone some headache.
I found a solution you can set a default header that will overwrite previous header:
RestClient restClient = RestClient
.builder(new HttpHost(url, port, scheme))
.setDefaultHeaders(new Header[]{
new BasicHeader("Content-type", "application/json")
})
.build();

ruby rest-client ipv6 request failure with Apache 2.2.31

I've been stuck with this for about two days...
I use ruby(version 2.3.3p222) gem rest-client(v2.0.0) to send a GET request with a ipv6 url to the server (Apache/2.2.31):
url = 'https://[fd36:4928:8040:dc10:0000:0000:0000:0160]:8080/resources/1'
resource = RestClient::Resource.new(url, :ssl_version => 'TLSv1', :verify_ssl => false, :headers => {'Authorization' => 'Basic cm9vdDAbCdEfwYXNzMSE='})
resource.get
I got a 400 bad response and the body says:"Your browser sent a request that this server could not understand. Additionally, a 400 Bad Request error was encountered while trying to use an ErrorDocument to handle the request"
However I can use curl command with the same parameters and get the right response, so I suspect maybe it's something wrong with the header of my rest-client request.
PS: I also tested with adding the 'host'
header: {'Authorization' => 'Basic cm9vdDAbCdEfwYXNzMSE=', 'host' => '[fd36:4928:8040:dc10:0000:0000:0000:0160]:8080' }
It still failed with the same bad response.
I just noticed the appache error for this request, it says:
"httpd[29124]: [error] Hostname fd36:4928:8040:dc10:0000:0000:0000:0160 provided via SNI and hostname fd36:4928:8040:dc10:0000:0000:0000 provided via HTTP are different
"
The curl command you supplied would translate --user admin:password into the following header:
Authorization: Basic YWRtaW46cGFzc3dvcmQ=
However, you're sending
Basic: cm9vdDAbCdEfwYXNzMSE=
which is not the same thing... so the server is probably complaining about not getting the correct auth...
After debugging and googling for another day, this problem seems to be clear:
From a similar bug report to chrome https://bugs.chromium.org/p/chromium/issues/detail?id=500981, "SNI is only hostnames, and should never contain IPs.". However ruby does use ip as hostname (in this case rest-client is nothing to blame since it just delegate everything down to ruby lib). You can find evidence in Net::HTTP#connect (around line 922):
# Server Name Indication (SNI) RFC 3546
s.hostname = #address if s.respond_to? :hostname=
Just comment out the last line it will work (to workaround this you have to do a monkey patch). Additionally, as pointed out by #alberge, host header does not contain brackets, the final request host header is like this: "FD36:4928:8040:DC10::162", no "[ ]" around.
Also on Apache side, it does something wrong since it just strips off everything from the last colon to get the host name without any extra check- this still exists in version 2.4.10, not sure if it is fixed or not.
This appears to be either a bug in rest-client or a regression in Ruby Net::HTTP.
https://github.com/rest-client/rest-client/issues/583
What version of Ruby are you using? Have you tried using Ruby 2.1 to see if it works there?
EDIT:
This is Ruby Bug #12642. The Host header for an IPv6 address is sent with no enclosing [ ].
Ruby in 2.1.6 - 2.1.10 doesn't have the bug, but versions >= 2.2.0 are affected.
And worse still, there's a bug with setting an explicit IPv6 Host header so you get an exception URI::InvalidComponentError: bad component(expected host component): [

HTTPS using jmeter is not working and getting 403 error

I am load testing an HTTPS service using jmeter.
It works well by using following curl on a linux box:
curl -k -v -HContent-Type:application/json
-HauthToken:abcdefghijkla995e2f9-6cba-46e7-8b08-a7ffb67ca95d20150416163318
-Hsystem_name:testingsystemname -X POST --data-binary '{"deviceId":"1","cookieId":null,"emailId":"jmetertest#gmail.com"}'
https://localhost:9443/service/push/datacheck
How do I use jmeter to hit the request for load testing.
I was putting the authToken and system_name under 'send parameters with request' but it did not work and i keep on getting a 403 error.
Please help
You need to add HTTP Header Manager to your Test Plan and configure it to send the following headers:
authToken=abcdefghijkla995e2f9-6cba-46e7-8b08-a7ffb67ca95d20150416163318
system_name=testingsystemname
For sending JSON switch HTTP Request sampler to "Body Data" tab and put it there.

How to login using mediawiki's api, curl, and bash?

My understanding of the process:
From mediawikis login manual https://www.mediawiki.org/wiki/API:Login
When using MediaWiki's web service API, you will probably need your application or client to log in. This involves submitting a login query, constructing a cookie, and confirming the login by resubmitting the login request with the confirmation token returned.
1) Attempt to login with username and password, this will fail with 'result="NeedToken"' as part of response html. Response will also contain the token to be passed in for the next login attempt.
2) Attempt to login again, this time passing in token in addition to un/pw. This should return with 'result="Success"'
My code:
###Attempt first login setup cookie jar
loginRes1=$(curl --cookie-jar cjar -X POST "$domain/wiki/api.php?action=login&lgname=$lgname&lgpassword=$lgpassword")
###Grab the token from login attempt
lgtoken=$(echo $loginRes1 |sed -rn "s/.*token="([0-9a-zA-Z]+)".*/\1/p" )
###Attempt second login, this time passing token as well
loginRes2=$(curl --cookie-jar cjar -X POST "$domain/wiki/api.php?action=login&lgname=$lgname&lgpassword=$lgpassword&lgtoken=$lgtoken")
Result:
echo $loginRes1
###Only relevant html from echo shown below, cleaned up into xml syntax
<?xml version="1.0"?> <api> <login result="NeedToken" token="944af711913a037cfb8b90d477d51f6c" cookieprefix="ronk" sessionid="isqvhm955lj35g1q2e2klme091" /> </api>
echo $loginRes2
###Only relevant html from echo shown below, cleaned up into xml syntax
<?xml version="1.0"?> <api> <login result="NeedToken" token="ffdd1aa6dc3699df26b9de6dd1c6d5a5" cookieprefix="ronk" sessionid="fdahoh4gh7junrqm1tk2p1qd25" /> </api>
I'm still getting the NeedToken result the second time, instead of Success as I would expect.
Logging in via browser
I can login normally with a browser with a form submission, the post request contains 4 parameters: wpName, wpPassword, wpLoginAttempt, wpLoginToken
wpName=myName&wpPassword=myPassword&wpLoginAttempt=Log+in&wpLoginToken=d3fe3a1de6fbc934acd3039149f3c56d
Other Notes
1) I confirmed that the un/pw works when logging in normally through a browser.
2) It's unclear to me if I'm using the curl cookie-jar syntax appropriately
3) I don't know the version of mediawiki I'm connecting to, it was installed recently and is likely the highest stable version.
4) You'll notice in the successful browser attempt, the parameters have the wp prefix instead of lg, if I change the curl attempt to match (i.e. wpName, wpPassword) then the returned result is:
<?xml version="1.0"?> <api> <warnings> <main xml:space="preserve">Unrecognized parameters: 'wpName', 'wpPassword'</main> </warnings> <login result="NoName" /> </api>
The --cookie-jar option to curl only tells curl to save cookies to the jar. It doesn't tell curl to load cookies from the jar.
To get curl to load cookies from the jar you need to use the -b option to specify the cookie jar to use.

CodeIgniter Curl Library Capturing Error

I am trying to retrieve an error when my CI curl request fails. However, I cant seem to get $this->curl->error_code or $this->curl->error_string to output any data. I am trying to make a request to an API and I am breaking the URL to force an error.
$api_url = "http://breamkebreakmedfd.com";
$this->curl->create($api_url);
$this->curl->execute();
echo($this->curl->error_string);
I get no error when I echo the error.

Resources