Curl post, without waiting for response - php

I am trying to figure out if there is a way to do a curl post, but without receiving the response.
I know I can prevent the response from being displayed by setting CURLOPT_RETURNTRANSFER to false, but I don't even want to receive it.
I am working on a proxy and need to do the post request to a webservice, but the response it gives is MASSIVE and ends up timing out my connection (even when set to 200 seconds).
Even if it did work, that's just way too long since I don't care what the response is at all.
I can't seem to find a way to do this.

Try using a socket rather than using cURL:
$requestBody = 'myparams=something&something=somethingelse';
$socket = fsockopen("mysite.com", 80, $errno, $errstr, 15);
if (!$socket) {
// Handle the error, can't connect
} else {
$http = "POST /path/to/post/to HTTP/1.1\r\n";
$http .= "Host: mysite.com\r\n";
$http .= "Content-Type: application/x-www-form-urlencoded\r\n";
$http .= "Content-length: " . strlen($post_data) . "\r\n";
$http .= "Connection: close\r\n\r\n";
$http .= $requestBody . "\r\n\r\n";
fwrite($socket, $http);
fclose($socket);
}
This will submit the POST request and not wait around for the response.

Related

PayPal IPN error: line folding of header fields is not supported

A PayPal IPN script that's been running for years suddenly stopped working. PayPal is returning the following response:
HTTP/1.1 400 Bad Request
Connection: close
Content-Length: 46
content-type: text/plain; charset=utf-8
line folding of header fields is not supported
To summarize how PayPal IPN is supposed to work:
PayPal POSTs to an endpoint on your system
The endpoint must reply back to PayPal with the POST data it received
PayPal responds back with VERIFIED
In my case, PayPal cannot verify the response because, "line folding of header fields is not supported".
Google's not providing much on "line folding header fields". I can only assume it's something to do with header formatting. Here is the pertinent code:
// 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
// 7/22/2013 - Update to use HTTP 1.1 instead of HTTP 1.0
$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";
$header .= "Host: www.paypal.com\r\n ";
$header .= "Connection: close\r\n\r\n";
// Open a connection to PayPal.com
$fp = #fsockopen("ssl://{$target}", 443, $errno, $errstr, 30);
if (!$fp) {
// HTTP ERROR
}else{
#fputs ($fp, $header . $req);
while (!#feof($fp)) {
$res = #fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
$verified = true;
}else{
// Log failure
}
}
#fclose ($fp);
}
Any ideas what might be causing the error about line folding in regards to the headers?
Header folding is explained under https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4:
Historically, HTTP header field values could be extended over
multiple lines by preceding each extra line with at least one space
or horizontal tab (obs-fold).
I had to echo out the headers you are generating to see the problem myself, it is quite hard to spot:
$header .= "Host: www.paypal.com\r\n ";
The extra space after the line break here, means the next header line will start with that space - and that means, you are "folding headers", without having actually intended to do so.
Remove that extra trailing space, and things should work fine.

Something like thread in php

I'm trying to program yahoo messenger robot,now my robot can get messages and answer to them.
Yahoo only can send 100 pm at each time I get notification.
now I wanna answer the each pm. I use while(true){ } to it and answer first pm,then second ,then 3rd and ... .
It's so slow ,because I can make only one connection to yahoo by this(I use curlib).
how can I send some messages at same time?I think I need something like thread but in php.
you can use pcntl_fork(). http://www.php.net/manual/en/function.pcntl-fork.php
You need pcntl extension and it only works on Unix
If you use curl function you might take a look at curl_multi_init(). http://www.php.net/manual/en/function.curl-multi-init.php
I've wrote a simple function below, which launches URL, and doesn't wait for a result, so like this you can launch many URLs on your own site, it will make your loop fast, and also no need to install any extensions to your server.
function call_url_async($url, $params, $type='POST', $timeout_in_seconds = 1)
{
//call the URL and don't wait for the result - useful to do time-consuming tasks in background
foreach ($params as $key => &$val)
{
if (is_array($val))
$val = implode(',', $val);
$post_params[] = $key.'='.urlencode($val);
}
$post_string = implode('&', $post_params);
$parts=parse_url($url);
$fp = fsockopen($parts['host'], isset($parts['port'])?$parts['port']:80, $errno, $errstr, $timeout_in_seconds);
//if ($fp == FALSE)
// echo "Couldn't open a socket to ".$url." (".$errstr.")<br><br>";
// Data goes in the path for a GET request
if ('GET' == $type)
$parts['path'] .= '?'.$post_string;
$out = "$type ".$parts['path']." HTTP/1.1\r\n";
$out.= "Host: ".$parts['host']."\r\n";
$out.= "Content-Type: application/x-www-form-urlencoded\r\n";
$out.= "Content-Length: ".strlen($post_string)."\r\n";
$out.= "Connection: Close\r\n\r\n";
// Data goes in the request body for a POST request
if ('POST' == $type && isset($post_string))
$out.= $post_string;
fwrite($fp, $out);
fclose($fp);
}

fsockopen https freezing on fgets

I attempting to connect to a server via PHP fsockopen to initially get a cookie for basic auth and then to persistently connect to a streaming server defined in the Location header of the response.
The problem is that my code freezes on fgets and never receives any response data from the destination server. I'm connecting via https on port 443 on an Amazon ec2 instance. The server connects fine via curl in my server's terminal or via my chome browser.
$this->conn = fsockopen('ssl://[destination_server]', 443, $errNo, $errStr, $this->connectTimeout);
stream_set_blocking($this->conn, 1);
fwrite($this->conn, "GET " . $urlParts['path'] . " HTTP/1.0\r\n");
fwrite($this->conn, "Host: " . $urlParts['host'] . "\r\n");
fwrite($this->conn, "Content-type: application/x-www-form-urlencoded\r\n");
fwrite($this->conn, "Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
fwrite($this->conn, 'Authorization: Basic ' . $authCredentials . "\r\n");
fwrite($this->conn, 'User-Agent: ' . self::USER_AGENT . "\r\n");
list($httpVer, $httpCode, $httpMessage) = preg_split('/\s+/', trim(fgets($this->conn, 1024)), 3);
//code never gets here!!!
Any thoughts?
I solved this problem by adding the header: "Connection: Close\r\n\r\n".
The initial request for the cookie returns a 302 redirect code and will sit on the open connection unless you pass that header.
Unfortunately, this little line had me stumped for a while.

fsockopen soap request

I am trying to send a SOAP message to a service using php.
I want to do it with fsockopen, here's is the code :
<?php
$fp = #fsockopen("ssl://xmlpropp.worldspan.com", 443, $errno, $errstr);
if (!is_resource($fp)) {
die('fsockopen call failed with error number ' . $errno . '.' . $errstr);
}
$soap_out = "POST /xmlts HTTP/1.1\r\n";
$soap_out .= "Host: 212.127.18.11:8800\r\n";
//$soap_out .= "User-Agent: MySOAPisOKGuys \r\n";
$soap_out .= "Content-Type: text/xml; charset='utf-8'\r\n";
$soap_out .= "Content-Length: 999\r\n\r\n";
$soap_put .= "Connection: close\r\n";
$soap_out .= "SOAPAction:\r\n";
$soap_out .= '
Worldspan
This is a test
';
if(!fputs($fp, $soap_out, strlen($soap_out)))
echo "could not write";
echo "<xmp>".$soap_out."</xmp>";
echo "--------------------<br>";
while (!feof($fp))
{
$soap_in .= fgets($fp, 100);
}
echo "<xmp>$soap_in</xmp>";
fclose($fp);
echo "ok";
the above code just hangs . if i remove the while it types ok, so i suppose the problem is at $soap_in .= fgets($fp, 100)
Any ideas of what is happening
Its not just a matter of opening a socket then writing 'POST....' to it - you need a full HTTP stack to parse the possible responses (e.g. what different encodings? Partial Content?). Use cURL.
The reason its currently failing is probably because the remote system is configured to use keepalives - which would again be solved by using a proper HTTP stack.
C.
I recommend, use curl for soap actions. http://www.zimbra.com/forums/developers/9890-solved-simple-soap-admin-example-php.html#post52586

PHP: Connection: keep-alive problem reading socket data

Trying to write data to a socket and read the response.
$packet = "GET /get-database HTTP/1.1\r\n";
$packet .= "Host: 192.168.3.136:3689\r\n";
//$packet .= "Accept-Encoding: gzip\r\n";
$packet .= "Viewer-Only-Client: 1\r\n";
$packet .= "Connection: keep-alive\r\n\r\n";
socket_write($socket, $packet, strlen($packet));
do{
$buf = "";
$buf = socket_read($socket, 4096);
$data .= $buf;
}while($buf != "");
echo "$data\r\n\r\n";
If I set the Connection to close then it works and I'm able to read the response. The problem with that is, that after I read the data, I need to write back to the socket. The response contains an id that I need to send back for verification. If I write to the server on two separate sockets, it rejects the verification post back. So I can only assume, that I need to post on same "open connection" or "session".
Any thoughts?
I would like to figure out why I can't read from the socket with Connection: keep-alive
####### EDIT
There has been a little development on this.
I'm trying to make this very simple so I can pinpoint the problem:
Right now my code looks like this:
$fp = pfsockopen("192.168.3.136", "3689");
$content = "GET /login?id=a90347 HTTP/1.1\r\n";
$content .= "Connection: keep-alive\r\n\r\n";
fputs($fp, $content);
while (!feof($fp)) {
echo fgets($fp, 8192);
}
What happens is, as soon as I do my fputs, I get a response header from the server that looks like this:
HTTP/1.1 200 OK
Date: Fri, 05 Mar 2010 22:05:47 GMT
RIPT-Server: iTunesLib/3.0.2 (Mac OS X)
Content-Type: application/x-dmap-tagged
Content-Length: 32
And then my cursor just sits there. After anywhere from 15 seconds to a minute, I sometimes get the content, but I am still stuck in the while loop.
Does anyone know, if after the server has sent the response header, if I should be sending something back to it to let it know that I am ready for the content?
Again, I don't think this is the case, since when I look in the packets on the network, I can see the entire response. That and the fact that I do sometimes get the content of the response. It's really like PHP can't handle this or I am just way off base.
Still need help..... :(
Working Code
$fp = pfsockopen("192.168.3.136", "3689");
$header = "GET /login?id=5648349 HTTP/1.1\r\n";
$header .= "Connection: keep-alive\r\n\r\n";
fputs($fp, $header);
$headers = array();
while(true){
$line = fgets($fp, 8192);
if($line == "\r\n"){ break; }
$line_parts = explode(': ',$line);
echo $line_parts[1]."\r\n";
$headers[$line_parts[0]] = $line_parts[1];
}
$content = fread($fp,intval($headers['Content-Length']));
echo $content;
Now, I'll have to be wary of the "\r\n" test as I'm sure it's possible that some responses might only send a "\n" after the header.
Did you try setting the socket to nonblocking mode?
socket_set_nonblock($socket);
EDIT1: Ok. Just a hunch... try this...
$fp = pfsockopen("192.168.3.136", "3689");
$content = "GET /login?id=a90347 HTTP/1.1\r\n";
$content .= "Connection: keep-alive\r\n\r\n";
fputs($fp, $content);
$headers = array();
do
{
$line = fgets($fp, 8192);
$line_parts = ecplode(': ',$line);
$headers[$line_parts[0]] = $line_parts[1];
} while($line != '');
$content = fread($fp,intval($headers['Content-Length']));
echo $content;

Categories