Jump to content

Help separating http header information from json encoded string.


atrum

Recommended Posts

Hello everyone,

 

I am working with an API that sends responses in a json format, but unfortunately it also sends raw header information in the same response. Json_decode isn't working I assume because of this extra data its not expecting.

 

So unless there is another way I was trying to use regex to separate the 2 data types.

 

Basically the format I get is this.

 

HTTP/1.1 200 OK Date: Mon, 06 Jun 2011 20:25:38 GMT Server: Apache/2.0.64 (Red Hat) Vary: Content-Type Content-Length: 603 Connection: close Content-Type: application/json {"WARNINGS":[],"DATA":{"key:value","key:value","key:value","key:value","key:value","key:value","key:value","key:value"}]},"ERRORS":[]}

 

It all gets sent as a single string. Can anyone help me figure this out?

 

 

 

Link to comment
Share on other sites

Ok here are the functions I use to connect to the api server.

 

I am using fsockopen to request the information.

 

I am pretty lost when it comes to regex so I don't really have anything to show that I have tried. Most of the time I get individual characters in an array instead of words.

<?php
// VSAPI Config
define("API_HOST","api.host.com"); //API HOST
define("ACCESS_KEY_ID","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); //API Acess Key ID
define("SECRET_ACCESS_KEY","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); //API Secret Access Key
$key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
//vsapi_connect: establishes the connection to the VSAPI server.
//3 arguments: $key, and $secret from the backroom api interface.
function vsapi_connect($host,$key,$secret,$string){
if($key !=="" || $string !==""){//if $key, or $secret are not blank, and the $string_array is an array.

	$fp = fsockopen("ssl://".$host, 443, $errno, $errstr, 30);

	if(!$fp){
		return $errno ." : ".$errstr;
	}else{
		return $fp;
	}
}else{
	return false;
}
}

//hmacsha1: hashing.// I don't know exactly what this does, but it is needed.
function hmacsha1($secret, $string){
$blocksize = 64;
$hashfunc = 'sha1';
if(strlen($secret) > $blocksize)
$secret = pack('H*', $hashfunc($secret));
$secret = str_pad($secret,$blocksize,chr(0x00));
$ipad = str_repeat(chr(0x36),$blocksize);
$opad = str_repeat(chr(0x5c),$blocksize);
$hmac = pack('H*',$hashfunc(($secret^$opad).pack('H*',$hashfunc(($secret^$ipad).$string))));
return $hmac;
}

//request: sends the request data over the connect, and returns the response.
function request($fp, $q){
fwrite($fp, $q);
$r = '';
while(!feof($fp)){
	$tr = fgets($fp, 256);
	$r .= $tr;
}
return $r;
}

?>

 

 

And here is the code that im using to call the process.

 

<?php
require_once($_SERVER['DOCUMENT_ROOT']."/apitest/api_connect.php"); //Connection settings and functions.
$accept = "application/json";
$verb = "GET"; //Method
$path = "/api/script/path"; //URI path
$proxy = "https://".API_HOST.$path; //HOST + URI
$date = gmdate('r'); //Date formated for httpd header.
$string = join("\n",array($verb,$accept,$date,$proxy));
$signature = base64_encode(hmacsha1(SECRET_ACCESS_KEY, $string));// Create authorization signature
$fp = vsapi_connect(API_HOST, ACCESS_KEY_ID, SECRET_ACCESS_KEY, $string);

// Request
$query  = $verb." ".$path." HTTP/1.1\r\n";                        // HTTP verb
$query .= "Host: api.host.com\r\n";               // Host header
$query .= "Accept: ".$accept."\r\n";                             // Accept header
$query .= "Content-Type: ".$accept."\r\n";                       // Content-type header
$query .= "Authorization: VKEY ".$key.":".$signature."\r\n";   // Authorization header
$query .= "Date: ".$date."\r\n";                                 // Date header
$query .= "Connection: Close\r\n\r\n";                       // Connection header

$response = request($fp, $query);                            // Communicate with API thru URL/URI



echo $response; // This is the part that contains the json string

?>

Link to comment
Share on other sites

The authentication required is over www-auth. Can curl or fopen do that? I've only used curl and fopen. At there most basic

 

Yes either should be able to handle the auth.  Try just moving the critical things into header() calls.

 

header("Content-Type: application/json)";  
header("Authorization: VKEY ".$key.":".$signature);

Link to comment
Share on other sites

  • 2 weeks later...

Here is the solution I came up with using Curl instead of Fsockopen.

 

<?php
//Curl Test Function

define("HOST","api.host.com"); //API HOST
define("ACCT_INFO","/account/information/1.0/"); //Defines the api path for getting account and product details.
define("KEY_ID","XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); //Defines key identification code.
define("SECRET_KEY","XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); //Defines secret response.

function hmacsha1($secret, $string){
	$blocksize = 64;
	$hashfunc = 'sha1';
	if (strlen($secret) > $blocksize)
		$secret = pack('H*', $hashfunc($secret));
	$secret = str_pad($secret,$blocksize,chr(0x00));
	$ipad = str_repeat(chr(0x36),$blocksize);
	$opad = str_repeat(chr(0x5c),$blocksize);
	$hmac = pack('H*',$hashfunc(($secret^$opad).pack('H*',$hashfunc(($secret^$ipad).$string))));
	return $hmac;
}

function fetch_info($customer,$action,$method){
	if($customer!==""){
		if($action!==""){
			$accept = 'application/json';  // Assign json application
			$proxy = "https://".HOST.$action.$customer; // Assign the proxy (URL/URI)
			$path = HOST.$action.$customer;

			// Authorization Header
			$date = gmdate('r'); // GMT based timestamp
			$string = join("\n", array("GET", $accept, $date, $proxy)); // Join string with new lines
			$signature = base64_encode(hmacsha1(SECRET_KEY, $string)); // Create authorization signature

			$ch = curl_init(); //Initialize the Curl Session.
			//Set all the necessary headers to authenticate.
			$headers = array(
				"$method $path HTTP/1.1",
				"Host: ".HOST,
				"Accept: $accept",
				"Content-Type: $accept",
				"Authorization: VKEY ".KEY_ID.":$signature",
				"Date: $date",
				"Connection: Close"
			);
			curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //Feeds the header details into the request.
			curl_setopt($ch, CURLOPT_HEADER, 0); //Mostly for debugging. if 3rd argument is 1, include header response.
			curl_setopt($ch, CURLOPT_URL, $proxy); //Sets the URL/PATH.
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //Allows returned data to be stored in a variable for later use.

			$results = json_decode(curl_exec($ch), true); //Returned data in an associative array.
			curl_close($ch); //Close the curl session

			return $results; //Returns an array of data requested.
		}else{
			$error = "Missing Argument: [Action]";
			return $error;
		}
	}else{
		$error = "Missing Argument: [Customer ID]";
		return $error;
	}
}
?>

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.