Extract data from part JSON and part HTTP response - php

I'm working with an API, using cURL I have received a set of data.
The data appears to be half HTTP request and half JSON. I'm not sure why it's mixed but essentially I get this response when I do a var_dump:
string(873) "HTTP/1.1 200 OK cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0 content-length: 153 content-type: application/json;charset=utf-8 date: Mon, 10 Nov 2014 10:58:49 UTC expires: Tue, 31 Mar 1981 05:00:00 GMT last-modified: Mon, 10 Nov 2014 10:58:49 GMT ml: A pragma: no-cache server: tsa_b set-cookie: guest_id=v1%3A141561712923128379; Domain=.twitter.com; Path=/; Expires=Wed, 09-Nov-2016 10:58:49 UTC status: 200 OK strict-transport-security: max-age=631138519 x-connection-hash: 57175e4dba3d726bebb399072c225958 x-content-type-options: nosniff x-frame-options: SAMEORIGIN x-transaction: 2e4b8e053e615c75 x-ua-compatible: IE=edge,chrome=1 x-xss-protection: 1; mode=block {"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAAMVfbQAAAAAAK7qYRQOgdZ771TrJ6pZ7nugCwVQ%3DLKcongtwy3lcBDbPSEreC9DfhJk3Gm7qyQInqhFAxYvo1clv4S"}"
That's the full data back. It's got HTTP info at the beginning and then part JSON at the end.
The only bit I need from this is the access_token data.
If it was just JSON then I could use json_decode to get the access_token out but because it's got all the HTTP info at the beginning json_decode cannot understand it and gives the result NULL.
How can I remove the HTTP part so I can just grab the access_token data?
ETA: my request is made through cURL, so the var I'm dumping out is $response
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$auth_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$header = curl_setopt($ch, CURLOPT_HEADER, 1);
$result = curl_exec($ch);
curl_close($ch);
The result I receive roughly matches the expected result given in the Twitter documentation so I don't think the data is corrupt/incorrect: https://dev.twitter.com/oauth/reference/post/oauth2/token

Switch of header output and remove
$header = curl_setopt($ch, CURLOPT_HEADER, 1);
or replace with
curl_setopt($ch, CURLOPT_HEADER, false);

$a='HTTP/1.1 200 OK cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0 content-length: 153 content-type: application/json;charset=utf-8 date: Mon, 10 Nov 2014 10:58:49 UTC expires: Tue, 31 Mar 1981 05:00:00 GMT last-modified: Mon, 10 Nov 2014 10:58:49 GMT ml: A pragma: no-cache server: tsa_b set-cookie: guest_id=v1%3A141561712923128379; Domain=.twitter.com; Path=/; Expires=Wed, 09-Nov-2016 10:58:49 UTC status: 200 OK strict-transport-security: max-age=631138519 x-connection-hash: 57175e4dba3d726bebb399072c225958 x-content-type-options: nosniff x-frame-options: SAMEORIGIN x-transaction: 2e4b8e053e615c75 x-ua-compatible: IE=edge,chrome=1 x-xss-protection: 1; mode=block {"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAAMVfbQAAAAAAK7qYRQOgdZ771TrJ6pZ7nugCwVQ%3DLKcongtwy3lcBDbPSEreC9DfhJk3Gm7qyQInqhFAxYvo1clv4S"}"';
preg_match("/\{.*\}/",$a,$m);
$ja=json_decode($m[0]);
var_dump($ja,$m);
output:
object(stdClass)[1]
public 'token_type' => string 'bearer' (length=6)
public 'access_token' => string 'AAAAAAAAAAAAAAAAAAAAAMVfbQAAAAAAK7qYRQOgdZ771TrJ6pZ7nugCwVQ%3DLKcongtwy3lcBDbPSEreC9DfhJk3Gm7qyQInqhFAxYvo1clv4S' (length=112)

Related

Json response on php curl request

I have sent a curl request, and I'm outputing the response this way.
$output = curl_exec($ch);
$json = json_decode($output, true);
echo $output;
echo $json;
This is the output.
HTTP/1.1 201 Created Server: nginx/1.15.8 Date: Wed, 02 Sep 2020 23:53:01 GMT Content-Type: application/json Transfer-Encoding: chunked Connection: keep-alive X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 X-Frame-Options: DENY Strict-Transport-Security: max-age=31536000; includeSubdomains { "orderRef" : "4352fa96-05cc-400e-854c-808e5da7dfd7", "autoStartToken" : "84ead0b7-1ee8-40ed-be82-1168e7cbb16b", "message" : "" }
I'm trying to decode the json part, but $json is just null. I'd like to be able to read $json["autoStartToken"]. How would I achieve this?
As catcon mentions:
Right now your curl request also return the header so you can't directly use json_decode with the respond, try putting curl_setopt($ch, CURLOPT_HEADER, 0); before the curl_exec($ch)

php curl_setop url error

I have a
$result = curl_exec($ch)
the $ value is like that
HTTP/1.1 302 Found
Date: Wed, 18 Apr 2018 12:45:05 GMT
Set-Cookie: OAMAuthnHintCookie=0#1524055505; httponly; secure; path=/; domain=.test.com
Set-Cookie: OAMRequestContext_test.test.com:443_527635=Rv52rjM82f3htVYzT+Lp0g==;max-age=300; httponly; secure; path=/
Location: https://id.test.com/obrareq.cgi?encquery%3DE6zb4nAIzYfopY8L5SbbJJPLfvrkN7Y1RkKgv4%2FSzBKmT1cY%2BhRn0A3AhCDxGFIB10DLwLMp%2BcR40CHFKhdrh2aZcEck%2Bd2pzikJ3WzWCAo5LiVW8O3CGPVoeFXUBY2orJxN9zSZXNXkAzg%2F%2F2twT%2FS1ZIUlox8fyQrKf6mITSrqbgKhn5dcC5CR79rJDCO75VEIU472JptWmPlBlEkyFT1XRO%2BUzXQHUwui92%2FGCh34PbbDrPajiyU71ycb03ffcCt0Sl1tKVNw2S%2BsUe81VH1jgV8yLWXslvl2SzsqpQUcZVZdi80HEM2ppQTsvECX%2BiyWnZ49nVBxp3YqU4nlhkAIaNaEbTEpPVF%2FvCJSuHo%3D%20agentid%3DWgtest%20ver%3D1%20crmethod%3D2
Content-Length: 676
Cache-Control: max-age=0
Expires: Wed, 18 Apr 2018 12:45:05 GMT
I extract the location: url with:
preg_match('/(Location: https:\/\/id\.test\.com\/obrareq\.cgi\?encquery)(.*)/', $res, $location);
and put the result in $found:
$found=$location[2];
then I want to use this url in a new curl_setop
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'https://id.test.com/obrareq.cgi?encquery'.$found);
......
but it doesn't give me any result.
If I do the same curl_setop with a manual copy of the url it works.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'https://id.test.com/obrareq.cgi?encquery%3DE6zb4nAIzYfopY8L5SbbJJPLfvrkN7Y1RkKgv4%2FSzBKmT1cY%2BhRn0A3AhCDxGFIB10DLwLMp%2BcR40CHFKhdrh2aZcEck%2Bd2pzikJ3WzWCAo5LiVW8O3CGPVoeFXUBY2orJxN9zSZXNXkAzg%2F%2F2twT%2FS1ZIUlox8fyQrKf6mITSrqbgKhn5dcC5CR79rJDCO75VEIU472JptWmPlBlEkyFT1XRO%2BUzXQHUwui92%2FGCh34PbbDrPajiyU71ycb03ffcCt0Sl1tKVNw2S%2BsUe81VH1jgV8yLWXslvl2SzsqpQUcZVZdi80HEM2ppQTsvECX%2BiyWnZ49nVBxp3YqU4nlhkAIaNaEbTEpPVF%2FvCJSuHo%3D%20agentid%3DWgtest%20ver%3D1%20crmethod%3D2y');
Any idea of what i did wrong?
......

Why is cURL exec also returning the header data of my POST request?

I'm just testing some code for image compression and then uploading to the Imgur API. But instead of just getting the response content I seem to be getting the header data as well and I can't figure out how to just parse the JSON. Here's what I have so far:
compress_test.php
include("imgur_upload.php");
echo compress_and_upload();
imgur_upload.php
function compress_and_upload(){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // for localhost
curl_setopt($ch, CURLOPT_HEADER, FALSE); // tried this but no change
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . IMGUR_CLIENT_ID));
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => 'http://userserve-ak.last.fm/serve/300x300/51654499.png', 'type' => 'url'));
$reply = curl_exec($ch);
curl_close($ch);
return $reply;
}
What I'm expecting to be echoed is just the JSON data I believe.
Here is what I'm getting:
BHTTP/1.1 200 OK
Server: nginx
Date: Sat, 03 Aug 2013 05:14:53 GMT
Content-Type: application/json
Content-Length: 325
Connection: keep-alive
Set-Cookie: IMGURSESSION=dhjtli4c84koo2jbr8lild7ji7; path=/; domain=.imgur.com
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Set-Cookie: _nc=1; path=/; domain=.imgur.com; httponly
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type, Accept, X-Mashape-Authorization
X-RateLimit-ClientLimit: 12500
X-RateLimit-ClientRemaining: 12473
X-RateLimit-UserLimit: 500
X-RateLimit-UserRemaining: 497
X-RateLimit-UserReset: 1375510414
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Set-Cookie: UPSERVERID=i-614a2006; path=/
Accept-Ranges: bytes
X-Imgur-Cached: 0
{"data":{"id":"HE981gx","title":null,"description":null,"datetime":1375506893,"type":"image\/png","animated":false,"width":300,"height":300,"size":458117,"views":0,"bandwidth":0,"favorite":false,"nsfw":null,"section":null,"deletehash":"qkl9lNDWCRR52Z0","link":"http:\/\/i.imgur.com\/HE981gx.png"},"success":true,"status":200}°
I ran the code on my own servers and used your code, didn't have this issue.

PHP Curl to get a download filesize

I use this script in two different servers:
function curlGetFileInfo($url, $cookies="default"){
global $_config;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'serverpath/cookies/'.$cookies.'.txt');
$data = curl_exec($ch);
curl_close($ch);
if ($data === false) {
return 0;
}
//echo $data;
$info['filename'] = get_between($data, 'filename="', '"');
$info['extension'] = end(explode(".",$info['filename']));
if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
$info['filesize'] = (int)$matches[1];
}
return $info;
}
These servers have the same PHP version with the same PHP-Curl version. These are the two different headers of the curl result:
Working one:
HTTP/1.1 302 Found Date: Tue, 12 Jun 2012 07:04:35 GMT Server:
Apache/2.2.16 (Debian) X-Powered-By: PHP/5.3.3-7+squeeze13 Expires:
Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store,
no-cache,must-revalidate, post-check=0, pre-check=0 Pragma: no-cache
Location:
http://stor1076.uploaded.to/dl/b3411ded-0f45-4efc-b705-8c8ac89b5e41
Vary: Accept-Encoding Connection: close Content-Type: text/html
HTTP/1.1 200 OK Server: nginx/1.0.5 Date: Tue, 12 Jun 2012 07:04:35
GMT Content-Type: video/x-msvideo Content-Length: 733919232
Last-Modified: Tue, 29 May 2012 15:10:07 GMT Connection: keep-alive
Content-Disposition: attachment;
filename="Saw.[Spanish.DVDRip].[XviD-Mp3].by.SDG.avi" Accept-Ranges:
bytes
Non working one:
HTTP/1.1 302 Found Date: Tue, 12 Jun 2012 07:05:26 GMT Server:
Apache/2.2.16 (Debian) X-Powered-By: PHP/5.3.3-7+squeeze13 Expires:
Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache,
must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Location:
http://stor1164.uploaded.to/dl/22c3d242-365d-4e1e-b903-f1e2b81812c2
Vary: Accept-Encoding Connection: close Content-Type: text/html
Cookies are set OK (with login), and other simple Curl functions are working fine.
Also, I did a curl_getinfo($ch, CURLINFO_HTTP_CODE) and give me that result:
Working one:
200
Non working one:
302
Any idea?
On the working one you seem to be running Apache as well as nginx. You can see there are two HTTP responses:
HTTP/1.1 302 Found Date: Tue, 12 Jun 2012 07:04:35 GMT Server:
Apache/2.2.16 (Debian) HTTP/1.1 200 OK Server: nginx/1.0.5
So, your setup differs. I don't know how exactly they are running together, but this gives some insight and may help you solve it: http://kbeezie.com/view/apache-with-nginx/
Ok, it was a open_basedir problem. Thanks guys.

curl not returning content length header

Trying to get image file size using curl but content length header is not returned:
$url ="http://www.collegefashion.net/wp-content/plugins/feed-comments-number/image.php?1263";
$fp = curl_init();
curl_setopt($fp, CURLOPT_NOBODY, true);
curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($fp, CURLOPT_FAILONERROR,1);
curl_setopt($fp, CURLOPT_REFERER,'');
curl_setopt($fp, CURLOPT_URL, $url);
curl_setopt($fp, CURLOPT_HEADER,1);
curl_setopt($fp, CURLOPT_USERAGENT,'Mozilla/5.0');
$body = curl_exec($fp);
var_dump($body):
HTTP/1.1 200 OK
Date: Sun, 02 May 2010 02:50:20 GMT
Server: Apache/2.0.63 (CentOS)
X-Powered-By: W3 Total Cache/0.8.5.2
X-Pingback: http://www.collegefashion.net/xmlrpc.php
Cache-Control: no-cache, must-revalidate
Expires: Sat, 26 Jul 1997 05:00:00 GMT
Content-Type: image/png
It works via ssh though:
curl -i http://www.collegefashion.net/wp-content/plugins/feed-comments-number/image.php?1263
HTTP/1.1 200 OK
Date: Sun, 02 May 2010 03:38:43 GMT
Server: Apache/2.0.63 (CentOS)
X-Powered-By: W3 Total Cache/0.8.5.2
X-Pingback: http://www.collegefashion.net/xmlrpc.php
Cache-Control: no-cache, must-revalidate
Expires: Sat, 26 Jul 1997 05:00:00 GMT
Content-Length: 347
Content-Type: image/png
CURLOPT_NOBODY makes a HEAD request while your command line with -i is a GET request...
If you'd use -I with your command line version they would be more similar.
Check curl_getinfo():
$size = curl_getinfo($fp, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
Execute it after curl_exec().
One other option is to set CURLOPT_HEADER to false and just do strlen($body) -- ignore this, I didn't noticed you were using CURLOPT_NOBODY.

Categories