header('Content-Disposition: attachment') not triggering when using with curl - php

I am exporting some invoices in json in my XmlController.php and converting them in xml in my xml_export.php
In my XmlController.php:
private function exportBills() {
$bill_ids = $this->_getParam('bill_ids');
$bill_model = new Model_Bills();
$bills = $bill_model->findByIds($bill_ids);
$data = array('bills' => array());
$extract = array();
foreach($bills as $bill) {
$data['bills'][] = $bill->getJsonView();
$extract[$bill->bill_reference_number] = $bill;
}
try {
$response = $this->post('xml_export.php', $data);
$this->getResponse()->setHttpResponseCode(200);
return;
} catch (Exception $e) {
$this->view->error = 'Unknown Error';
$this->view->description = $e->getMessage();
$this->getResponse()->setHttpResponseCode(500);
return;
}
}
private function post($url, $data) {
$data = json_encode($data);
$headers = array_merge(
array(
'Accept: application/xml',
'Content-Length: ' . strlen($data),
'Origin: ' . get_base_url()));
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
$xml = curl_exec($curl);
curl_close($curl);
if(false === $xml) {
throw new Exception('cURL failed! URL was: ' . $url);
}
}
And in my xml_export.php:
require_once('../library/functions.php');
$json = file_get_contents('php://input');
$date = date('Y-m-d H:i:s');
try{
$input = json_decode($json, true);
$response = array();
$xml_string = null;
$xml_concat = null;
if(implode('', array_keys($input)) === 'invoices') {
foreach ($input['invoices'] as $invoice) {
$xml_data = new SimpleXMLElement('<?xml version="1.0"?><data></data>');
array_to_xml($invoice, $xml_data);
$xml = $xml_data->asXML();
$xml = preg_replace('~<(\d)~', '<number$1', $xml);
$xml = preg_replace('~<\/(\d)~', '</number$1', $xml);
$domxml = new DOMDocument('1.0');
$domxml->preserveWhiteSpace = false;
$domxml->formatOutput = true;
$domxml->loadXML($xml);
$xml_string = $domxml->saveXML();
$xml_concat .= $xml_string;
}
}elseif(implode('', array_keys($input)) === 'bills') {
foreach ($input['bills'] as $bill) {
$xml_data = new SimpleXMLElement('<?xml version="1.0"?><data></data>');
array_to_xml($bill, $xml_data);
$xml = $xml_data->asXML();
$xml = preg_replace('~<(\d)~', '<number$1', $xml);
$xml = preg_replace('~<\/(\d)~', '</number$1', $xml);
$domxml = new DOMDocument('1.0');
$domxml->preserveWhiteSpace = false;
$domxml->formatOutput = true;
$domxml->loadXML($xml);
$xml_string = $domxml->saveXML();
$xml_concat .= $xml_string;
}
}
file_put_contents('/tmp/report.xml', print_r(htmlspecialchars($xml_concat), true));
header('Content-type: text/xml');
header('Content-Disposition: attachment; filename="report.xml"');
echo $xml_concat;
readfile('/tmp/report.xml');
exit;
}catch(OAuthException $e){
die('Unable to export. Please contact support for assistance');
}
My $xml_concat definitely has output and my /tmp/report.xml also exists and has output but the download was not triggered.
Below is my reponse header:
HTTP/1.1 200 OK
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre- check=0
Content-Type: application/json
Date: Sat, 26 Mar 2016 14:47:22 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Server: nginx
Vary: Accept
X-Powered-By: PHP/5.6.16-1+deb.sury.org~trusty+1
Content-Length: 0
Connection: keep-alive
and my request header:
POST /v1/xml HTTP/1.1
Connection: keep-alive
Content-Length: 81
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.108 Safari/537.36
Content-Type: application/json
Accept: application/json
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
I am not exactly sure why it is in application/json when I specified in application/xml in my controller and the headers did not pick up the content-disposition.

Related

Can't send the request to the server

I've some problem with the PHP script. So, I'm trying to connect to the FMI Server, but when I'm enter a valid credentials the server always return HTTP code 330, instead of 200 OK. Also when I'm trying with invalid credentials it's return 401 and it's okay, but why I've this problem only with VALID credentials?
What I'm tried?
curl_setopt($ch,CURLOPT_ENCODING , "gzip");
But no luck :(
Here's my code:
<?php
$username = "callibra#yandex.ru"; //Valid login
$password = "callibra4App"; //Valid Password
class FMIWebApplication {
private $client = array(
"user-agent" => "FindMyiPhone/472.1 CFNetwork/711.1.12 Darwin/14.0.0",
"headers" => array(
"X-Apple-Realm-Support" => "1.0",
"X-Apple-Find-API-Ver" => "3.0",
"X-Apple-AuthScheme" => "UserIdGuest",
"X-Apple-I-MD-RINFO" => "17106176",
"Accept" => "*/*",
"Connection" => "keep-alive",
"Accept-Encoding" => "br, gzip, deflate",
"Accept-Language" => "en-us",
"X-Apple-I-TimeZone" => "GMT+2",
"X-Apple-I-Locale" => "en_US"
)
);
public $username;
public $password;
public $devices = array();
public function __construct($username, $password) {
$this->username = $username;
$this->password = $password;
$this->authenticate();
}
public function authenticate() {
$url = "https://fmipmobile.icloud.com/fmipservice/device/".$this->username."/initClient";
list($headers, $body) = $this->curlPOST($url, "", $this->username.":".$this->password);
/*
if ($headers["http_code"] == 200) {
return 200;
};
if ($headers["http_code"] == 401) {
return 401;
};
if ($headers["http_code"] == 403) {
return 403;
};*/
echo $headers["http_code"];
}
private function curlPOST($url, $body, $authentication = "") {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $this->client["user-agent"]);
curl_setopt($ch, CURLOPT_SSLVERSION, 6);
if (strlen($authentication) > 0) {
curl_setopt($ch, CURLOPT_USERPWD, $authentication);
}
$arrHeaders = array();
$arrHeaders["Content-Length"] = strlen($request);
foreach ($this->client["headers"] as $key=>$value) {
array_push($arrHeaders, $key.": ".$value);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $arrHeaders);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$responseBody = substr($response, $header_size);
$headers = array();
foreach (explode("\r\n", substr($response, 0, $header_size)) as $i => $line) {
if ($i === 0)
$headers['http_code'] = $info["http_code"];
else {
list ($key, $value) = explode(': ', $line);
if (strlen($key) > 0)
$headers[$key] = $value;
}
}
return array($headers, json_decode($responseBody, true));
}
}
$API = new FMIWebApplication($username, $password);
$API->authenticate();
?>
That's what I'm getting from the server:
HTTP/1.1 330 Server: AppleHttpServer/70a91026 Date: Thu, 07 Mar 2019 13:23:40 GMT Content-Length: 0 Connection: keep-alive X-Responding-Instance: fmipservice:34000504:mr23p40ic-ztdg08174101:7004:1903B41:738abffa X-Responding-Server: mr23p40ic-ztdg08174101_004 X-Responding-Partition: p40 X-Apple-MMe-Host: p40-fmipmobile.icloud.com X-Apple-MMe-Scope: 639524741 Strict-Transport-Security: max-age=31536000; includeSubDomains Set-Cookie: NSC_q40-gnjqtfswjdf=6ad0a3dee1e78d9bd168cb5a7ceafc289128c7a38269b4bddde70dac09e4e273e5f12331;path=/;secure;httponly via: icloudedge:mc10p01ic-zteu01141501:7401:18RC846:Manchester X-Apple-Request-UUID: 8d5dc207-f1f8-453f-8863-9e0d5ab3b58b access-control-expose-headers: X-Apple-Request-UUID access-control-expose-headers: Via 330

Smugmug uploading image API v2 using PHP & Curl

Im trying to upload an image to Smugmug using the Upload API v2.
I've been trying for quite a time but it wont work.
This is what i've came up with so far.
When i run the script the response is as follows:
HTTP/1.1 100 Continue HTTP/1.1 200 OK Cache-Control: private, no-store, no-cache, max-age=1, must-revalidate Content-Type: text/xml; charset=utf-8 Date: Tue, 07 Jul 2015 14:18:50 GMT Edge-Control: no-store Expires: Tue, 07 Jul 2015 14:18:50 GMT Server: nginx X-Powered-By: SmugMug/1.0 X-SmugMug-Hiring: How to love what you do: http://www.smugmug.com/jobs/ X-SmugMug-Values: 1/4 - Thrill your customers Content-Length: 38 Connection: keep-alive
But the file isn't uploaded..
Do you see anything wrong with the code?
include_once("oauth/OAuth.php");
include_once("constants.php");
$access_token = '***';
$access_token_secret = '***';
$consumer = new OAuthConsumer(API_KEY, API_KEY_SECRET);
$signature_method = new OAuthSignatureMethod_PLAINTEXT;
$token = new OAuthToken($access_token, $access_token_secret);
$req_token = OAuthRequest::from_consumer_and_token($consumer, $token, "POST", 'http://upload.smugmug.com');
$req_token->sign_request($signature_method, $consumer, $token);
$parameters = $req_token->get_parameters();
$path = 'image.png';
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $path);
finfo_close($finfo);
$header[] = 'Authorization: OAuth realm="http://upload.smugmug.com/",
oauth_consumer_key='.$parameters['oauth_consumer_key'].',
oauth_token='.$parameters['oauth_token'].',
oauth_signature_method='.$parameters['oauth_signature_method'].',
oauth_signature='.$parameters['oauth_signature'].',
oauth_timestamp='.time().',
oauth_nonce='.md5(time() . mt_rand()).',
oauth_version=1.0';
$body[] = 'Accept: application/json';
$body[] = 'X-Smug-Version: v2';
$body[] = 'X-Smug-ResponseType: JSON';
$body[] = 'X-Smug-AlbumUri: /api/v2/album/******';
$body[] = 'X-Smug-Filename: image.png';
$body[] = 'Content-MD5: '.$base64.'';
$body[] = 'Content-Length: '.filesize($path).'';
$body[] = 'Content-Type: '.$mime.'';
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, 'http://upload.smugmug.com/');
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_error ($ch);
$result = curl_exec($ch);
print_r($result);
Using OAuth can be tricky, and the upload API for SmugMug is a little unique. It might be helpful to use one of the PHP wrappers out there rather than write your own code. Here are two, both of which have examples of how to upload images:
1.) phpSmug
2.) DFM Smug Wrapper
For example with the DFM Smug Wrapper, you can do the following (copied from the README file included with the wrapper):
<?php
require_once("dfm-smug-wrapper/dfm-smug-wrapper.php");
$f = new DFM_Smug(
"oauth_consumer_key=12345678",
"oauth_secret=some_secret",
"token_id=12345",
"token_secret=some_other_secret",
"app_name=My Cool App/1.0 (http://app.com)",
"api_ver=2.0"
);
$f->images_upload("AlbumID=123456", "File=/path/to/image.jpg");
?>

How to add values to HTTP response header using php

So far I manage to get HTTP response header from this
$ch = curl_init();<br/>
$url="http://localhost/PHP_Projects/Test/response.php";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
$headers = get_headers_from_curl_response($response);
foreach($headers as $x => $x_value){<br/>
print $x.": ".$x_value;<br/>
}
function get_headers_from_curl_response($response)
{<br/>
$headers = array();
$header_text = substr($response, 0, strpos($response, "\r\n\r\n"));
foreach (explode("\r\n", $header_text) as $i => $line)
if ($i === 0)
$headers['http_code'] = $line;
else
{
list ($key, $value) = explode(': ', $line);
$headers[$key] = $value;
}
return $headers;
}
The out put from this is like
HTTP/1.1 200 OK
Date: Thu, 07 May 2015 03:26:26 GMT
Server: Apache/2.4.12 (Win32) OpenSSL/1.0.1l PHP/5.6.8
X-Powered-By: PHP/5.6.8
Content-Length: 128
Content-Type: text/html; charset=UTF-8
but I want to add some more to this like
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Path=/application_uri
Freeflow: FC
charge: Y
amount: 100
Expires: -1
Pragma: no-cache
Cache-Control: max-age=0
Content-Type: UTF-8
Content-Length: 20
$headers = array( 'Path: application_uri',
'Freeflow: FC',
'charge: Y',
'amount: 100',
);
curl_setopt ($ch, CURLOPT_HTTPHEADER,$headers);

PHP CURL fetch header from URL and set it to variable

I have a piece of code that trying to call Cloudstack REST API :
function file_get_header($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
$datas = curl_exec($ch);
curl_close($ch);
return $datas;
}
$url = "http://10.151.32.51:8080/client/api?" . $command . "&" . $signature . "&" . $response;
echo $test = file_get_header($url);
And the output is like this :
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Set-Cookie: JSESSIONID=74A5104C625549EB4F1E8690C9FC8FC1; Path=/client Content-Type: text/javascript;charset=UTF-8 Content-Length: 323 Date: Sun, 01 Jun 2014 20:08:36 GMT
What I am trying to do is how to print JSESSIONID=74A5104C625549EB4F1E8690C9FC8FC1 only and assign it into variable? Thankss,
Here's a method that will parse all your headers into a nice associative array, so you can get any header value by requesting $dictionary['header-name']
$url = 'http://www.google.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$datas = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($datas, 0, $header_size);
curl_close($ch);
echo ($header);
$arr = explode("\r\n", $header);
$dictionary = array();
foreach ($arr as $a) {
echo "$a\n\n";
$key_value = explode(":", $a, 2);
if (count($key_value) == 2) {
list($key, $value) = $key_value;
$dictionary[$key] = $value;
}
}
//uncomment the following line to see $dictionary is an associative-array of Header keys to Header values
//var_dump($dictionary);
Simple, just match the part of the string you want with preg_match:
<?php
$text = "HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Set-Cookie: JSESSIONID=74A5104C625549EB4F1E8690C9FC8FC1; Path=/client Content-Type: text/javascript;charset=UTF-8 Content-Length: 323 Date: Sun, 01 Jun 2014 20:08:36 GMT";
preg_match("/JSESSIONID=\\w{32}/u", $text, $match);
echo $result = implode($match);
?>

Using cURL to findout where website redirects?

I'm trying to get server redirect url. I have tried
function http_head_curl($url,$timeout=10)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); // in seconds
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$res = curl_exec($ch);
if ($res === false) {
throw new RuntimeException("cURL exception: ".curl_errno($ch).": ".curl_error($ch));
}
return trim($res);
}
echo http_head_curl("http://www.site.com",$timeout=10);
Result is;
HTTP/1.1 301 Moved Permanently Date: Sun, 12 May 2013 23:34:22 GMT
Server: LiteSpeed Connection: close X-Powered-By: PHP/5.3.23
Set-Cookie: PHPSESSID=0d4b28dd02bd3d8413c92f71253e8b31; path=/;
HttpOnly X-Pingback: http://site.com/xmlrpc.php Content-Type:
text/html; charset=UTF-8 Location: http://site.com/ HTTP/1.1 200 OK
Date: Sun, 12 May 2013 23:34:23 GMT Server: LiteSpeed Connection:
close X-Powered-By: PHP/5.3.23 Set-Cookie:
PHPSESSID=630ed27f107c07d25ee6dbfcb02e8dec; path=/; HttpOnly
X-Pingback: http://site.com/xmlrpc.php Content-Type: text/html;
charset=UTF-8
It shows almost all header information, but not showing where it redirects. How do I get the redirected page url ?
It's the Location header.
$headers = array();
$lines = explode("\n", http_head_curl('http://www.site.com', $timeout = 10));
list($protocol, $statusCode, $statusMsg) = explode(' ', array_shift($lines), 3);
foreach($lines as $line){
$line = explode(':', $line, 2);
$headers[trim($line[0])] = isset($line[1]) ? trim($line[1]) : '';
}
// 3xx = redirect
if(floor($statusCode / 100) === 3)
print $headers['Location'];
$response = curl_exec($ch);
$info = curl_getinfo($ch);
$response_header = substr($response, 0, $info['header_size']);
$response_header = parseHeaders($response_header, 'Status');
$content = substr(response, $info['header_size']);
$url_redirect = (isset($response_header['Location'])) ? $response_header['Location'] : null;
var_dump($url_redirect);
/*
* or you can use http://php.net/http-parse-headers,
* but then need to install http://php.net/manual/en/book.http.php
*/
function parseHeaders($headers, $request_line)
{
$results = array();
$lines = array_filter(explode("\r\n", $headers));
foreach ($lines as $line) {
$name_value = explode(':', $line, 2);
if (isset($name_value[1])) {
$name = $name_value[0];
$value = $name_value[1];
} else {
$name = $request_line;
$value = $name_value[0];
}
$results[$name] = trim($value);
}
return $results;
}
After your CURL request is done, use curl_getinfo with the CURLINFO_EFFECTIVE_URL option. Done.
Compared to the other (complicated) answers, this will provide you the full URL that your request "ended up on".

Categories