I am using PerfectSwift for a RESTful API to bridge our TeamCity build server and HipChat; however I am stuck at a point whereby I am unable to post to the HipChat backend using Perfect's cURL wrapper.
The command I am trying to mimic is:
curl -d '{"color":"green","message":"My first notification (yey)","notify":false,"message_format":"text"}' -H 'Content-Type: application/json' https://<MY DOMAIN>/v2/room/509/notification?auth_token=<MY AUTH TOKEN>
I currently have the following code in my Perfect program:
let curl = CURL(url: "https://<MY DOMAIN>/v2/room/509/notification?auth_token=<MY AUTH TOKEN>")
curl.setOption(CURLOPT_POST, int: 1)
curl.setOption(CURLOPT_POSTFIELDS, s: "{\"color\":\"green\",\"message\":\"My first notification (yey)\",\"notify\":false,\"message_format\":\"text\"}")
curl.setOption(CURLOPT_HTTPHEADER, s: "[Content-Type:application/json]")
curl.perform { (code, header, body) in
}
However, the message never gets to HipChat, or, if it does, it's not in a readable format.
When I paste the first command into terminal, everything works as expected.
From my understanding, this uses a similar system to PHP, and I am therefore including the PHP tag as I feel PHP developers may be able to offer advice if I am using the wrong CURLOPTs etc...
Thanks in advance.
Related
I've setup a GitHub webhook with a secret and selected application/x-www-form-urlencoded for the content type.
I tried to search around but there does not seem to be much info on how to use the post data, such as what does GitHub include in the POST request, can I just do:
$_POST["secret"] or is there more to it than that? I know I could test this myself but with the way I setup the webhook its hard to see the output and more of a pain to do a var_dump() for POST.
So basically my question is what is the POST layout when GitHub sends a POST request, because I am looking to validate which branch was pushed and validate the secret as well.
seems it is translated by PHP as $_SERVER['HTTP_X_HUB_SIGNATURE']
but when in doubt as to how PHP will name a header, set up a page with <?php phpinfo(~0); , and run curl with the url like curl http://ratma.net/phpinfo.php --header "X-Hub-Signature: test" -v 2>&1 | grep -i test , and you should see what the header is called. in this case, i got
<tr><td class="e">$_SERVER['HTTP_X_HUB_SIGNATURE']</td><td class="v">test</td></tr>
Let me preface this by stating that I'm a complete novice when it comes to php, but I have a need to create a php script for a particular curl request to monitor the state of a service.
The curl command is:
curl --insecure --digest 'https://admin:password#localhost:9993/management' --header "Content-Type: application/json" -d '{"operation":"read-attribute","name":"server-state","json.pretty":1}'
And it returns this output:
"outcome" : "success",
"result" : "running"
I've searched around, found some examples and hacked together a few different scripts but none of them give me the desired result (entirely my fault). I seem to have the authentication side working but I'm failing miserably at sending the array and returning a result. Essentially, I'm interested in getting the "running" field back (or whatever other value it might return) which I can use in out monitoring system. The closest I've got is for the server to throw a java ioexception at me because of an invalid character.
Any assistance will be greatly appreciated.
Thanks,
Mark J.
Never mind. I needed to json_encode my data string. All working now.
I followed this Laravel token API tutorial: http://rjv.im/post/95988160186/api-token-authentication-with-laravel-and-sentry-part. I have written the following cURL request to communicate with my API:
curl -H "X-Auth-Token:tokenhere" http://localhost:8000/account
The request works properly, and accurately returns the expected data. When I translate this to Python I receive urllib2.HTTPError: HTTP Error 401: Unauthorized
import urllib2
req = urllib2.Request('http://localhost:8000/account')
req.add_header("X-Auth-Token", "tokenhere")
resp = urllib2.urlopen(req)
content = resp.read()
print content
If I pass user credentials using basic auth instead of an X-Auth-Token, the request works as expected:
import urllib2
def basic_authorization(user, password):
s = user + ":" + password
return "Basic " + s.encode("base64").rstrip()
req = urllib2.Request("http://localhost:8000/account", headers = { "Authorization": basic_authorization("usernameHere", "passwordHere"), })
f = urllib2.urlopen(req)
print f.read()
Any assistance would be much appreciated.
There is something you missed in the tutorial. In the tokens table there is a column:
$table->string('client');
It is important from which client you are sending your request. I am using https://github.com/hisorange/browser-detect to detect from which client I got the request.
But for now I will just try to see User Agent. In my laravel code I just logged every request to see what's happening with the following code:
Route::filter('auth.token', function($route, $request)
{
....
Log::info($request);
....
}
Now, Let's see:
When I use curl from command line:
curl -u user#example.com:password -X GET http://localhost:8000/account
My User Agent is
User-Agent: curl/7.32.0
I sent the same from python using your code above, User Agent is:
User-Agent: Python-urllib/2.7
Ah! That must be it. You have to authenticate your user at least once using Basic Auth, it will give you a token and that token is valid for only that client. In the first part http://rjv.im/post/78940780589/api-token-authentication-with-laravel-and-sentry-part of tutorial there was no such condition. In the comments I received someone posted a query on how to support multiple clients, so this example was made to solve that problem.
Apart from that, may I suggest this library: https://github.com/chrisbjr/api-guard It supports Rate Limiting, easy to integrate with Sentry. It's a bit different from my tutorial. Using my solution you can hit any endpoint using Basic Auth or Token. Using above library, only token is permitted, so there is dedicated route to generate token. Let me know how it goes.
I am quite experienced in PHP but I've always had troubles with connection between servers like "post". I have a FLAC audio file that I need to post to Google's Speech Recognition API server. I don't know neither how to "listen" to its response. I would like a script like that, assuming that this kind of function exists :
<?php
$fileId = $_GET['fileId'];
$filepath = $fileId . ".flac";
recognize($filepath);
function recognize($pathToFile) {
//It's the following function that I'm looking for
$response = $pathToFile->post("http://www.google.com/speech-api/v1/.....&client=chromium");
//The $response would be the short JSON that Google feed back.
echo $response;
}
?>
EDIT
I've followed a tutorial to create a Shell Script that posts my FLAC file using Wget --post. I would like to post like this, but in PHP. Also, at the end of the command, there is this > answer.ret line, so that Google's answer would be written to this file. I was wondering if there was an alternate method to it in PHP.
Here's the command line :
wget -q -U "Mozilla/5.0" --post-file audio1.flac --header="Content-Type: audio/x-flac; rate=16000" -O - "http://www.google.com/speech-api/v1/recognize?lang=fr-fr&client=chromium" > trancription1.ret
EDIT 2
I figured out how to do it, with #hakre 's answer and baked up a little Gist for curious people. Here it is: https://gist.github.com/chlkbumper/4969389. Don't forget that the FLAC file must be a 16k bitrate FLAC
A POST request is just a standard HTTP request, just with the POST method specified. The rest of the HTTP Request and HTTP Response is pretty much the same.
You get the response of a request in form of a HTTP Response btw.. It is absolutely normaltiv defined in RFC 2616 - just relate to this document and it explains everything.
A function in PHP to send HTTP requests is file_get_contents, it returns the requests response. This is done via the HTTP stream wrapper that offers some options you need to send a POST request (default is GET). See HTTP context options.
Another popular PHP extension for sending HTTP requests are the Curl bindings.
An API I'm trying to program to requires multipart/form-data content with the HTTP GET verb. From the command line I can make this work like this:
curl -X GET -H "Accept: application/json" -F grant_type=consumer_credentials -F consumer_key=$key -F consumer_secret=$secret https://example.com/api/AccessToken
which seems like a contradiction in terms to me, but it actually works, and from what I see tracing it actually uses GET. I've tried a bunch of things to get this working using PHP's cURL library, but I just can't seem to get it to not use POST, which their servers kick out with an error.
Update to clarify the question: how can I get php's cURL library to do the same thing as that command line?
which seems like a contradiction in terms to me, but it actually
works, and from what I see tracing it actually uses GET
Not exactly. curl uses a feature of the HTTP/1.1. It inserts additional field to the header Expect: 100-continue, on which, if supported by server, server should response by HTTP/1.1 100 Continue, which tells the client to continue with its request. This interim response is used to inform the client that the initial part of the request has been received and has not yet been rejected by the server. The client SHOULD continue by sending the remainder of the request or, if the request has already been completed, ignore this response. The server MUST send a final response after the request has been completed.
Since they are insisting on HTTP GET, then just encode the form elements into query parameters on the URL you are GETing and use cURL's standard get options instead of posting multipart/formdata.
-X will only change the method keyword, everything else will remain acting the same which in this case (with the -F options) means like multipart formpost.
-F is multipart formpost and you really cannot convert that to a query part in the URL suitable for a typical GET so this was probably not a good idea to start with.
I would guess that you actually want to use -d to specify the data to post, and then you use -G to convert that data into a string that gets appended to the URL so that the operation turns out to a nice and clean GET.