Difference between cURL headers - php

What is difference between below headers sent by cURL?
$header="POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .="Content-Type: application/x-www-form-urlencoded\r\n";
$header .="Host: www.paypal.com\r\n";
$header .="Connection: close\r\n\r\n";
And
$header = array ('POST /cgi-bin/webscr HTTP/1.1', 'Content-Type: application/x-www-form-urlencoded', 'Host: www.paypal.com', 'Connection: close');
Used for
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
Can I use both methods for setting up headers for cURL?Thanks

Both solutions are wrong although the second is less wrong.
Both include the POST line which is the request line and not actually a header by definition. Thus, including that in the header option will create a bad request. (but yes, it may still work)

Related

two HTTP requests in PHP using fsockopen

I have a problem which I couldn't solve almost a week. I searched everything but couldn't find an answer.
I need to do 3 x HTTP requests to the server and then receive answers.
First is GET request to get cookie. Second is POST with cookie and the third is redirect.
$host = "www.xx.com";
$user_agent = "User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20100101 Firefox/12.0\r\n";
$sock = fsockopen("ssl://$host", 443, $errno, $errstr, 30);
if (!$sock) die("$errstr ($errno)\n");
#########################################
# GET
#########################################
$request .= "GET $path HTTP/1.1\r\n";
$request .= "Accept: */*\r\n";
$request .= "Host: $host\r\n";
$request .= $user_agent;
$request .= "Connection: close\r\n";
$request .= "\r\n";
fwrite($sock, $request);
$http_response = stream_get_contents($sock);
list($headers, $body) = explode("\r\n\r\n", $http_response, 2);
// get cookie
preg_match_all('/Set-Cookie:\s*(.*)\b/', $headers, $cookie_res);
foreach($cookie_res[1] as &$val){
$cookie .= "Cookie: ".$val."\r\n";
}
echo "<pre><p>$headers<br />cookie: $cookie</p></pre>";
$data = preg_replace('/^\s+|\n|\r|\s+$/m', '', $data);
#########################################
# POST with cookie
#########################################
$request2 .= "POST $path"."filter/ HTTP/1.1\r\n";
$request2 .= "Host: $host\r\n";
$request2 .= $user_agent;
$request2 .= "Accept: text/html,application/xhtml+xml,application/xml;\r\n";
$request2 .= "Connection: keep-alive\r\n";
$request2 .= $cookie;
$request2 .= "Referer: $path\r\n";
$request2 .= "Content-type: application/x-www-form-urlencoded; charset=UTF-8\r\n";
$request2 .= "Content-length: " . strlen($data) . "\r\n";
$request2 .= "\r\n";
$request2 .= "$data\r\n";
$request2 .= "\r\n";
fwrite($sock, $request2);
$http_response2 = stream_get_contents($sock);
list($headers2, $body2) = explode("\r\n\r\n", $http_response2, 2);
echo "<pre><p>$headers2</p></pre>";
So I get response after the first GET request, but I don't get response after POST request.
If I close connection after first request and reopen it again before second then it works. But I want to do it in one connection. I don't understand why it doesn't work without reconnecting.
Please help! :)
P.S. don't recommend to use CURL because I don't have it installed on this server.

IPN Verification Postback to HTTPS

My PHP code currently uses the following to Postback to PayPal. How do I update this to meet the new payment security standards coming into effect?
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value)
{
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
if (!$fp)
{
//an error occurred...
}
else
{
fputs ($fp, $header . $req);
while (!feof($fp))
{
$res = fgets ($fp, 1024);
if(strcmp ($res, "VERIFIED") == 0)
{
//all is well...
}
}
}
To enable IPN Verification Postback to HTTPS, change your code as follows,
$fp = fsockopen( 'tls://ipnpb.paypal.com', 443, $errno, $errstr, 30);
PayPal recommends to use ipnpb.paypal.com endpoint in production environment.
Also, you need to change HTTP/1.0 to HTTP/1.1 to comply with PayPal upgrades.
The Header you need to submit,
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: www.paypal.com\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen( $req ) . "\r\n";
$header .= "Connection: close\r\n\r\n";
For the sandbox change,
$header .= "Host: www.paypal.com\r\n";
to
$header .= "Host: www.sandbox.paypal.com\r\n";
The new code suggested above has now had a chance to be tested.
This did NOT work:
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value)
{
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen( 'tls://ipnpb.paypal.com', 443, $errno, $errstr, 30);
This is what works:
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value)
{
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
What to do about using HTTP/1.0 and posting to www.paypal.com rather than using HTTP/1.1 and posting to tls://ipnpb.paypal.com?
There's a couple of things that need to be done:
You're still on HTTP/1.0; you need to switch to HTTP/1.1.
You need to switch to using TLS.
Most PHP setups nowadays should have cURL installed, so the easiest thing to do would be to use cURL. To do this, the last four lines of your code would change to the following:
$curl = curl_init( 'https://ipnpb.paypal.com/cgi-bin/webscr' );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl, CURLOPT_POST, true );
curl_setopt( $curl, CURLOPT_POSTFIELDS, $req );
$response = curl_exec( $curl );
if( 'VERIFIED' == trim( $response ) ) {
// IPN verified by PayPal
}
I have a similiar issue with Paypal IPN verification and using this code
// post back to PayPal system to validate
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
If I understand the solution correctly, the new code should look like
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: ipnpb.paypal.com\r\n";
$header .= "Connection: close\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen( 'tls://ipnpb.paypal.com', 443, $errno, $errstr, 30);

Using Volusion API to Import Order Data

I've been trying to use the Volusion API to import order data with no luck and support through Volusion is limited. I tend to lean towards a PHP solution, and their web site has this example for using the API for Import with php...
<?php
// Create the Xml to POST to the Webservice
$Xml_to_Send = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
$Xml_to_Send .= "<Volusion_API>";
$Xml_to_Send .= "<!--";
$Xml_to_Send .= " xml input file for \"\"";
$Xml_to_Send .= "-->";
$Xml_to_Send .= "</Volusion_API>";
// Create the Header
$url = "https://www.xxxxxcomusa.com/net/WebService.aspx?Login=xxxxx#xxxxcomusa.com &EncryptedPassword=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&Import=Insert";
$header = "POST".$url." HTTP/1.0 \r\n";
$header .= "MIME-Version: 1.0 \r\n";
$header .= "Content-type: text/xml; charset=utf-8 \r\n";
$header .= "Content-length: ".strlen($post_string)." \r\n";
$header .= "Content-transfer-encoding: text \r\n";
$header .= "Request-number: 1 \r\n";
$header .= "Document-type: Request \r\n";
$header .= "Interface-Version: Test 1.4 \r\n";
$header .= "Connection: close \r\n\r\n";
$header .= $Xml_to_Send;
// Post and Return Xml
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 4);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $header);
$data = curl_exec($ch);
// Check for Errors
if (curl_errno($ch)){
print curl_error($ch);
} else {
curl_close($ch);
}
// Display the Xml Returned on the Browser
echo $data;
?>
I've edited this accordingly in order to get an order updated (used "Import=Update") but there is no 'data' output on the resulting page and the record does not get updated. I am able to get data returned from the api using a similar url so I know my encrypted password is correct. I think I also determined that the line that reads...
$header = "POST".$url." HTTP/1.0 \r\n";
should read ...
$header = "POST ".$url." HTTP/1.0 \r\n";
with a space after POST but I'm still not able to successfully update a record. I was hoping someone might have had success and can share more specifics on how you were able to import an update using the Volusion API (and hopefully PHP).
Instead of trying with CUSTOMREQUEST you can use below one. It sends your headers appropriately.
First make the header as below:
$header = array(
"MIME-Version: 1.0",
"Content-type: text/xml; charset=utf-8",
"Content-transfer-encoding: text",
"Request-number: 1",
"Document-type: Request",
"Interface-Version: Test 1.4"
);
After that make your post request as below with the above header.
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $Xml_to_Send);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
Here is the code I ended up with but as I mention above it appears that Import=Update does not work with Volusion Order data, but similar code should work when trying to use the Volusion API and PHP to import. Thanks again for your help Sabuj!
<?php
$file = file_get_contents('mydir/singleorder.txt', true);
// Create the Xml to POST to the Webservice
$Xml_to_Send = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
$Xml_to_Send .= "<Volusion_API>";
// $Xml_to_Send .= "<!--";
$Xml_to_Send .= $file;
// $Xml_to_Send .= "\"\"";
// $Xml_to_Send .= "-->";
$Xml_to_Send .= "</Volusion_API>";
$url = "https://www.xxxxxusa.com/net/WebService.aspx?Login=xxxx#xxxxxxxcom.com&EncryptedPassword=0000000000000000000000000000xxxxxxxxxx&Import=Update";
// Create the Header
$header = array(
"MIME-Version: 1.0",
"Content-type: text/xml; charset=utf-8",
"Content-transfer-encoding: text",
"Request-number: 1",
"Document-type: Request",
"Interface-Version: Test 1.4"
);
// Post and Return Xml
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $Xml_to_Send);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$data = curl_exec($ch);
// Check for Errors
if (curl_errno($ch)){
print curl_error($ch);
} else {
curl_close($ch);
}
// Display the Xml Returned on the Browser
echo $data;
?>
First you should echo your file.
Because I was having the same issue, the remaining code is correct but may be your file path is wrong and doesn't get by PHP so thats why the records is not inserted.
When I changed the directory path is like this..
$file = file_get_contents('singleorder.txt', true);
It will be always in the same directory.
It started work fine. So try this for solution.

New HTTP/1.1 php headers do not work?

I have been using a php script as IPN listener for years and it works fine.
A few days ago, Paypal set a message warning that October 7, 2013 code must be using HTTP/1.1. So I copied the sample code provided in lieu of my current headers :
-- new code---
// post back to PayPal system to validate
$header="POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .="Content-Type: application/x-www-form-urlencoded\r\n";
$header .="Host: www.paypal.com\r\n";
$header .="Connection: close\r\n\r\n";
-- Existing code ---
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
Now the script no longer works. I get a 401 error :(
What's wrong ? I am growing extremely concerned, if new code does not work, that it will no work on time. Looked everywhere and could not find a definitive answer. I would like to get this working.
Help !
Try this code:
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Host: www.paypal.com\r\n";
$header .= "Connection: close\r\n";
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);

php - how to be able to ajax post and return from this script?

I'm quite stuck in how to edit this script be able to take a request from jquery and return to me the value the script returns? Any help is most gratefully appreciated?
I can use it to pass an xml file and url from the filesystem and get the return I expect but would really like to be able to use it as a proxy to a wsdl service.
[edit] Due to environmental changes I'm wanting to use the below script to pass back to me the xml return from a wsdl service that I'm passing xml. It works fine when I do so from the command line - I'm just unsure how to be able to get the script to accept a post and then return the xml return from the service call.
I'm using the script as follows from the command line:
php file.php theurl <test.xml
^^ Which returns to me the xml I would like to then pass back to the frontend
<?php
ini_set('display_errors', "1");
$url= $argv[1];
echo "url\n$url\n";
preg_match("/https?:\/\/([^\/]*)(.*)/", $url, $matches);
$host=$matches[1];
$request=$matches[2];
$mxml=fread(STDIN,65536);
$yt =curl_init();
$header = "POST $request HTTP/1.0\r\n";
$header .= "Host: $host\r\n";
$header .= "SoapAction:";
$header .= "Content-Type: text/xml\r\n";
$header .= "Content-Length: ".strlen($mxml)."\r\n";
$header .= "Content-Transfer-Encoding: text\r\n";
$header .= "Connection-Close: close\r\n\r\n";
echo "header\n$header\n";
$header .= $mxml;
curl_setopt($yt, CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($yt, CURLOPT_URL, $url);
curl_setopt($yt, CURLOPT_CUSTOMREQUEST, $header);
curl_setopt($yt, CURLOPT_RETURNTRANSFER, true);
$rxml=curl_exec($yt);
echo "sent\n$mxml\n";
echo "received\n$rxml\n";
echo curl_error($yt);
?>
Sussed it. Sorry forgot to post answer. Hopefully help someone else:
<?php
$url = 'http://myURL';
$xmlpost = file_get_contents('php://input');
$header = "POST $url HTTP/1.0\r\n";
$header .= "Host: myHOST\r\n";
$header .= "SoapAction: ''";
$ch = curl_init();
//Set the URL
curl_setopt($ch, CURLOPT_URL, $url);
//Enable POST data
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlpost);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $header);
//curl_exec automatically writes the data returned
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
$.post('path/to/php/', function(data)
{
$('body').append('<div id="outputs"></div>');
$('#outputs').html($(data).find('name_of_xml_node').text());
}, 'xml');
maybe.. can't guarantee this one, without at the least maybe some sample data.. as well as this would be more example to work with rather than actually based off what your getting for xml data..
Also you want your PHP to output the XML only no extra strings or anything else like that, that can break the formatting of XML

Categories