I'm trying to send a request to a remote server using the fire-and-forget approach. This is my code:
function backgroundPost($url, $data = array()){
$parts=parse_url($url);
$fp = fsockopen($parts['host'],
isset($parts['port'])?$parts['port']:80,
$errno, $errstr, 30);
if (!$fp) {
return false;
} else {
$encoded_data = json_encode($data);
$output = "POST ".$parts['path']." HTTP/1.1\r\n";
$output .= "Host: ".$parts['host']."\r\n";
$output .= "Content-Type: application/json\r\n";
$output .= "Content-Length: " . strlen($encoded_data) . "\r\n";
$output .= "Connection: Close\r\n\r\n";
$output .= $encoded_data;
fwrite($fp, $output);
fclose($fp);
return true;
}
}
//Example of use
backgroundPost('url-here', array("foo" => "bar"));
but the data that arrives is simply empty.
When I spin up the application locally and send the request to my own machine instead, the data does arrive.
Am I misunderstanding something about this pattern?
Why is it working when sending a request to my own machine but not a remote one?
Thanks!
I am trying to get a response from a URL using socket programming, but nothing is working correctly. I am using PHP, and I am told by the developer I am working with that I need to open a socket, send a request, and then I should get a JSON response. the $message is the string that needs to be sent in order to receive a response.
This is what I have tried so far...
$message = "api\tjson\tget\trooms\n";
$response = fsockopen("142.4.xxx.xxx", 5678);
fputs($response, $message);
fgets($response, 2048);
$data = json_decode($response, true);
And then I go on to parse the JSON response.
I have also tried,
$message = "api\tjson\tget\trooms\n";
$response = fsockopen("142.4.xxx.xxx", 5678);
fputs($response, $message);
socket_read($response, 2048, PHP_NORMAL_READ);
$data = json_decode($response, true);
But then I get an error stating that socket_read is not the correct resource. Any help would be appreciated.
You need to do some error checking, at least. Maybe this will help:
$message = "api\tjson\tget\trooms\n";
$response = fsockopen("142.4.xxx.xxx", 5678, $errno, $errstr, 30);
if (!$response) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "POST /script.php HTTP/1.1\r\n";
$out .= "Host: www.webste.com\r\n";
$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
$out .= 'Content-Length: ' . strlen($message) . "\r\n\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($response, $out);
fwrite($response, $message);
while (!feof($response)) {
echo fgets($response, 128);
}
fclose($response);
}
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
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;
I am attempting to post data using fsockopen, and then returning the result.
Here is my current code:
<?php
$data="stuff=hoorah\r\n";
$data=urlencode($data);
$fp = fsockopen("www.website.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "POST /script.php HTTP/1.0\r\n";
$out .= "Host: www.webste.com\r\n";
$out .= 'Content-Type: application/x-www-form-urlencoded\r\n';
$out .= 'Content-Length: ' . strlen($data) . '\r\n\r\n';
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
It is supposed to echo the page, and it is echoing the page, but here is the script for script.php
<?php
echo "<br><br>";
$raw_data = $GLOBALS['HTTP_RAW_POST_DATA'];
parse_str( $raw_data, $_POST );
//test 1
var_dump($raw_data);
echo "<br><br>":
//test 2
print_r( $_POST );
?>
The outcome is:
HTTP/1.1 200 OK Date: Tue, 02 Mar 2010
22:40:46 GMT Server: Apache/2.2.3
(CentOS) X-Powered-By: PHP/5.2.6
Content-Length: 31 Connection: close
Content-Type: text/html; charset=UTF-8
string(0) "" Array ( )
What do I have wrong? Why isn't the variable posting its data?
There are many small errors in your code. Here's a snippet which is tested and works.
<?php
$fp = fsockopen('example.com', 80);
$vars = array(
'hello' => 'world'
);
$content = http_build_query($vars);
fwrite($fp, "POST /reposter.php HTTP/1.1\r\n");
fwrite($fp, "Host: example.com\r\n");
fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
fwrite($fp, "Content-Length: ".strlen($content)."\r\n");
fwrite($fp, "Connection: close\r\n");
fwrite($fp, "\r\n");
fwrite($fp, $content);
header('Content-type: text/plain');
while (!feof($fp)) {
echo fgets($fp, 1024);
}
And then at example.com/reposter.php put this
<?php print_r($_POST);
When run you should get output something like
HTTP/1.1 200 OK
Date: Wed, 05 Jan 2011 21:24:07 GMT
Server: Apache
X-Powered-By: PHP/5.2.9
Vary: Host
Content-Type: text/html
Connection: close
1f
Array
(
[hello] => world
)
0
At no point is $data being written to the socket. You want to add something like:
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
fwrite($fp, $data);
Try this instead
$out .= 'Content-Length: ' . strlen($data) . '\r\n';
$out .= "Connection: Close\r\n\r\n";
$out .= $data;
Try this:
<?php
$data="stuff=hoorah\r\n";
$data=urlencode($data);
$fp = fsockopen("www.website.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "POST /script.php HTTP/1.0\r\n";
$out .= "Host: www.webste.com\r\n";
$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
$out .= 'Content-Length: ' . strlen($data) . "\r\n\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
fwrite($fp, $data);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
Some character escapes such as \n do not work in single quotes.
Nice one Tamlyn, works great!
For those that also need to send get vars along with the url,
//change this:
fwrite($fp, "POST /reposter.php HTTP/1.1\r\n");
//to:
$query = 'a=1&b=2';
fwrite($fp, "POST /reposter.php?".$query." HTTP/1.1\r\n");
Try this in reposter.php
$raw_data = $GLOBALS['HTTP_RAW_POST_DATA'];
parse_str( $raw_data, $_POST );
print_r( $_POST );
Because, the data wasn't in the $_POST[] variables but it was in the $GLOBALS['HTTP_RAW_POST_DATA'] variable.
you can use this technique it will help to call as many as pages you like all pages will run at once independently without waiting for each page response as asynchronous.
cornjobpage.php //mainpage
<?php
post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue");
//post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue2");
//post_async("http://localhost/projectname/otherpage.php", "Keywordname=anyValue");
//call as many as pages you like all pages will run at once independently without waiting for each page response as asynchronous.
?>
<?php
/*
* Executes a PHP page asynchronously so the current page does not have to wait for it to finish running.
*
*/
function post_async($url,$params)
{
$post_string = $params;
$parts=parse_url($url);
$fp = fsockopen($parts['host'],
isset($parts['port'])?$parts['port']:80,
$errno, $errstr, 30);
$out = "POST ".$parts['path']."?$post_string"." HTTP/1.1\r\n";//you can use GET instead of POST if you like
$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";
fwrite($fp, $out);
fclose($fp);
}
?>
testpage.php
<?
echo $_REQUEST["Keywordname"];//case1 Output > testValue
?>
PS:if you want to send url parameters as loop then follow this answer :https://stackoverflow.com/a/41225209/6295712
Curl is too heavy in some case, to use post_to_host():
//GET:
$str_rtn=post_to_host($str_url_target, array(), $arr_cookie, $str_url_referer, $ref_arr_head, 0);
//POST:
$arr_params=array('para1'=>'...', 'para2'=>'...');
$str_rtn=post_to_host($str_url_target, $arr_params, $arr_cookie, $str_url_referer, $ref_arr_head);
//POST with file:
$arr_params=array('para1'=>'...', 'FILE:para2'=>'/tmp/test.jpg', 'para3'=>'...');
$str_rtn=post_to_host($str_url_target, $arr_params, $arr_cookie, $str_url_referer, $ref_arr_head, 2);
//raw POST:
$tmp=array_search('uri', #array_flip(stream_get_meta_data($GLOBALS[mt_rand()]=tmpfile())));
$arr_params=array('para1'=>'...', 'para2'=>'...');
file_put_contents($tmp, json_encode($arr_params));
$arr_params=array($tmp);
$str_rtn=post_to_host($str_url_target, $arr_params, $arr_cookie, $str_url_referer, $ref_arr_head, 3);
//get cookie and merge cookies:
$arr_new_cookie=get_cookies_from_heads($ref_arr_head)+$arr_old_cookie;//don't change the order
//get redirect url:
$str_url_redirect=get_from_heads($ref_arr_head, 'Location');
post to host php project location: http://code.google.com/p/post-to-host/
Is using cURL and option?
Sorry for refresh, but for people who still have problem like this, change HTTP/1.0 to HTTP/1.1 and it will work.