(PHP 4, PHP 5)
fsockopen — Stellt eine Internet- oder Unix-Domain-Socket-Verbindung her
Initialisiert eine Socket-Verbindung zu der in hostname angegebenen Ressource.
PHP unterstützt Ziele im Internet und Unixdomänen, wie sie unter Liste der unterstützten Socket-Transporter beschrieben sind. Eine Liste unterstützter Transportarten können Sie auch mittels stream_get_transports() ermitteln.
Der Socket wird standardmäßig im Blocking Mode geöffnet. Sie können auf den Non-Blocking-Modus wechseln, indem Sie die Funktion stream_set_blocking() nutzen.
Wenn Sie OpenSSL-Support mit einkompiliert haben, können Sie dem Parameter hostname entweder ein ssl:// oder ein tls:// voranstellen, um eine SSL- oder TLS-Verbindung aufzubauen, die via TCP/IP mit dem entfernten Server verbunden wird.
Die Portnummer.
Sofern unterstützt, enthält der Parameter die Fehlernummer des Systemlevels, die beim Aufruf der connect()-Funktion auftrat.
Wenn der Rückgabewert von errno 0 ist und die Funktion FALSE zurückgibt, ist dies ein Zeichen, dass der Fehler vor dem connect()-Aufruf auftrat. Dies ist meist der Fall, wenn es ein Problem beim Initialisieren des Sockets gibt.
Die Fehlermeldung als String.
Der Connection-Timeout in Sekunden.
Hinweis:
Wenn Sie einen Timeout für das Lesen oder Schreiben von Daten über den Socket setzen wollen, verwenden Sie stream_set_timeout(), da der timeout-Parameter von fsockopen() nur für das reine Konnektieren des Sockets gedacht ist.
Die Funktion fsockopen() gibt einen Zeiger auf eine Datei zurück, der zusammen mit den anderen Dateifunktionen (wie fgets(), fgetss(), fwrite(), fclose() und feof()) verwendet werden kann. Wenn der Aufruf fehlschlägt, wird FALSE zurückgegeben.
Wirft E_WARNING, wenn hostname keine gültige Domain ist.
Version | Beschreibung |
---|---|
4.3.0 | Der Parameter timeout wird nun auch unter win32-Systemen unterstützt. |
4.3.0 | SSL und TLS over TCP/IP-Support wurde hinzugefügt. |
4.0.0 | UDP-Support wurde hinzugefügt. |
Beispiel #1 fsockopen()-Beispiel
<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
Beispiel #2 Eine UDP-Verbindung nutzen
Das folgende Beispiel zeigt, wie Sie den Tag und die Zeit vom UDP-Service "daytime" (Port 13) Ihrer Maschine abfragen können.
<?php
$fp = fsockopen("udp://127.0.0.1", 13, $errno, $errstr);
if (!$fp) {
echo "ERROR: $errno - $errstr<br />\n";
} else {
fwrite($fp, "\n");
echo fread($fp, 26);
fclose($fp);
}
?>
Hinweis:
Abhängig von der Systemumgebung kann es vorkommen, dass die Unix-Domäne oder der optionale Connection-Timeout nicht verfügbar sind.
UDP-Sockets werden manchmal ohne die Rückgabe eines Fehlermeldung geöffnet, obwohl der entfernte Host nicht erreichbar ist. Der Fehler wird nur sichtbar, wenn Sie Daten vom Socket lesen oder zum Socket schreiben wollen. Der Grund dafür ist, dass UDP ein "verbindungsloses" Protokoll ist, das bedeutet, dass das Betriebssystem nicht versucht, eine Verbindung zum Socket herzustellen, solange es nicht wirklich Daten senden oder empfangen muss.
Hinweis: Wenn Sie eine numerische IPv6-Adresse angeben, z.B. fe80::1, müssen Sie die IP in eckige Klammern schreiben, z.B. tcp://[fe80::1]:80.
<?php
/*
this script i used for remote my PvPGN Server, to check email user.
not good, but it work.
*/
set_time_limit(0);
$host = 'host';
$port = 'port';
$user = 'user';
$pass = 'pass';
$socket = fsockopen($host, $port) or die('Could not connect to: '.$host);
$userdota = "palma";
if($socket)
{
sendcmd("\r",$socket);
$status = "open"; // set status open
while($status=="open") //while we are connected to the server
{
$line = @fgets($socket, 1024) ;
/////////////login////////////////
if (strstr($line, "there is no guest account"))
{
sendcmd($user."\r\n",$socket);
sendcmd($pass."\r\n",$socket);
}
//////////////send command ////////////////////
if (strstr($line,"Your unique name: ".$user))
{ sendcmd("/finger ".$userdota."\r\n",$socket);
}
//////////////get email////////////////////
if (strstr($line,"email:")) // if respone server write "email:"
{
$pattern = '/email:(.*) ,/';
preg_match($pattern, $line, $matches);
fclose($socket);
$status="close"; // status close
$matches=str_replace(" ","", $matches);
$matches=str_replace(",is_operator:0,is_admin:0,","", $matches);
$matches=str_replace("email:","", $matches);
print $matches[0];
$email=$matches[0];
}
if (strstr($line,"ERROR: Invalid user.")) // if respone server write "ERROR: Invalid user."
{
fclose($socket);
$status="close";
$error ="Invalid User"; // error message
}
////////////login failed //////////////////////////
if (strstr($line, "Login failed")) // if respone server write "Login failed"
{
$error = "Login Failed"; // error message
fclose($socket);
$status="close";
}
flush(); // close
}
}
function sendcmd($cmd,$socket) // send command function
{
fputs($socket, $cmd, strlen($cmd));
}
?>
Make sure you don't use a double line break ("\r\n\r\n") during the middle of your header, as it appears to end the header.
This means a \r\n\r\n before "Connection: close\r\n\r\n" will not correctly tell fsockopen to close the request, leading to a max timeout error.
Some of the code on this page does this. It took me days to figure out. Example:
<?php
// Wrong:
fwrite($fp, "GET / HTTP/1.1\r\n");
fwrite($fp, "Host: php.net\r\n");
fwrite($fp, "User-Agent: example\r\n\r\n");
fwrite($fp, "Connection: Close\r\n\r\n");
// Right:
fwrite($fp, "GET / HTTP/1.1\r\n" );
fwrite($fp, "Host: php.net\r\n");
fwrite($fp, "User-Agent: example\r\n");
fwrite($fp, "Connection: Close\r\n\r\n");
?>
I would like to save people some time. I spent a couple hours trying to de-hunkify the response from apache2. I found out that if you simply make a 1.0 request vs. a 1.1 request you will get no hunks and so this simple script below will get the page you want in plain text, no hunks:
<?php
$data=false;
$url='www.example.com';
$fp = @fsockopen($url, 80, $errno, $errstr, 1);
if ($fp) {
stream_set_timeout($fp,1);
$out = "GET / HTTP/1.0\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
if (fwrite($fp, $out)) {
$content='';
$header = "not yet";
while (!feof($fp)) {
$data=true;
$line=fgets($fp,128);
if ($line=="\r\n" && $header=="not yet") {
$header = "passed";
}
if ($header=="passed") {
$content.=$line;
}
}
fclose ($fp);
}
}
if (!$data) {
print "Unable to retrieve all or part of $url";
} else {
print "$content";
}
?>
I borrowed some of the script from another poster here - the portion removing the returned header.
A short, quick unchunk function that makes use of regular expressions:
<?php
function unchunk($result) {
return preg_replace_callback(
'/(?:(?:\r\n|\n)|^)([0-9A-F]+)(?:\r\n|\n){1,2}(.*?)'.
'((?:\r\n|\n)(?:[0-9A-F]+(?:\r\n|\n))|$)/si',
create_function(
'$matches',
'return hexdec($matches[1]) == strlen($matches[2]) ? $matches[2] : $matches[0];'
),
$result
);
}
?>
I wasn’t too happy with all the code snippets I found for unchunking chunked HTTP 1.1 replies, as most of them were either bloated with stuff I don’t need or calling several other functions and thus tricky to implement. And some didn’t even work at all for me...
I just thought I could try implementing my own function and here it is. I haven't had any problems with it, so I hope someone finds this useful.
<?php
function unchunkHttp11($data) {
$fp = 0;
$outData = "";
while ($fp < strlen($data)) {
$rawnum = substr($data, $fp, strpos(substr($data, $fp), "\r\n") + 2);
$num = hexdec(trim($rawnum));
$fp += strlen($rawnum);
$chunk = substr($data, $fp, $num);
$outData .= $chunk;
$fp += strlen($chunk);
}
return $outData;
}
?>
Before calling this function you may want to check if the content is really chunked using a code snipped like this:
<?php
while (!feof($fp)) {
$reply .= fgets($fp, 1024);
}
$data = substr($reply, (strpos($reply, "\r\n\r\n")+4));
if (strpos(strtolower($reply), "transfer-encoding: chunked") !== FALSE) {
$data = unchunkHttp11($data);
}
?>
A simple proxy list checker. You can check a list ip:port if that port is opened on that IP.
<?php
$fisier = file_get_contents('proxy_list.txt'); // Read the file with the proxy list
$linii = explode("\n", $fisier); // Get each proxy
$fisier = fopen("bune.txt", "a"); // Here we will write the good ones
for($i = 0; $i < count($linii) - 1; $i++) test($linii[$i]); // Test each proxy
function test($proxy)
{
global $fisier;
$splited = explode(':',$proxy); // Separate IP and port
if($con = @fsockopen($splited[0], $splited[1], $eroare, $eroare_str, 3))
{
fwrite($fisier, $proxy . "\n"); // Check if we can connect to that IP and port
print $proxy . '<br>'; // Show the proxy
fclose($con); // Close the socket handle
}
}
fclose($fisier); // Close the file
?>
In all header aspects I can understand for 3rd party content you may not be able to apply the following but for those reading pages where content being read by fsockopen is editable then I suggest adding a simple unique tag to the beginning of any page being read such as ":THISTAG:"
Cleaning the header contents becomes simplier when you can then use a method like split to grab your data like:
list($header,$data) = explode(":THISTAG:",$data);
For some reason the default FreeBSD 7.0 port (jailed environment) breaks fsockopen() on SSL URLs, returning a constant stream of nothing! In my case this resulted in php-cgi bringing down lighttpd completely, in rapid time! Avoid FreeBSD/jails/fsockopen + SSL. Use curl_init() instead.
Just wanna add a small note:
If your URL scheme is https, remember to change port into 443.
<?php
$fp = fsockopen("ssl://www.example.com", 443, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
This makes me stuck for a while :(
note:
the default protocol - if not given - seems to be tcp://
When downloading large files, it is not really efficient to put the whole server answer in memory before parsing the data to remove the header parts. Here is a simple way to do it while writing the data as it arrive:
<?php
// $socket is a valid fsockopen handle
$out = '';
$headerendfound = false;
$fp = fopen($fileTarget, 'w');
$buffer = '';
while (!feof($socket)) {
$out = fgets ($socket,16384);
if ($headerendfound) {
fwrite($fp, $out);
print '.';
}
if (!$headerendfound) {
$buffer .= $out;
print "searching for header\n";
$headerend = strpos($buffer, "\r\n\r\n");
if ($headerend !== false) {
$headerendfound = true;
fwrite($fp, substr($buffer, $headerend+4));
$buffer = '';
}
}
}
fclose($fp);
fclose($socket);
?>
look at this smart ssl/http fsockopen function as a good solution for dealing with things
<?php
function _get($type,$host,$port='80',$path='/',$data='') {
$_err = 'lib sockets::'.__FUNCTION__.'(): ';
switch($type) { case 'http': $type = ''; case 'ssl': continue; default: die($_err.'bad $type'); } if(!ctype_digit($port)) die($_err.'bad port');
if(!empty($data)) foreach($data AS $k => $v) $str .= urlencode($k).'='.urlencode($v).'&'; $str = substr($str,0,-1);
$fp = fsockopen($host,$port,$errno,$errstr,$timeout=30);
if(!$fp) die($_err.$errstr.$errno); else {
fputs($fp, "POST $path HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ".strlen($str)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $str."\r\n\r\n");
while(!feof($fp)) $d .= fgets($fp,4096);
fclose($fp);
} return $d;
}
?>
I've been searching a big while before considering that it was impossible to use context with fsockopen, as it was in PHP4.
If you want to use sockets with tls or ssl encryption and certificates and so on, you'd better have a look to stream_socket_client.
To just take the HTTP content from fsockopen, better wait until feof finish to read the \r\n separator
<?php
//fsockopen, fputs..
$content = "";
$header = "not yet";
while( !feof( $pointer ) ) {
$line = fgets( $pointer, 128 );
if( $line == "\r\n" && $header == "not yet" ) {
$header = "passed";
}
if( $header == "passed" ) {
$content .= $line;
}
}
//fclose..
echo( substr( $content, 2 ) );
?>
[NOTE BY danbrown AT php DOT net: Updated version. Contains author-submitted bug fixes.]
Here is a way to get an array of cities / states for any zip code anywhere in the US. This example uses a $_GET variable to specify which zip code, but you can get it from any source you wish. This will return actual and acceptable zip code cities (according to USPS), but can be easily modified to include just the actual city.
<?php
if($_GET['zip'])
{
if(!($fp = fsockopen('zip4.usps.com', 80, $errno, $errstr)))
echo 'Could not connect to USPS! Error number: ' . $errno . '(' . $errstr . ')';
else
{
$poststring =
"GET /zip4/zcl_3_results.jsp?zip5=" . $_GET['zip'] . " HTTP/1.0\r\n" .
"Connection: close\r\n\r\n";
fputs($fp, $poststring);
$buffer = '';
while(!feof($fp))
$buffer .= fgets($fp, 128);
fclose($fp);
preg_match('/Actual City name(.*)/s', $buffer, $match);
$temp = explode('Not Acceptable', $match[1]);
// Capture city/state combination for all valid cities
preg_match_all('/headers="pre">(?:<b>)?([\w|\s]+), (\w+)/', $temp[0], $acceptable, PREG_SET_ORDER);
$values = array();
foreach($acceptable as $value)
$values[] =
array
(
'city' => $value[1],
'state' => $value[2]
);
if(count($values) == 0)
echo 'Zip could not be found in the database!';
}
}
else
echo 'Please specify a zip!';
?>
For those wanting to use fsockopen() to connect to a local UNIX socket who can't find documentation on how to do it, here's a (rough) example:
<?php
$sock = fsockopen('unix:///full/path/to/my/socket.sock', NULL, $errno, $errstr);
fwrite($sock, 'SOME COMMAND'."\r\n");
echo fread($sock, 4096)."\n";
fclose($sock);
?>
When you're connecting through a proxy server you can't rely on fsockopen returning false to indicate that the connection has failed. (This also applies to fgets and fwrite.)
To check whether the proxy succeeded in contacting the real target host, you need to look for the http response code in the headers that get returned. Typically, if the proxy was unable to reach the host, you'll find a line containing something like:
HTTP/1.0 503 Service Unavailable
"system level connect()" is not further documented inside the php documentation so it is hard to find out more about error numbers.
someone suggest a more system-close way to find out more about error numbers here: http://www.askapache.com/php/fsockopen-socket.html (an interesting read about fsockopen anyway).
in my case i could debug to the fact that fsocketopen error number 16 was resulted in the inpossibility to resolve a hostname.
Notice using "tcp" insted of "http"
<?php
fsockopen("tcp://example.net",80 , $errno, $errstr, 30);
?>
My $0.02 on handling chunked transfer encoded output... Has rudimentary error handling.
<?php
//
// Example usage...
//
$server = '127.0.0.1';
$port = '80';
$uri = '/cgi-bin/random-cgi';
$content = 'Your post content...';
$post_results = httpPost($server,$port,$uri,$content);
if (!is_string($post_results)) {
die('uh oh, something went wrong');
} else {
die('Here are your results: ' . $post_results);
}
//
// Post provided content to an http server and optionally
// convert chunk encoded results. Returns false on errors,
// result of post on success. This example only handles http,
// not https.
//
function httpPost($ip=null,$port=80,$uri=null,$content=null) {
if (empty($ip)) { return false; }
if (!is_numeric($port)) { return false; }
if (empty($uri)) { return false; }
if (empty($content)) { return false; }
// generate headers in array.
$t = array();
$t[] = 'POST ' . $uri . ' HTTP/1.1';
$t[] = 'Content-Type: text/html';
$t[] = 'Host: ' . $ip . ':' . $port;
$t[] = 'Content-Length: ' . strlen($content);
$t[] = 'Connection: close';
$t = implode("\r\n",$t) . "\r\n\r\n" . $content;
//
// Open socket, provide error report vars and timeout of 10
// seconds.
//
$fp = @fsockopen($ip,$port,$errno,$errstr,10);
// If we don't have a stream resource, abort.
if (!(get_resource_type($fp) == 'stream')) { return false; }
//
// Send headers and content.
//
if (!fwrite($fp,$t)) {
fclose($fp);
return false;
}
//
// Read all of response into $rsp and close the socket.
//
$rsp = '';
while(!feof($fp)) { $rsp .= fgets($fp,8192); }
fclose($fp);
//
// Call parseHttpResponse() to return the results.
//
return parseHttpResponse($rsp);
}
//
// Accepts provided http content, checks for a valid http response,
// unchunks if needed, returns http content without headers on
// success, false on any errors.
//
function parseHttpResponse($content=null) {
if (empty($content)) { return false; }
// split into array, headers and content.
$hunks = explode("\r\n\r\n",trim($content));
if (!is_array($hunks) or count($hunks) < 2) {
return false;
}
$header = $hunks[count($hunks) - 2];
$body = $hunks[count($hunks) - 1];
$headers = explode("\n",$header);
unset($hunks);
unset($header);
if (!verifyHttpResponse($headers)) { return false; }
if (in_array('Transfer-Coding: chunked',$headers)) {
return trim(unchunkHttpResponse($body));
} else {
return trim($body);
}
}
//
// Validate http responses by checking header. Expects array of
// headers as argument. Returns boolean.
//
function validateHttpResponse($headers=null) {
if (!is_array($headers) or count($headers) < 1) { return false; }
switch(trim(strtolower($headers[0]))) {
case 'http/1.0 100 ok':
case 'http/1.0 200 ok':
case 'http/1.1 100 ok':
case 'http/1.1 200 ok':
return true;
break;
}
return false;
}
//
// Unchunk http content. Returns unchunked content on success,
// false on any errors... Borrows from code posted above by
// jbr at ya-right dot com.
//
function unchunkHttpResponse($str=null) {
if (!is_string($str) or strlen($str) < 1) { return false; }
$eol = "\r\n";
$add = strlen($eol);
$tmp = $str;
$str = '';
do {
$tmp = ltrim($tmp);
$pos = strpos($tmp, $eol);
if ($pos === false) { return false; }
$len = hexdec(substr($tmp,0,$pos));
if (!is_numeric($len) or $len < 0) { return false; }
$str .= substr($tmp, ($pos + $add), $len);
$tmp = substr($tmp, ($len + $pos + $add));
$check = trim($tmp);
} while(!empty($check));
unset($tmp);
return $str;
}
?>
When you try to POST/GET requests via HTTPS over SSL/TLS you should notice this:
<?php
// preconditions
$port = 80 | 443
$host = "www.example.com";
$method = "POST" | "GET";
$contenttype = "text/html" | "text/plain" | "text/xml" | ...;
$data = "<something>";
// script
if($port == 443)
$sslhost = "ssl://".$host;
else
$sslhost = $host;
$fp = fsockopen($sslhost, $port);
fputs($fp, "$method $path HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-type: $contenttype\r\n");
fputs($fp, "Content-length: ".strlen($data)."\r\n");
fputs($fp, "Connection: close\r\n");
fputs($fp, "\r\n");
?>
The server usually does not understand the HTTP-header "Host: XXX" if you provide it with the trailing "ssl://" used by fsockopen(); If you do it anyway you probably get a HTTP 400 back as response. :-)
If you have to use a proxy to make requests outside of your local network, you may use this class:
<?php
/*
*
* No Proxy Authentification Implemented; PHP 5
*
*/
class RemoteFopenViaProxy {
private $result;
private $proxy_name;
private $proxy_port;
private $request_url;
public function get_proxy_name() {
return $this->proxy_name;
}
public function set_proxy_name($n) {
$this->proxy_name = $n;
}
public function get_proxy_port() {
return $this->proxy_port;
}
public function set_proxy_port($p) {
$this->proxy_port = $p;
}
public function get_request_url() {
return $this->request_url;
}
public function set_request_url($u) {
$this->request_url = $u;
}
public function get_result() {
return $this->result;
}
public function set_result($r) {
$this->result = $r;
}
private function get_url_via_proxy() {
$proxy_fp = fsockopen($this->get_proxy_name(), $this->get_proxy_port());
if (!$proxy_fp) {
return false;
}
fputs($proxy_fp, "GET " . $this->get_request_url() . " HTTP/1.0\r\nHost: " . $this->get_proxy_name() . "\r\n\r\n");
while (!feof($proxy_fp)) {
$proxy_cont .= fread($proxy_fp, 4096);
}
fclose($proxy_fp);
$proxy_cont = substr($proxy_cont, strpos($proxy_cont, "\r\n\r\n") + 4);
return $proxy_cont;
}
private function get_url($url) {
$fd = @ file($url);
if ($fd) {
return $fd;
} else {
return false;
}
}
private function logger($line, $file) {
$fd = fopen($file . ".log", "a+");
fwrite($fd, date("Ymd G:i:s") . " - " . $file . " - " . $line . "\n");
fclose($fd);
}
function __construct($url, $proxy_name = "", $proxy_port = "") {
$this->set_request_url($url);
$this->set_proxy_name($proxy_name);
$this->set_proxy_port($proxy_port);
}
public function request_via_proxy() {
$this->set_result($this->get_url_via_proxy());
if (!$this->get_result()) {
$this->logger("FAILED: get_url_via_proxy(" . $this->get_proxy_name() . "," . $this->get_proxy_port() . "," . $this->get_request_url() . ")", "RemoteFopenViaProxyClass.log");
}
}
public function request_without_proxy() {
$this->set_result($this->get_url($this->get_request_url()));
if (!$this->get_result()) {
$this->logger("FAILED: get_url(" . $url . ")", "RemoteFopenViaProxyClass.log");
}
}
}
?>
Use it this way:
<?php
// call constructor
$obj = new RemoteFopenViaProxy($insert_request_url, $insert_proxy_name, $insert_proxy_port);
// change settings after object generation
$obj->set_proxy_name($insert_proxy_name);
$obj->set_proxy_port($insert_proxy_port);
$obj->set_request_url($insert_request_url);
$obj->request_via_proxy();
echo $obj->get_result();
?>
If there are errors during execution, the script tries to write some useful information into a log file.
An edit to my below function for extra headers support and a bit of debugging
( array("key" => "value") type)
<?php
if(!function_exists("download")){
function download($uri, $port = 80, $extra_headers = NULL){
if(!function_exists("stripos")){
function stripos($str, $needle, $offset=0){
return strpos(strtolower($str),strtolower($needle),$offset);
}/* endfunction stripos */
}/* endfunction exists stripos*/
if(!is_int($port))$port = 80;
if(!is_array($extra_headers))$extra_headers = array();
$uri = strtr( strval($uri), array("http://" => "", "https://" => "ssl://", "ssl://" => "ssl://", "\\" => "/", "//" => "/") );
if( ( $protocol = stripos($uri, "://") ) !== FALSE ){
if( ( $domain_pos = stripos($uri, "/", ($protocol + 3)) ) !== FALSE ){
$domain = substr($uri, 0, $domain_pos);
$file = substr($uri, $domain_pos);
}
else{
$domain = $uri;
$file = "/";
}
}
else{
if( ( $domain_pos = stripos($uri, "/") ) !== FALSE ){
$domain = substr($uri, 0, $domain_pos);
$file = substr($uri, $domain_pos);
}
else{
$domain = $uri;
$file = "/";
}
}
$fp = fsockopen($domain, $port, $errno, $errstr, 30);
if(!$fp){
return FALSE;
}
else{
$out = "GET " . $file . " HTTP/1.1\r\n";
$out .= "Host: " . $domain . "\r\n";
foreach( $extra_headers as $nm => $vl ){
$out .= strtr( strval($nm), array( "\r" => "", "\n" => "", ": " => "", ":" => "") ) . ": " . strtr( strval($vl), array( "\r" => "", "\n" => "", ": " => "", ":" => "") ) . "\r\n";
}
$out .= "Connection: Close\r\n\r\n";
$response = "";
fwrite($fp, $out);
while (!feof($fp)) {
$response .= fgets($fp, 128);
}
fclose($fp);
global $http_response_header;
$http_response_header = array();
if( stripos($response, "\r\n\r\n") !== FALSE ){
$hc = explode("\r\n\r\n", $response);
$headers = explode("\r\n", $hc[0]);
if(!is_array($headers))$headers = array();
foreach($headers as $key => $header){
$a = "";
$b = "";
if( stripos($header, ":") !== FALSE ){
list($a, $b) = explode(":", $header);
$http_response_header[trim($a)] = trim($b);
}
}
return end($hc);
}
else if( stripos($response, "\r\n") !== FALSE ){
$headers = explode("\r\n", $response);
if(!is_array($headers))$headers = array();
foreach($headers as $key => $header){
if( $key < ( count($headers) - 1 ) ){
$a = "";
$b = "";
if( stripos($header, ":") !== FALSE ){
list($a, $b) = explode(":", $header);
$http_response_header[trim($a)] = trim($b);
}
}
}
return end($headers);
}
else{
return $response;
}
}
}/*endfunction download*/
}/*endif no function download*/
?>
<?php
// Check for new version
$current_version = explode('.', '1.0.00');
$minor_revision = (int) $current_version[2];
$errno = 0;
$errstr = $version_info = '';
if ($fsock = fsockopen("www.exanmple.eu", 80, $errno, $errstr, 30))
{
@fputs($fsock, "GET /ver.txt HTTP/1.1\r\n");
@fputs($fsock, "HOST: www.example.eu\r\n");
@fputs($fsock, "Connection: close\r\n\r\n");
$get_info = false;
while (!@feof($fsock))
{
if ($get_info)
{
$version_info .= @fread($fsock, 1024);
}
else
{
if (@fgets($fsock, 1024) == "\r\n")
{
$get_info = true;
}
}
}
@fclose($fsock);
$version_info = explode("\n", $version_info);
$latest_head_revision = (int) $version_info[0];
$latest_minor_revision = (int) $version_info[2];
$latest_version = (int) $version_info[0] . '.' . (int) $version_info[1] . '.' . (int) $version_info[2];
if ($latest_head_revision == 2 && $minor_revision == $latest_minor_revision)
{
$version_info = '<p style="color:green">OK</p>';
}
else
{
$version_info = '<p style="color:red">neaktualne';
$version_info .= '<br />'Latest_version_info' . $latest_version) . ' ' . sprintf(Current_version_info'. '1.0.00') . '</p>';
}
}
else
{
if ($errstr)
{
$version_info = '<p style="color:red">' . sprintf(Connect_socket_error) . '</p>';
}
else
{
$version_info = '<p>'Socket_functions_disabled'</p>';
}
}
$version_info .= '<p>'Mailing_list_subscribe_reminder'</p>';
echo $version_info;
?>
The DEFAULT stream timeout is set according to default_socket_timeout in your php.ini file. Took forever for me to dig that up....
For those of you who do not have cURL, you might want to try this.
It doesn't have all the functions that cURL has, but it has the basics.
Please let me know of any bugs or problems.
<?php
function open_page($url,$f=1,$c=2,$r=0,$a=0,$cf=0,$pd=""){
global $oldheader;
$url = str_replace("http://","",$url);
if (preg_match("#/#","$url")){
$page = $url;
$url = @explode("/",$url);
$url = $url[0];
$page = str_replace($url,"",$page);
if (!$page || $page == ""){
$page = "/";
}
$ip = gethostbyname($url);
}else{
$ip = gethostbyname($url);
$page = "/";
}
$open = fsockopen($ip, 80, $errno, $errstr, 60);
if ($pd){
$send = "POST $page HTTP/1.0\r\n";
}else{
$send = "GET $page HTTP/1.0\r\n";
}
$send .= "Host: $url\r\n";
if ($r){
$send .= "Referer: $r\r\n";
}else{
if ($_SERVER['HTTP_REFERER']){
$send .= "Referer: {$_SERVER['HTTP_REFERER']}\r\n";
}
}
if ($cf){
if (@file_exists($cf)){
$cookie = urldecode(@file_get_contents($cf));
if ($cookie){
$send .= "Cookie: $cookie\r\n";
$add = @fopen($cf,'w');
fwrite($add,"");
fclose($add);
}
}
}
$send .= "Accept-Language: en-us, en;q=0.50\r\n";
if ($a){
$send .= "User-Agent: $a\r\n";
}else{
$send .= "User-Agent: {$_SERVER['HTTP_USER_AGENT']}\r\n";
}
if ($pd){
$send .= "Content-Type: application/x-www-form-urlencoded\r\n";
$send .= "Content-Length: " .strlen($pd) ."\r\n\r\n";
$send .= $pd;
}else{
$send .= "Connection: Close\r\n\r\n";
}
fputs($open, $send);
while (!feof($open)) {
$return .= fgets($open, 4096);
}
fclose($open);
$return = @explode("\r\n\r\n",$return,2);
$header = $return[0];
if ($cf){
if (preg_match("/Set\-Cookie\: /i","$header")){
$cookie = @explode("Set-Cookie: ",$header,2);
$cookie = $cookie[1];
$cookie = explode("\r",$cookie);
$cookie = $cookie[0];
$cookie = str_replace("path=/","",$cookie[0]);
$add = @fopen($cf,'a');
fwrite($add,$cookie,strlen($read));
fclose($add);
}
}
if ($oldheader){
$header = "$oldheader<br /><br />\n$header";
}
$header = str_replace("\n","<br />",$header);
if ($return[1]){
$body = $return[1];
}else{
$body = "";
}
if ($c === 2){
if ($body){
$return = $body;
}else{
$return = $header;
}
}
if ($c === 1){
$return = $header;
}
if ($c === 3){
$return = "$header$body";
}
if ($f){
if (preg_match("/Location\:/","$header")){
$url = @explode("Location: ",$header);
$url = $url[1];
$url = @explode("\r",$url);
$url = $url[0];
$oldheader = str_replace("\r\n\r\n","",$header);
$l = "Location:";
$oldheader = str_replace("Location:",$l,$oldheader);
return open_page($url,$f,$c,$r,$a,$cf,$pd);
}else{
return $return;
}
}else{
return $return;
}
}
/////////////
////Usage////
/////////////
$url = "http://www.php.net";
$f = 1;
$c = 2;//1 for header, 2 for body, 3 for both
$r = NULL;
$a = NULL;
$cf = NULL;
$pd = NULL;
$page = open_page($url,$f,$c,$r,$a,$cf,$pd);
print $page;
?>
I was having trouble doing an https in fopen and with fsockopen where the address had ssl://. I was getting error code 114 in the log. After much research i found that there was some ssl conflict trouble with MySQL 5.0.20-5.0.33. It had some functions that were interfering with openssl that showed up in the php install.
http://bugs.mysql.com/bug.php?id=21930
http://bugs.mysql.com/bug.php?id=19289
I ran into a problem where I needed to make an fsockopen() style connection from one specific ip address on a server with multiple ip aliases. Unfortunately fsockopen() does not allow the specification of a source address making it unsuitable. I could not find any other solutions elsewhere so here is mine for those with php 5.1.0 or greater.
<?php
// connect to the internet using the '192.168.0.100' IP
$opts = array('socket' => array('bindto' => '192.168.0.100:0'));
$context = stream_context_create($opts);
$fp = stream_socket_client("tcp://www.example.com:80", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
?>
Now $fp can be used like a resource handle returned by a vanilla fsockopen() call!
easy get UIDL.
A code is better than the feof.
<?php
$fp = fsockopen($host, 110, $errno, $errstr, 5);
if ($fp > 0) {
fread($fp,1024);
fputs($fp, "USER $user\r\n");
fread($fp,1024);
fputs($fp, "PASS $pass\r\n");
fread($fp,1024);
fputs($fp, "UIDL\r\n");
fgets($fp,1024);
do {
$line = rtrim(fgets($fp, 1024));
if ($line == '.') break;
list(, $UIDL) = split(' ', $line, 2);
echo $UIDL;
} while ($line != '.');
fputs($fp, "QUIT\r\n");
}
fclose($fp);
?>
To check if a Url is Online (with http and https)
Using @fgets to hide Warning when using SSL
(Bug: "Warning: function.fgets SSL: fatal protocol error", http://bugs.php.net/bug.php?id=23220)
<?php
function isOnline($url) {
if (!$url_info = parse_url($url)) {
return false;
}
switch ($url_info['scheme']) {
case 'https':
$scheme = 'ssl://';
$port = 443;
break;
case 'http':
default:
$scheme = '';
$port = 80;
}
$data = "";
$fid = @fsockopen($scheme . $url_info['host'], $port, $errno, $errstr, 30);
if ($fid) {
fputs($fid, 'HEAD ' . (isset($url_info['path'])? $url_info['path']: '/') . (isset($url_info['query'])? '?' . $url_info['query']: '') . " HTTP/1.0\r\n" .
"Connection: close\r\n" .
'Host: ' . $url_info['host'] . "\r\n\r\n");
while (!feof($fid)) {
$data .= @fgets($fid, 128);
}
fclose($fid);
return !empty($data);
} else {
return false;
}
}
?>
[EDIT by danbrown AT php DOT net: This note contains a big-fixed version of the user function decode_body(). Fix by (martjean77 at hot dot sapm dot mail dot com) [sic].]
Handling chunked data needs careful handling, because the data can also be compressed inside the chunked data, and chunked data can have many parts, so you need to watch for that. Here a simple example that uses one function decode_header(); to build the header into a key => value array, so it makes it easy to test for the content and transfer types inside the decode_body(); function!
<?php
function decode_header ( $str )
{
$part = preg_split ( "/\r?\n/", $str, -1, PREG_SPLIT_NO_EMPTY );
$out = array ();
for ( $h = 0; $h < sizeof ( $part ); $h++ )
{
if ( $h != 0 )
{
$pos = strpos ( $part[$h], ':' );
$k = strtolower ( str_replace ( ' ', '', substr ( $part[$h], 0, $pos ) ) );
$v = trim ( substr ( $part[$h], ( $pos + 1 ) ) );
}
else
{
$k = 'status';
$v = explode ( ' ', $part[$h] );
$v = $v[1];
}
if ( $k == 'set-cookie' )
{
$out['cookies'][] = $v;
}
else if ( $k == 'content-type' )
{
if ( ( $cs = strpos ( $v, ';' ) ) !== false )
{
$out[$k] = substr ( $v, 0, $cs );
}
else
{
$out[$k] = $v;
}
}
else
{
$out[$k] = $v;
}
}
return $out;
}
function decode_body ( $info, $str, $eol = "\r\n" )
{
$tmp = $str;
$add = strlen ( $eol );
$str = '';
if ( isset ( $info['transfer-encoding'] ) && $info['transfer-encoding'] == 'chunked' )
{
do
{
$tmp = ltrim ( $tmp );
$pos = strpos ( $tmp, $eol );
$len = hexdec ( substr ( $tmp, 0, $pos ) );
if ( isset ( $info['content-encoding'] ) )
{
$str .= gzinflate ( substr ( $tmp, ( $pos + $add + 10 ), $len ) );
}
else
{
$str .= substr ( $tmp, ( $pos + $add ), $len );
}
$tmp = substr ( $tmp, ( $len + $pos + $add ) );
$check = trim ( $tmp );
}
while ( ! empty ( $check ) );
}
else if ( isset ( $info['content-encoding'] ) )
{
$str = gzinflate ( substr ( $tmp, 10 ) );
}
else {
$str = $tmp;
}
return $str;
}
if ( ( $io = fsockopen( "www.yahoo.com", 80, $errno, $errstr, 5 ) ) !== false )
{
$send = "GET / HTTP/1.1\r\n";
$send .= "Host: www.yahoo.com\r\n";
$send .= "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20021204\r\n";
$send .= "Referer: http://www.yahoo.com/\r\n";
$send .= "Accept: text/xml,application/xml,application/xhtml+xml,";
$send .= "text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,";
$send .= "image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1\r\n";
$send .= "Accept-Language: en-us, en;q=0.50\r\n";
$send .= "Accept-Encoding: gzip, deflate, compress;q=0.9\r\n";
$send .= "Connection: Close\r\n\r\n";
fputs ( $io, $send );
$send = '';
do
{
$send .= fgets ( $io, 4096 );
} while ( strpos ( $send, "\r\n\r\n" ) === false );
$info = decode_header ( $send );
$send = '';
while ( ! feof ( $io ) )
{
$send .= fread ( $io, 8192 );
}
fclose ( $io );
$send = decode_body ( $info, $send );
echo '<h3>Header Array</h3>';
echo '<pre>';
print_r ( $info );
echo '</pre>';
echo '<h3>Document Body</h3>';
echo $send;
}
?>
This script checks specific ports so you need to have the correct port open on the server for this to work.
E.g if i have a windows domain controller and it is servering LDAP then the following would be used to check it is online:
<?php
chkServer("MyDC", "389");
?>
for a webserver:
<?php
chkServer("MyWebSvr", "80");
?>
etc etc
--------------------------------------------------------
<?php
// check if a server is up by connecting to a port
function chkServer($host, $port)
{
$hostip = @gethostbyname($host); // resloves IP from Hostname returns hostname on failure
if ($hostip == $host) // if the IP is not resloved
{
echo "Server is down or does not exist";
}
else
{
if (!$x = @fsockopen($hostip, $port, $errno, $errstr, 5)) // attempt to connect
{
echo "Server is down";
}
else
{
echo "Server is up";
if ($x)
{
@fclose($x); //close connection
}
}
}
}
?>
The following function performs pop3 authentication. Returns NULL on error, or true/false to indicate username/password matching:
$address is the hostname of the server and $ssl is a boolean that indicates whether an SSL connection is requested.
<?php
function pop3authCheck($username, $password, $address, $ssl)
{
if ($ssl)
$uri="ssl://$address:995";
else
$uri="tcp://$address:110";
$fp=fsockopen($uri);
if (!$fp)
return(NULL);
$st=fgets($fp, 512);
if (substr($st, 0, 3)!="+OK")
{
fclose($fp);
return(NULL);
}
$st="USER $username\n";
if (fwrite($fp, $st)!=strlen($st))
{
fclose($fp);
return(NULL);
}
$st=fgets($fp, 512);
if (substr($st, 0, 3)!="+OK")
{
fclose($fp);
return(NULL);
}
$st="PASS $password\n";
if (fwrite($fp, $st)!=strlen($st))
{
fclose($fp);
return(NULL);
}
$st=fgets($fp, 512);
fclose($fp);
if (substr($st, 0, 3)=="+OK")
return(true);
else if (substr($st, 0, 4)=="+ERR")
return(false);
else
return(NULL);
}
?>
I've had issues with some of the handlers for chunked http 1.1 responses. Here's a method that worked for me, if it works for you as well, then cheers :P
<?php
function httpSocketConnection($host, $method, $path, $data)
{
$method = strtoupper($method);
if ($method == "GET")
{
$path.= '?'.$data;
}
$filePointer = fsockopen($host, 80, $errorNumber, $errorString);
if (!$filePointer)
{
logEvent('debug', 'Failed opening http socket connection: '.$errorString.' ('.$errorNumber.')<br/>\n');
return false;
}
$requestHeader = $method." ".$path." HTTP/1.1\r\n";
$requestHeader.= "Host: ".$host."\r\n";
$requestHeader.= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\r\n";
$requestHeader.= "Content-Type: application/x-www-form-urlencoded\r\n";
if ($method == "POST")
{
$requestHeader.= "Content-Length: ".strlen($data)."\r\n";
}
$requestHeader.= "Connection: close\r\n\r\n";
if ($method == "POST")
{
$requestHeader.= $data;
}
fwrite($filePointer, $requestHeader);
$responseHeader = '';
$responseContent = '';
do
{
$responseHeader.= fread($filePointer, 1);
}
while (!preg_match('/\\r\\n\\r\\n$/', $responseHeader));
if (!strstr($responseHeader, "Transfer-Encoding: chunked"))
{
while (!feof($filePointer))
{
$responseContent.= fgets($filePointer, 128);
}
}
else
{
while ($chunk_length = hexdec(fgets($filePointer)))
{
$responseContentChunk = '';
logEventToTextFile('debug', $chunk_length);
$read_length = 0;
while ($read_length < $chunk_length)
{
$responseContentChunk .= fread($filePointer, $chunk_length - $read_length);
$read_length = strlen($responseContentChunk);
}
$responseContent.= $responseContentChunk;
fgets($filePointer);
}
}
logEventToTextFile('debug', $responseContent);
return chop($responseContent);
}
?>
I had a problem receving a "Content-Transfer: chunked" response i tried some prior codes but i had some problems too and i decided to code my own (it post something and receive the response although it's chunked). I hope you enjoy...
<?php
function doPost($uri,$postdata,$host){
$da = fsockopen($host, 80, $errno, $errstr);
if (!$da) {
echo "$errstr ($errno)<br/>\n";
echo $da;
}
else {
$salida ="POST $uri HTTP/1.1\r\n";
$salida.="Host: $host\r\n";
$salida.="User-Agent: PHP Script\r\n";
$salida.="Content-Type: application/x-www-form-urlencoded\r\n";
$salida.="Content-Length: ".strlen($postdata)."\r\n";
$salida.="Connection: close\r\n\r\n";
$salida.=$postdata;
fwrite($da, $salida);
while (!feof($da))
$response.=fgets($da, 128);
$response=split("\r\n\r\n",$response);
$header=$response[0];
$responsecontent=$response[1];
if(!(strpos($header,"Transfer-Encoding: chunked")===false)){
$aux=split("\r\n",$responsecontent);
for($i=0;$i<count($aux);$i++)
if($i==0 || ($i%2==0))
$aux[$i]="";
$responsecontent=implode("",$aux);
}//if
return chop($responsecontent);
}//else
}//function-doPost
?>
If you want to GET/POST some page through the HTTP protocol and if you want to keep-alive your connection, you may have a problem with a loop-stuck. Here is hint how to solve it:
<?php
$fp = fsockopen ("www.php.net", 80, $errno, $errstr, 30);
if(!$fp) {
echo $errstr;
} else {
fwrite($fp, "GET / HTTP/1.1\r\nHost: www.php.net\r\nConnection: Keep-Alive\r\n\r\n");
$data = '';
while(!feof($fp)) {
$data .= fread($fp, 4096);
if(substr($data, -9)=="\r\n\r\n0\r\n\r\n") {
exit;
}
}
}
echo $data;
?>
When your connection times out the server may issue Fatal error: Maximum execution time of 30 seconds exceeded in ...
To get around this try this method used with error handling and copied method for ping operation.
<?php
function Ping(){
// false proxy used to generate connection error
$ProxyServer = "116.155.95.163";
$ProxyPort = 8080;
$timeout=10;
echo "Opening ProxyServer $ProxyServer<br>";
// must use next two statements
Set_Time_Limit(0); //Time for script to run .. not sure how it works with 0 but you need it
Ignore_User_Abort(True); //this will force the script running at the end
$handle = fsockopen($ProxyServer, $ProxyPort,$errno,$errstr,$timeout);
if (!$handle){
echo "Failed to open ProxyServer $ProxyServer errno=$errno,errstr=$errstr<br>";
return 0;
}
else {
// copied method for PING like time operation
$status = socket_get_status($handle);
echo "Opened ProxyServer $ProxyServer<br>";
//Time the responce
list($usec, $sec) = explode(" ", microtime(true));
$start=(float)$usec + (float)$sec;
$timeout=120;
stream_set_timeout($handle,$timeout);
//send somthing
ini_set('display_errors','0');
$write=fwrite($handle,"echo this\n");
if(!$write){
return 0;
}
echo "Try To Read<br>";
stream_set_blocking($handle,0);
//Try to read. the server will most likely respond with a "ICMP Destination Unreachable" and end the read. But that is a responce!
fread($handle,1024);
fclose($handle);
echo "Read<br>";
ini_set('display_errors','1');
//Work out if we got a responce and time it
list($usec, $sec) = explode(" ", microtime(true));
$laptime=((float)$usec + (float)$sec)-$start;
if($laptime>$timeout)
return 0;
//else
// $laptime = round($laptime,3);
return $laptime;
}
}
// must use ErrorHandler to avoid php error being printed to screen
function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars)
{
// you can set this to what ever you like.
echo "In Error Handler<br>";
return 0;
}
$old_error_handler = set_error_handler("userErrorHandler");
$time = Ping();
echo "Time=$time<br>";
echo "Done Checking<br>";
?>
Response Will be:
Opening ProxyServer 116.155.95.163
In Error Handler
Failed to open ProxyServer 116.155.95.163 errno=10060,errstr=A connection attempt failed
because the connected party did not properly respond after a period of time, or
established connection failed because connected host has failed to respond.
Time=0
Done Checking
Thanks to everyone for your source code examples.
AndE
This is a simple example for sending and retrieve SOAP message by using fsockopen:
<?php
$fp = @fsockopen("www.example.com", 80, $errno, $errstr);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$soap_out = "POST /example/exampleServer.php HTTP/1.0\r\n";
$soap_out .= "Host: www.example.com\r\n";
$soap_out .= "User-Agent: MySOAPisOKGuys \r\n";
$soap_out .= "Content-Type: text/xml; charset=ISO-8859-1\r\n";
$soap_out .= "Content-Length: 512\r\n\r\n";
$soap_out .= '<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns5973:contact xmlns:ns5973="http://tempuri.org">
<__numeric_0><id xsi:nil="true"/></__numeric_0>
</ns5973:contact>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
fputs($fp, $soap_out, strlen($soap_out)); // send request SOAP
echo "<xmp>".$out."</xmp>";
while (!feof($fp)) {
$soap_in . = fgets($fp, 100);
}
echo "<xmp>$soap_in</xmp>"; //display response SOAP
fclose($fp);
}
?>
And this is an example result:
POST /soap/example/contactServer.php HTTP/1.0
Host: www.example.com
User-Agent: MySOAPisOKGuys
Content-Type: text/xml; charset=ISO-8859-1
Content-Length: 512
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><ns5973:contact
xmlns:ns5973="http://tempuri.org"><__numeric_0><id
xsi:nil="true"/></__numeric_0></ns5973:contact>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
HTTP/1.1 200 OK
Date: Thu, 06 Apr 2006 07:03:26 GMT
Server: Apache/1.3.23 (Win32)
X-Powered-By: PHP/4.1.1
X-SOAP-Server: MySOAPisOKGuys
Content-Length: 625
Connection: close
Content-Type: text/xml; charset=ISO-8859-1
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><ns1:contactResponse
xmlns:ns1="http://tempuri.org">
<return xsi:type="xsd:string">
</return>
</ns1:contactResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Lots of tries and lots of reading http-headers...
If you want to post $_POST vars and (in this case) one file named userfile to $remote_server and $remote_url.
<?php
// get the necessary data
$file_name = $_FILES['userfile']['name']; // the file
$tmp_name = $_FILES['userfile']['tmp_name']; // the file
$content_type = $_FILES['userfile']['type']; // the file mime type
srand((double)microtime()*1000000);
$boundary = "---------------------".substr(md5(rand(0,32000)),0,10);
// Build the header
$header = "POST $remote_url HTTP/1.0\r\n";
$header .= "Host: $remote_server\r\n";
$header .= "Content-type: multipart/form-data, boundary=$boundary\r\n";
// attach post vars
foreach($_POST AS $index => $value){
$data .="--$boundary\r\n";
$data .= "Content-Disposition: form-data; name=\"".$index."\"\r\n";
$data .= "\r\n".$value."\r\n";
$data .="--$boundary\r\n";
}
// and attach the file
$data .= "--$boundary\r\n";
$content_file = join("", file($tmp_name));
$data .="Content-Disposition: form-data; name=\"userfile\"; filename=\"$file_name\"\r\n";
$data .= "Content-Type: $content_type\r\n\r\n";
$data .= "".$content_file."\r\n";
$data .="--$boundary--\r\n";
$header .= "Content-length: " . strlen($data) . "\r\n\r\n";
// Open the connection
$fp = fsockopen($remote_server, 80);
// then just
fputs($fp, $header.$data);
fclose($fp);
?>
login to the site prior to downloading page:
In some wierd situations site security is based on
ASPSESSION ID and where could be a
login asp script in one place, and the actual page with
information in another place.
for such cases you have to submit ( POST ) you login and
password first, when grab ASP session (and also some
cookies from response, and when use that ASP SESSION in
second request to the actual page: (i took some parts of
codes from other ppl)
<?php
//submit login form: (url, post data, extra headers (optional))
//do not put http into URL, just domain name
$mycookies = GetCookies("www.yourdomain.com/login.login.asp",
"password=12345&username=your_username&submit=LOGIN&set=Y","");
//some extra params if you need them
// echo "Cookies:<br><pre>\n".$mycookies."\n</pre>";
//$body =PostPage("www.example.com/coolpage.asp",
//"action=zzz",$mycookies);
//echo "<br>Body:<br>\n".$body."\n";
//im using get page - so it goes like this:
$opts = array('http'=>array('method'=>"GET",
'header'=>"Accept-language: en\r\nCookie: ".$mycookies."\r\n" ));
$context = stream_context_create($opts);
$fp = fopen('http://www.example.com/coolpage.asp?p1=1&p2=23', 'r', false, $context);
fpassthru($fp);
$html = fread($fp, 1000000);
fclose($fp);
echo $html;
function PostPage($host,$query,$others=''){
$path=explode('/',$host);
$host=$path[0];
unset($path[0]);
$path='/'.(implode('/',$path));
$post="POST $path HTTP/1.1\r\nHost: $host\r\n";
$post.="Content-type: application/x-www-form-";
$post.="urlencoded\r\n${others}";
$post.="User-Agent: Mozilla 4.0\r\nContent-length: ";
$post.=strlen($query)."\r\nConnection: close\r\n\r\n$query";
$h=fsockopen($host,80);
fwrite($h,$post);
for($a=0,$r='';!$a;){
$b=fread($h,8192);
$r.=$b;
$a=(($b=='')?1:0);
}
fclose($h);
return $r;
}
function GetCookies($host,$query,$others=''){
$path=explode('/',$host);
$host=$path[0];
unset($path[0]);
$crlf = "\r\n";
$path='/'.(implode('/',$path));
$post="POST $path HTTP/1.1\r\nHost: $host\r\n";
$post.="Content-type: application/x-www-form-urlencoded\r\n${others}";
$post.="User-Agent: Mozilla 4.0\r\nContent-length: ";
$post.=strlen($query)."\r\nConnection: close\r\n\r\n$query";
$h=fsockopen($host,80);
fwrite($h,$post);
$r="";
for($a=0;!$a;){
$b=fread($h,512);
echo $b;
$r.=$b;
$gotSession=strpos($r,"ASPSESSION");
if($gotSession)
if(strpos($r, $crlf . $crlf,$gotSession)>0) break;
$a=(($b=='')?1:0);
}
fclose($h);
$arr = split("Set-Cookie:",$r);
$AllCookies="";$count=1;
while ($count < count($arr)) {
$AllCookies.=substr($arr[$count].";",
0,strpos($arr[$count].";",";")+1);
$count++;}
return $AllCookies;
}
?>
It's not optimized , but i hope someone might find it usefull.
Best Regards
DRY_GIN
We have implemented a Syslog class in PHP following the RFC 3164 rules. Using this class, it is possible to send syslog messages to external servers.
We use this class for example to log information, to synchronize some processes or to launch external "threads".
Class abstract, full class implementation can be found at http://developer.sysco.ch/php/
<?php
// (...)
class Syslog
{
var $_facility; // 0-23
var $_severity; // 0-7
var $_hostname; // no embedded space, no domain name, only a-z A-Z 0-9 and other authorized characters
var $_fqdn;
var $_ip_from;
var $_process;
var $_content;
var $_msg;
var $_server; // Syslog destination server
var $_port; // Standard syslog port is 514
var $_timeout; // Timeout of the UDP connection (in seconds)
// (...)
function Send($server = "", $content = "", $timeout = 0)
{
// (...)
$actualtime = time();
$month = date("M", $actualtime);
$day = substr(" ".date("j", $actualtime), -2);
$hhmmss = date("H:i:s", $actualtime);
$timestamp = $month." ".$day." ".$hhmmss;
$pri = "<".($this->_facility*8 + $this->_severity).">";
$header = $timestamp." ".$this->_hostname;
// (...)
$msg = $this->_process.": ".$this->_fqdn." ".$this->_ip_from." ".$this->_content;
$message = substr($pri.$header." ".$msg, 0, 1024);
$fp = fsockopen("udp://".$this->_server, $this->_port, $errno, $errstr, $this->_timeout);
if ($fp)
{
fwrite($fp, $message);
fclose($fp);
$result = $message;
}
else
{
$result = "ERROR: $errno - $errstr";
}
return $result;
}
// (...)
?>
Example
<?php
require_once('syslog.php');
$syslog = new Syslog();
$syslog->Send('192.168.0.12', 'My first PHP syslog message');
?>
This is an ident request example. If your client is running identd your real username will be known by the server.
It is also usefull to identify people bypassing IP ACLs by using SOCKS proxy and dynamic IP forwarding. If the socks proxy server uses ident (most unices do) you will know his real username.
For more information see RFC1413
Timeout of 2 seconds in the example may not be enough.
<?php
error_reporting(E_ALL);
$remip = $HTTP_SERVER_VARS['REMOTE_ADDR'];
$remport = $HTTP_SERVER_VARS['REMOTE_PORT'];
ob_implicit_flush();
$fp = fsockopen($remip, 113, $errno, $errstr, 2);
if (!$fp) {
echo "$errstr ($errno)<br>\n";
exit;
}
else {
$out = "$remport, 80\r\n";
fwrite($fp, $out);
$answer=fgets($fp, 128);
}
fclose($fp);
$ansparts=explode(":",$answer);
$user=chop($ansparts[3]);
echo "You are $user@$remip:$remport";
?>
Additional ICQ status request over proxy
<?php
function icq_uin($uin)
{
if (! is_numeric($uin))
return false;
$proxy_name = 'proxy.mydomain.de';
$proxy_port = 8080;
$proxy_user = "";
$proxy_pass = "";
$proxy_cont = '';
$request_url = "http://status.icq.com/online.gif?icq=$uin";
$proxy_fp = fsockopen($proxy_name, $proxy_port);
if (!$proxy_fp)
return false;
fputs($proxy_fp, "GET $request_url HTTP/1.0\r\nHost: $proxy_name\r\n");
fputs($proxy_fp, "Proxy-Authorization: Basic ". base64_encode ("$proxy_user:$proxy_pass")."\r\n\r\n");
while(!feof($proxy_fp)){
$proxy_cont .= fread($proxy_fp,4096);
}
fclose($proxy_fp);
$proxy_cont = substr($proxy_cont, strpos($proxy_cont,"\r\n\r\n")+4);
if (strstr($proxy_cont, 'online1'))
return 'online';
if (strstr($proxy_cont, 'online0'))
return 'offline';
if (strstr($proxy_cont, 'online2'))
return 'disabled';
}
echo "User is ".icq_uin(123456789012345);
?>
Thanx
[EDIT BY danbrown AT php DOT net: Based on code provided in a note by (rafaelbc AT matrix DOT com DOT br) on 23-MAY-09, which has since been removed.]
I have found, when using fsockopen() and the POST method, that using HTTP/1.1 is VERY significantly slower than HTTP/1.0 (at least for the server I'm querying, an Orion-based server). Also, using cURL tended to be faster than fsockopen(), though only slightly. For example, here was a recent set of data (for the same exact request in each case):
cURL: 4.2sec
fsockopen() HTTP/1.0: 4.9sec
fsockopen() HTTP/1.1: 19.9sec (!)
I'm not sure why this was occurring. Perhaps it has something to do with the Orion server, which I have little experience with. However, it was not a fluke, and I double-checked the code to make sure there were no errors.
EDITORS NOTE: HTTP/1.1 uses persistent connection causing this delay. Use "Connection: close" header to disable it.
Something useful for ICQ:
<?php
$icquin = "197829943";
function GetICQ($uin) {
if (!is_numeric($uin)) return FALSE;
$fp = fsockopen('status.icq.com', 80, $errno, $errstr, 8);
if (!$fp) {
return "N/A";
}
else {
$request = "HEAD /online.gif?icq=$uin HTTP/1.0\r\n"
."Host: web.icq.com\r\n"
."Connection: close\r\n\r\n";
fputs($fp, $request);
do {
$response = fgets($fp, 1024);
}
while (!feof($fp) && !stristr($response, 'Location'));
fclose($fp);
if (strstr($response, 'online1')) return 'Online';
if (strstr($response, 'online0')) return 'Offline';
if (strstr($response, 'online2')) return 'N/A';
// N/A means, this User set the Option, his Online
// Status cannot be shown over the Internet
return FALSE;
}
}
echo GetICQ($icquin);
?>
<?php
/************************************************************
* Author: Richard Lajaunie
* Mail : richard.lajaunie@cote-azur.cci.fr
*
* subject : this script retreive all mac-addresses on all ports
* of a Cisco 3548 Switch by a telnet connection
*
* base on the script by: xbensemhoun at t-systems dot fr on the same page
**************************************************************/
if ( array_key_exists(1, $argv) ){
$cfgServer = $argv[1];
}else{
echo "ex: 'php test.php 10.0.0.0' \n";
exit;
}
$cfgPort = 23; //port, 22 if SSH
$cfgTimeOut = 10;
$usenet = fsockopen($cfgServer, $cfgPort, $errno, $errstr), $cfgTimeOut);
if(!$usenet){
echo "Connexion failed\n";
exit();
}else{
echo "Connected\n";
fputs ($usenet, "password\r\n");
fputs ($usenet, "en\r\n");
fputs ($usenet, "password\r\n");
fputs ($usenet, "sh mac-address-table\r\n");
fputs ($usenet, " "); // this space bar is this for long output
// this skip non essential text
$j = 0;
while ($j<16){
fgets($usenet, 128);
$j++;
}
stream_set_timeout($usenet, 2); // set the timeout for the fgets
$j = 0;
while (!feof($usenet)){
$ret = fgets($usenet, 128);
$ret = str_replace("\r", '', $ret);
$ret = str_replace("\n", "", $ret);
if (ereg("FastEthernet", $ret)){
echo "$ret \n";
}
if (ereg('--More--', $ret) ){
fputs ($usenet, " "); // for following page
}
$info = stream_get_meta_data($usenet);
if ($info['timed_out']) {
$j++;
}
if ($j >2){
fputs ($usenet, "lo");
break;
}
}
}
echo "End.\r\n";
?>
If you are using fsockopen to access webpage, but come across a redirect (Location: ) in the header and want to find and follow the redirect as in this snippet:
<?php
while (!feof($fp)) {
$line=fgets($fp, 1024);
if (stristr($line,"location:")!="") {
$redirect=preg_replace("/location:/i","",$line);
}
}
?>
Then don't forget to <?php $redirect = trim($redirect); ?> before trying to follow this new link as $redirect actually has a \r\n on the end of it and won't give you a valid path in the next iteration otherwise. A six hour bug.
Saul Dobney
Be careful if you open a lot of sockets in one php-file!
I had a script which checked a lot of domains and opened sockets to the whois-server. Even that I closed the connections after I checked a domain (fclose), the sockets seemed to stay open. After a while (about 1000 connections) the php-script couldn't open any more sockets.
It took a while to fix this problem. I did this by writing a script which started the check-scripts with wget (or lynx). I started 5 scripts parallel and just checked 20 domains. After that new 5 scripts where opened. That helped me not to open too many sockets in one php-file because when a php-script ends, all open sockets are closed.
Example:
start.php:
<?php
ignore_user_abort(true);
for($i=0; $i<100; $i++) {
echo $i."- "; flush();
$exec_string = 'lynx http://example.com/whois.php &';
$output = `$exec_string`;
sleep(10);
$exec_string = 'killall lynx';
$output = `$exec_string`;
}
?>
whois.php:
<?php
ignore_user_abort(true);
for($i=0; $i<50; $i++) {
fsockopen(whois.server...);
// here you process the whois-things
}
?>
Hope this'll help some people!
The following script will login to a POP3 account using the username, password and server name provided via a standard form; determine the amount of messages using a binary search; then purge all messages.
<?php
$server = $_POST["server"];
$user = $_POST["user"];
$pass = $_POST["pass"];
$count = 1;
$low = 0;
$mid = 0;
$high = 100000;
$connection = fsockopen($server, 110, $errno, $errstr, 30);
if(!$connection) {
print "Connect Failed: $errstr ($errno)";
} else {
$output = fgets($connection, 128);
fputs($connection, "user $user\n");
$output = fgets($connection, 128);
fputs($connection, "pass $pass\n");
$output = fgets($connection, 128);
while($low < $high - 1) {
$mid = floor(($low + $high) / 2);
fputs($connection, "list $mid\n");
$output = fgets($connection, 128);
$subout = substr($output, 0, 4);
if($subout == "+OK ") {
$low = $mid;
continue;
}
elseif($subout == "-ERR") {
$high = $mid;
continue;
} else {
break;
print "An error has occurred. Please try again.";
}
}
$limit = $mid - 1;
while($count <= $limit) {
fputs($connection, "dele $count\n");
fgets($connection, 128);
$count = $count + 1;
}
fputs($connection, "quit\n");
}
fclose($connection);
print "Successfully removed $limit messages.";
?>
Here's a function that I needed and couldn't use CURL... it helps you if you want to send the POST data (instead of GET) from one form to 2 or more other PHP scripts. Trust me... it's a life saver!!
<?php
function HTTP_Post($URL,$data, $referrer="") {
// parsing the given URL
$URL_Info=parse_url($URL);
// Building referrer
if($referrer=="") // if not given use this script as referrer
$referrer=$_SERVER["SCRIPT_URI"];
// making string from $data
foreach($data as $key=>$value)
$values[]="$key=".urlencode($value);
$data_string=implode("&",$values);
// Find out which port is needed - if not given use standard (=80)
if(!isset($URL_Info["port"]))
$URL_Info["port"]=80;
// building POST-request:
$request.="POST ".$URL_Info["path"]." HTTP/1.1\n";
$request.="Host: ".$URL_Info["host"]."\n";
$request.="Referer: $referer\n";
$request.="Content-type: application/x-www-form-urlencoded\n";
$request.="Content-length: ".strlen($data_string)."\n";
$request.="Connection: close\n";
$request.="\n";
$request.=$data_string."\n";
$fp = fsockopen($URL_Info["host"],$URL_Info["port"]);
fputs($fp, $request);
while(!feof($fp)) {
$result .= fgets($fp, 128);
}
fclose($fp);
return $result;
}
$output1=HTTP_Post("http://www.example.com/script1.php",$_POST);
$output2=HTTP_Post("http://www.example.net/script2.php",$_POST);
?>
You may be able to speed this function up by using an IP address instead of a domain. PHP uses getHostByAddr internally in this function anyway, so you can save a step in the function process.
The documentation example is of a GET request. I have found POST documentation to be lacking, and here's a function to easily simulate submitting form data:
<?php
# $host includes host and path and filename
# ex: "myserver.com/this/is/path/to/file.php"
# $query is the POST query data
# ex: "a=thisstring&number=46&string=thatstring
# $others is any extra headers you want to send
# ex: "Accept-Encoding: compress, gzip\r\n"
function post($host,$query,$others=''){
$path=explode('/',$host);
$host=$path[0];
unset($path[0]);
$path='/'.(implode('/',$path));
$post="POST $path HTTP/1.1\r\nHost: $host\r\nContent-type: application/x-www-form-urlencoded\r\n${others}User-Agent: Mozilla 4.0\r\nContent-length: ".strlen($query)."\r\nConnection: close\r\n\r\n$query";
$h=fsockopen($host,80);
fwrite($h,$post);
for($a=0,$r='';!$a;){
$b=fread($h,8192);
$r.=$b;
$a=(($b=='')?1:0);
}
fclose($h);
return $r;
}
?>
Here's a function to just fetch the contents behind an URL.
<?php
function fetchURL( $url ) {
$url_parsed = parse_url($url);
$host = $url_parsed["host"];
$port = $url_parsed["port"];
if ($port==0)
$port = 80;
$path = $url_parsed["path"];
if ($url_parsed["query"] != "")
$path .= "?".$url_parsed["query"];
$out = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";
$fp = fsockopen($host, $port, $errno, $errstr, 30);
fwrite($fp, $out);
$body = false;
while (!feof($fp)) {
$s = fgets($fp, 1024);
if ( $body )
$in .= $s;
if ( $s == "\r\n" )
$body = true;
}
fclose($fp);
return $in;
}
?>
Ping from PHP script. (Without system call)
This is of cause not a real ping since there is no support for ICMP. So it can't send a packet and get it back. But the important thing is to get a response from the server, even if it is only a ICMP error message. That way it verifies the servers existens and calculate the round trip time, which is the essential function of ping. It work well on all servers I have tried, with the echo service running.
<?php
$host='www.php.com';
$timeout=2;
//Open the socket
$handle=fsockopen('ddp://'.$host, 7, $errno, $errstr, $timeout);
if (!$handle)
echo "$errstr ($errno)<br>\r\n";
else {
//Set read timeout
stream_set_timeout($handle, $timeout);
for($i=0;$i<3;$i++){
//Time the responce
list($usec, $sec) = explode(" ", microtime(true));
$start=(float)$usec + (float)$sec;
//send somthing
$write=fwrite($handle,"echo this\n");
if(!$write){
echo "Error in writing to socked<br>\r\n";
break;
}
echo 'Send packet to '.$host;
//Try to read. the server will most likely respond with a "ICMP Destination Unreachable" and end the read. But that is a responce!
fread($handle,1024);
//Work out if we got a responce and time it
list($usec, $sec) = explode(" ", microtime(true));
$laptime=((float)$usec + (float)$sec)-$start;
if($laptime>$timeout)
echo " : No reply<br>\r\n";
else
echo " : Round trip = ".round($laptime,3)." s<br>\r\n";
}
fclose($handle);
}
?>
The following snippet allows you to retrieve the title of a page.
Great for rewriting auto-url detectors to display the actual title rather then http://...
<?php
echo get_url_title("http://www.php.net/cal.php?id=409");
function get_url_title($url, $timeout = 2)
{
$url = parse_url($url);
if(!in_array($url['scheme'],array('','http')))
return;
$fp = fsockopen ($url['host'], ($url['port'] > 0 ? $url['port'] : 80), $errno, $errstr, $timeout);
if (!$fp)
{
return;
// echo "$errstr ($errno)<br>\n";
}
else
{
fputs ($fp, "GET /".$url['path'].($url['query'] ? '?'.$url['query'] : '')." HTTP/1.0\r\nHost: ".$url['host']."\r\n\r\n");
$d = '';
while (!feof($fp))
{
$d .= fgets ($fp,2048);
if(preg_match('~(</head>|<body>|(<title>\s*(.*?)\s*</title>))~i', $d, $m))
break;
}
fclose ($fp);
return $m[3];
}
}
?>
Found this php class to use telnet from here:
http://cvs.adfinis.ch/cvs.php/phpStreamcast/telnet.class.php
There's no docs and a lot of it's in french though so maybe it will help
someone to have my working code. This code is used to telnet into a
pix and execute the "shun" command.
<?php
//-------telnet.class.php usage example---------
$telnet = new telnet;
// Next line is for logging.
//By default you need to create a folder called /log and give it the
//rights your webserver is running.
$telnet->setLog(1,"mylog");
$telnet->set_host("myhost.myplace.com");
//You need to set the prompt to what you know its going to be,
//then call wait_prompt...which waits for what you just set
$telnet->set_prompt("Password: ");
$telnet->connect();
$telnet->wait_prompt();
$telnet->write("mypassword");
//Have to change the prompt...in my example this is the
//prompt that a pix will change to after loggin in.
$telnet->set_prompt("pix> ");
$telnet->wait_prompt();
$telnet->write("en");
$telnet->set_prompt("Password: ");
$telnet->wait_prompt();
$telnet->write("enable_password");
//When you go into enable mode in a pix the prompt changes
$telnet->set_prompt("pix# ");
$telnet->wait_prompt();
$telnet->write("shun " . $shun_address);
$telnet->wait_prompt();
$telnet->write("clear xlate");
$telnet->wait_prompt();
$telnet->write("write mem");
$telnet->wait_prompt();
$telnet->write("exit");
$telnet->disconnect();
?>
Modified code for telnet to work with not-so-fast connections.
The old version garbles the output and/or cuts the output before
it is finished when output is above about 100 lines.
<?php
# This is the difficult part, the Telnet header
$header1=chr(0xFF).chr(0xFB).chr(0x1F).chr(0xFF).chr(0xFB).
chr(0x20).chr(0xFF).chr(0xFB).chr(0x18).chr(0xFF).chr(0xFB).
chr(0x27).chr(0xFF).chr(0xFD).chr(0x01).chr(0xFF).chr(0xFB).
chr(0x03).chr(0xFF).chr(0xFD).chr(0x03).chr(0xFF).chr(0xFC).
chr(0x23).chr(0xFF).chr(0xFC).chr(0x24).chr(0xFF).chr(0xFA).
chr(0x1F).chr(0x00).chr(0x50).chr(0x00).chr(0x18).chr(0xFF).
chr(0xF0).chr(0xFF).chr(0xFA).chr(0x20).chr(0x00).chr(0x33).
chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0x2C).chr(0x33).
chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0xFF).chr(0xF0).
chr(0xFF).chr(0xFA).chr(0x27).chr(0x00).chr(0xFF).chr(0xF0).
chr(0xFF).chr(0xFA).chr(0x18).chr(0x00).chr(0x58).chr(0x54).
chr(0x45).chr(0x52).chr(0x4D).chr(0xFF).chr(0xF0);
$header2=chr(0xFF).chr(0xFC).chr(0x01).chr(0xFF).chr(0xFC).
chr(0x22).chr(0xFF).chr(0xFE).chr(0x05).chr(0xFF).chr(0xFC).chr(0x21);
# connecting
$fp=fsockopen("127.0.0.1",23);
# sending the Telnet header
fputs($fp,$header1);
usleep(125000);
fputs($fp,$header2);
usleep(125000);
# login
fputs($fp,"user\r");
usleep(125000);
fputs($fp,"users.pass\r");
usleep(125000);
# root looks nice
fputs($fp,"su\r");
usleep(125000); # takes some time, we had to wait
fputs($fp,"root.pass\r");
# some tests
fputs($fp,"ifconfig\r");
fputs($fp,"echo year telnet php connect works|wall\r");
# we had to wait
usleep(125000);
# show the output
do
{
$output.=fread($fp, 80); // read line by line, or at least small chunks
$stat=socket_get_status($fp);
}
while($stat["unread_bytes"]);
$output = str_replace("\n", "<br>", $output);
echo $output;
fclose($fp);
?>
Set up SSL connection to server that requires client certificate:
Convert client certificate from *.pfx (pkcs12) into*.pem with openssl (if needed):
> openssl pkcs12 -in keys.pfx -out keys.pem
PHP:
<?php
$context = stream_context_create();
$result = stream_context_set_option($context, 'ssl', 'local_cert', '/path/to/keys.pem');
$result = stream_context_set_option($context, 'ssl', 'passphrase', 'pass_to_access_keys');
$socket = fsockopen('ssl://'.$host, 443, $errno, $errstr, 30, $context);
?>
Here is a function for testing a website/URI for availability:
<?php
/*
* @return boolean
* @param string $link
* @desc Überprüft die angegeben URL auf Erreichbarkeit (HTTP-Code: 200)
*/
function url_validate( $link )
{
$url_parts = @parse_url( $link );
if ( empty( $url_parts["host"] ) ) return( false );
if ( !empty( $url_parts["path"] ) )
{
$documentpath = $url_parts["path"];
}
else
{
$documentpath = "/";
}
if ( !empty( $url_parts["query"] ) )
{
$documentpath .= "?" . $url_parts["query"];
}
$host = $url_parts["host"];
$port = $url_parts["port"];
// Now (HTTP-)GET $documentpath at $host";
if (empty( $port ) ) $port = "80";
$socket = @fsockopen( $host, $port, $errno, $errstr, 30 );
if (!$socket)
{
return(false);
}
else
{
fwrite ($socket, "HEAD ".$documentpath." HTTP/1.0\r\nHost: $host\r\n\r\n");
$http_response = fgets( $socket, 22 );
if ( ereg("200 OK", $http_response, $regs ) )
{
return(true);
fclose( $socket );
} else
{
// echo "HTTP-Response: $http_response<br>";
return(false);
}
}
}
?>
<?php
// This is a modification to the script I submitted below.
// This script is an example of posting multiple files using
// fsockopen.
// The tricky part is making sure the HTTP headers and file boundaries are acceptable to the target webserver.
// This script is for example purposes only and could/should be improved upon.
$host='targethost';
$port=80;
$path='/test/socket/file_upload/receive_files.php';
// the file you want to upload
$file_array[0] = "dingoboy.gif"; // the file
$file_array[1] = "dingoboy2.gif"; // the file
$file_array[2] = "dingoboy3.gif"; // the file
$content_type = "image/gif"; // the file mime type
//$content_type = "text/plain";
//echo "file_array[0]:$file_array[0]<br><br>";
srand((double)microtime()*1000000);
$boundary = "---------------------------".substr(md5(rand(0,32000)),0,10);
$data = "--$boundary";
for($i=0;$i<count($file_array);$i++){
$content_file = join("", file($file_array[$i]));
$data.="
Content-Disposition: form-data; name=\"file".($i+1)."\"; filename=\"$file_array[$i]\"
Content-Type: $content_type
$content_file
--$boundary";
}
$data.="--\r\n\r\n";
$msg =
"POST $path HTTP/1.0
Content-Type: multipart/form-data; boundary=$boundary
Content-Length: ".strlen($data)."\r\n\r\n";
$result="";
// open the connection
$f = fsockopen($host, $port);
fputs($f,$msg.$data);
// get the response
while (!feof($f)) $result .= fread($f,32000);
fclose($f);
?>
Just a note to everyone who is using fsockopen and fread / fgets for a HTTP connection.
Unless you specify "Connection: Close" in your headers you will need to wait for the socket to time out before feof($streamPointer) to return true.
This has wasted 2 days of my time, grr!
-Rob
This is a very fast program for test a form or link (many times).
<?php
$repeat = 100; // How many times repeat the test
$timeout = 100; // Max time for stablish the conection
$size = 16; // Bytes will be read (and display). 0 for read all
$server = '64.246.30.37'; // IP address
$host = 'www.foo.com'; // Domain name
$target = '/poll/answer.asp'; // Specific program
$referer = 'http://www.test.com/'; // Referer
$port = 80;
// Setup an array of fields to get with then create the get string
$gets = array ( 'get_field_1' => 'somevalue',
'get_field_2' => 'somevalue' );
// Setup an array of fields to post with then create the post string
$posts = array ( 'post_field_1' => 'somevalue',
'post_field_2' => 'somevalue' );
// That's all. Now the program proccess $repeat times
$method = "GET";
if ( is_array( $gets ) ) {
$getValues = '?';
foreach( $gets AS $name => $value ){
$getValues .= urlencode( $name ) . "=" . urlencode( $value ) . '&';
}
$getValues = substr( $getValues, 0, -1 );
} else {
$getValues = '';
}
if ( is_array( $posts ) ) {
foreach( $posts AS $name => $value ){
$postValues .= urlencode( $name ) . "=" . urlencode( $value ) . '&';
}
$postValues = substr( $postValues, 0, -1 );
$method = "POST";
} else {
$postValues = '';
}
$request = "$method $target$getValues HTTP/1.1\r\n";
$request .= "Host: $host\r\n";
$request .= 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) ';
$request .= "Gecko/20021204\r\n";
$request .= 'Accept: text/xml,application/xml,application/xhtml+xml,';
$request .= 'text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,';
$request .= "image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1\r\n";
$request .= "Accept-Language: en-us, en;q=0.50\r\n";
$request .= "Accept-Encoding: gzip, deflate, compress;q=0.9\r\n";
$request .= "Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66\r\n";
$request .= "Keep-Alive: 300\r\n";
$request .= "Connection: keep-alive\r\n";
$request .= "Referer: $referer\r\n";
$request .= "Cache-Control: max-age=0\r\n";
if ( $method == "POST" ) {
$lenght = strlen( $postValues );
$request .= "Content-Type: application/x-www-form-urlencoded\r\n";
$request .= "Content-Length: $lenght\r\n";
$request .= "\r\n";
$request .= $postValues;
}
for ( $i = 0; $i < $repeat; $i++ ) {
$socket = fsockopen( $server, $port, $errno, $errstr, $timeout );
fputs( $socket, $request );
if ( $size > 0 ) {
$ret = fgets( $socket, $size );
} else {
$ret = '';
while ( !feof( $socket ) ) {
$ret .= fgets( $socket, 4096 );
}
}
fclose( $socket );
echo "<hr> $i -- $content $ret";
}
?>
Alejandro Salamanca
RedCetus.com
Try this.
Use AUTH when necessary.
Read RFC 821 when having problems.
<?php
$handle = smtp_connect($smtp_server, 25, 30, 1, 1, 1);
echo smtp_command($handle, "EHLO $domain\r\n", 1, 1);
echo smtp_command($handle, "MAIL FROM:<$from_mail>\r\n", 1, 1);
echo smtp_command($handle, "RCPT TO:<$to_mail>\r\n", 1, 1);
echo smtp_command($handle, "DATA\r\n", 1, 1);
echo smtp_command($handle, "$message\r\n.\r\n", 1, 1);
// don't do it like this - it will hang up
// echo smtp_command($handle, "$message", 1, 1);
// echo smtp_command($handle, "\r\n.\r\n", 1, 1);
echo smtp_command($handle, "QUIT\r\n", 1, 1);
smtp_close($handle);
function smtp_connect($host, $port, $timeout=30, $echo_command=False, $echo_response=False, $nl2br=False)
{
$errno = 0;
$errstr = 0;
if($echo_command)
{
if($nl2br) { echo nl2br("CONNECTING TO $host\r\n"); }
else { echo "CONNECTING TO $host\r\n"; }
}
$handle = fsockopen($host, $port, $errno, $errstr, $timeout);
if(!$handle)
{
if($echo_command)
{
if($nl2br) { echo nl2br("CONNECTION FAILED\r\n"); }
else { echo "CONNECTION FAILED\r\n"; }
}
return False;
}
if($echo_command)
{
if($nl2br) { echo nl2br("SUCCESS\r\n"); }
else { echo "SUCCESS\r\n"; }
}
$response = fgets($handle,1);
$bytes_left = socket_get_status($handle);
if ($bytes_left > 0) { $response .= fread($handle, $bytes_left["unread_bytes"]); }
if($echo_response)
{
if($nl2br) { echo nl2br($response); }
else { echo $response; }
}
return $handle;
}
function smtp_command($handle, $command, $echo_command=False, $nl2br=False)
{
if($echo_command)
{
if($nl2br) { echo nl2br($command); }
else { echo $command; }
}
fputs($handle, $command);
$response = fgets($handle,1);
$bytes_left = socket_get_status($handle);
if ($bytes_left > 0) { $response .= fread($handle, $bytes_left["unread_bytes"]); }
if($nl2br) { return nl2br($response); }
else { return $response; }
}
function smtp_close($handle)
{
fclose($handle);
}
?>
Improved HTTP/1.1 chunked transfer-encoding example.
The sample code given below by Jack does not function correctly when run against a recent version of Apache (I'm assuming that this did once work, but from the HTTP/1.1 spec I can only assume if it did work it was based mostly on luck).
<?php
$header = "";
$response = "";
// connect
if (!($request=fsockopen('whatever.com',80,$errno,$errstr))) exit($errstr);
else {
socket_set_timeout($request,10);
// send request
fwrite($request,$post);
// get header
do $header.=fread($request,1); while (!preg_match('/\\r\\n\\r\\n$/',$header));
// check for chunked encoding
if (preg_match('/Transfer\\-Encoding:\\s+chunked\\r\\n/',$header))
do {
$byte = "";
$chunk_size="";
do {
$chunk_size.=$byte;
$byte=fread($request,1);
} while ($byte!="\\r"); // till we match the CR
fread($request, 1); // also drop off the LF
$chunk_size=hexdec($chunk_size); // convert to real number
$response.=fread($request,$chunk_size);
fread($request,2); // ditch the CRLF that trails the chunk
} while ($chunk_size); // till we reach the 0 length chunk (end marker)
else {
// check for specified content length
if (preg_match('/Content\\-Length:\\s+([0-9]*)\\r\\n/',$header,$matches)) {
$response=fread($request,$matches[1]);
} else {
// not a nice way to do it (may also result in extra CRLF which trails the real content???)
while (!feof($request)) $response .= fread($request, 4096);
}
}
// close connection
fclose($request);
}
// do something useful with the response
print($header);
print($response);
?>
Richard.
just a quick note for users attempting https and thinking they must resort to curl or alternate methods -
you can use fsockopen, just read the docs closely. basically they are saying to use 'ssl://' for a HTTPS (SSL) web request.
so this would work for authorize.net, and others; even for that paypal IPN - however I think it would be best to leave the site and deal with paypal's form:
<?php
$host = "somehost.somedomain.com";
$port = 443;
$path = "/the/url/path/file.php"; //or .dll, etc. for authnet, etc.
//you will need to setup an array of fields to post with
//then create the post string
$formdata = array ( "x_field" => "somevalue");
//build the post string
foreach($formdata AS $key => $val){
$poststring .= urlencode($key) . "=" . urlencode($val) . "&";
}
// strip off trailing ampersand
$poststring = substr($poststring, 0, -1);
$fp = fsockopen("ssl://".$host, $port, $errno, $errstr, $timeout = 30);
if(!$fp){
//error tell us
echo "$errstr ($errno)\n";
}else{
//send the server request
fputs($fp, "POST $path HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ".strlen($poststring)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $poststring . "\r\n\r\n");
//loop through the response from the server
while(!feof($fp)) {
echo fgets($fp, 4096);
}
//close fp - we are done with it
fclose($fp);
}
?>
If you want to connect via Telnet, it could be useful to set also the Terminal Type (some OS requires it)
<?php
$IAC = chr(255); /* interpret as command: */
$SB = chr(250); /* interpret as subnegotiation */
$SE = chr(240); /* end sub negotiation */
$TELOPT_TTYPE = chr(24); /* terminal type */
$TELQUAL_IS = chr(0); /* Option is... */
//sending Terminal Type
fwrite($sock,$IAC.$SB.$TELOPT_TTYPE.$TELQUAL_IS.'vt100'.$IAC.$SE);
?>
ciao
Sergio Paternoster
thought you guys may appreciate this function, allows you to pass an array of urls to download and does so simultaneously using non-blocking sockets, then returns the data in an array.
<?php
// function connects to an array of URLS at the same time
// and returns an array of results.
function multiHTTP ($urlArr) {
$sockets = Array(); // socket array!
$urlInfo = Array(); // info arr
$retDone = Array();
$retData = Array();
$errno = Array();
$errstr = Array();
for ($x=0;$x<count($urlArr);$x++) {
$urlInfo[$x] = parse_url($urlArr[$x]);
$urlInfo[$x][port] = ($urlInfo[$x][port]) ? $urlInfo[$x][port] : 80;
$urlInfo[$x][path] = ($urlInfo[$x][path]) ? $urlInfo[$x][path] : "/";
$sockets[$x] = fsockopen($urlInfo[$x][host], $urlInfo[$x][port],
$errno[$x], $errstr[$x], 30);
socket_set_blocking($sockets[$x],FALSE);
$query = ($urlInfo[$x][query]) ? "?" . $urlInfo[$x][query] : "";
fputs($sockets[$x],"GET " . $urlInfo[$x][path] . "$query HTTP/1.0\r\nHost: " .
$urlInfo[$x][host] . "\r\n\r\n");
}
// ok read the data from each one
$done = false;
while (!$done) {
for ($x=0; $x < count($urlArr);$x++) {
if (!feof($sockets[$x])) {
if ($retData[$x]) {
$retData[$x] .= fgets($sockets[$x],128);
} else {
$retData[$x] = fgets($sockets[$x],128);
}
} else {
$retDone[$x] = 1;
}
}
$done = (array_sum($retDone) == count($urlArr));
}
return $retData;
}
?>
To make a telnet connection with a Cisco router:
<?php
$cfgServer = "nnn.nnn.nnn.nnn"; //IP of your router
$cfgPort = 23; //port, 22 if SSH
$cfgTimeOut = 10;
$usenet = fsockopen($cfgServer, $cfgPort, $errno, $errstr, $cfgTimeOut);
if(!$usenet)
{
echo "Connexion failed\n";
exit();
}
else
{
echo "Connected\n<BR>";
fputs ($usenet, "toto\r\n");
fputs ($usenet, "en\r\n");
fputs ($usenet, "tutu\r\n");
fputs ($usenet, "exit\r\n");
while (!feof($usenet))
{
echo ". ".fgets($usenet, 128)."<BR>\n";
}
}
?>
Then you will have:
Connected
. ��������
.
. User Access Verification
.
. Password:
. testXB>en
. Password:
. testXB#exit
.
Here's a quick function to establish a connection to a web server that will time out if the connection is lost after a user definable amount of time or if the server can't be reached.
Also supports Basic authentication if a username/password is specified. Any improvements or criticisms, please email me! :-)
Returns either a resource ID, an error code or 0 if the server can't be reached at all. Returns -1 in the event that something really wierd happens like a non-standard http response or something. Hope it helps someone.
Cheers,
Ben Blazely
<?php
function connectToURL($addr, $port, $path, $user="", $pass="", $timeout="30")
{
$urlHandle = fsockopen($addr, $port, $errno, $errstr, $timeout);
if ($urlHandle)
{
socket_set_timeout($urlHandle, $timeout);
if ($path)
{
$urlString = "GET $path HTTP/1.0\r\nHost: $addr\r\nConnection: Keep-Alive\r\nUser-Agent: MyURLGrabber\r\n";
if ($user)
$urlString .= "Authorization: Basic ".base64_encode("$user:$pass")."\r\n";
$urlString .= "\r\n";
fputs($urlHandle, $urlString);
$response = fgets($urlHandle);
if (substr_count($response, "200 OK") > 0) // Check the status of the link
{
$endHeader = false; // Strip initial header information
while ( !$endHeader)
{
if (fgets($urlHandle) == "\r\n")
$endHeader = true;
}
return $urlHandle; // All OK, return the file handle
}
else if (strlen($response) < 15) // Cope with wierd non standard responses
{
fclose($urlHandle);
return -1;
}
else // Cope with a standard error response
{
fclose($urlHandle);
return substr($response,9,3);
}
}
return $urlHandle;
}
else
{
return 0;
}
}
}
?>
You can know from which country are your visitors sending a query to ip-to-country online tool using code below:
****************************************
<?php
$ip = $REMOTE_ADDR;
$doc = "/get-country/?ip=" . $ip . "&user=guest&pass=guest";
$url = "ip-to-country.com";
$fp = fsockopen ($url, 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br/>\n";
} else {
fputs ($fp, "GET $doc HTTP/1.0\r\nHost: " . $url. "\r\n\r\n");
while (!feof($fp)) {
$httpresult = fgets ($fp,1024);
}
fclose ($fp);
}
if (isset($httpresult))
{
echo "Ud. est� accediendo desde: <b>$httpresult</b>";
}
?>
****************************************
NOTE: I had to modify the code provided by ip-to-country in its own Tools section because is buggy.
Here is how to connect to the web from behind a proxy server:
<?php
/*************start code**************/
/*your proxy server address*/
$proxy = "192.168.10.1";
/*your proxy server port*/
$port = 8080;
/*the url you want to connect to*/
$url = "http://www.php.net/";
$fp = fsockopen($proxy, $port);
fputs($fp, "GET $url HTTP/1.0\r\nHost: $proxy\r\n\r\n");
while(!feof($fp)){
$line = fgets($fp, 4000);
print($line);
}
fclose($fp);
/**************end code**************/
?>
The timeout parameter was not supported under windows until PHP 4.3.0, previously it was fixed at 30sec.
Here is some code to help out abit more with the EOF problem.
I had a problem where I needed to strip out so many lines of server input to get back right data i wanted.
<?php
$port=4000;
$host="localhost";
$message="test";
$status=senddata($host,$port,$message);
print "$status";
function senddata($host,$port,$message) {
#takes in account servers that do not return EOF character
#send data to server and get back input
#function globals
$linenumber="2"; #amount of lines to get rid of before we give input
$lineamount="1"; #amount of lines to read after we give input
$fp = fsockopen("$host", $port, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)";
}
else {
for ($i = 1; $i < $linenumber+1; $i++) {
fread ($fp,1);
$bytes_left = socket_get_status($fp);
if ($bytes_left > 0) { fread($fp, $bytes_left[unread_bytes]); }
}
fputs($fp, "$message\r\n");
for ($i = 1; $i < $lineamount+1; $i++) {
$status.=fread($fp,1);
$bytes_left = socket_get_status($fp);
if ($bytes_left > 0) { $status.=fread($fp, $bytes_left[unread_bytes]); }
}
fclose ($fp);
}
return $status;
}
?>
I was tearing my hair out for a week trying to figure out how to do this.
If you use fsockopen with a service that doesn't have an EOF, or you try to read beyond EOF or line break, PHP can hang completely.
In my case, I was trying to write a class that talks to Kali servers (www.kali.net) to get a list of people on the chat server. To keep PHP from hanging due to the above, I discovered this:
<?php
class kali_utils {
function games_list($kali_server_ip, $kali_server_port) {
$result = array();
$fp = fsockopen($kali_server_ip, $kali_server_port, $errno, $error, 30);
if (!$fp) {
$result["errno"] = $errno;
$result["error"] = $error;
}
else {
fputs($fp, "KALIQ");
$header = fread($fp, 5);
$bytes_left = socket_get_status($fp);
if ($bytes_left > 0) {
$result["results"] = fread($fp, $bytes_left["unread_bytes"]);
}
else {
$result["results"] = "";
}
fclose($fp);
}
return $result;
}
}
?>
When I send the request packet, I get a response packet of length 5. Then I call socket_get_status() and use the unread_bytes key from it to know how far to fread from the socket. Works very good.
I've only used this on PHP 4.2.1 so far.
Here's how to send an email using SMTP. This includes rudimentary checking on server responses during the process of sending an email. Could be improved by more comprehensive processing of the result codes...or going on to the next mail exchanger when you fail after connecting to the first.
<?php
function another_mail($to,$subject,$headers,$message)
{
// Could get this from the php ini?
$from="me@example.com";
list($me,$mydomain) = split("@",$from);
// Now look up the mail exchangers for the recipient
list($user,$domain) = split("@",$to,2);
if(getmxrr($domain,$mx,$weight) == 0) return FALSE;
// Try them in order of lowest weight first
array_multisort($mx,$weight);
$success=0;
foreach($mx as $host) {
// Open an SMTP connection
$connection = fsockopen ($host, 25, $errno, $errstr, 1);
if (!$connection)
continue;
$res=fgets($connection,256);
if(substr($res,0,3) != "220") break;
// Introduce ourselves
fputs($connection, "HELO $mydomain\n");
$res=fgets($connection,256);
if(substr($res,0,3) != "250") break;
// Envelope from
fputs($connection, "MAIL FROM: $from\n");
$res=fgets($connection,256);
if(substr($res,0,3) != "250") break;
// Envelope to
fputs($connection, "RCPT TO: $to\n");
$res=fgets($connection,256);
if(substr($res,0,3) != "250") break;
// The message
fputs($connection, "DATA\n");
$res=fgets($connection,256);
if(substr($res,0,3) != "354") break;
// Send To:, From:, Subject:, other headers, blank line, message, and finish
// with a period on its own line.
fputs($connection, "To: $to\nFrom: $from\nSubject: $subject\n$headers\n\n$message\n.\n");
$res=fgets($connection,256);
if(substr($res,0,3) != "250") break;
// Say bye bye
fputs($connection,"QUIT\n");
$res=fgets($connection,256);
if(substr($res,0,3) != "221") break;
// It worked! So break out of the loop which tries all the mail exchangers.
$success=1;
break;
}
// Debug for if we fall over - uncomment as desired
// print $success?"Mail sent":"Failure: $res\n";
if($connection) {
if($success==0) fputs($connection, "QUIT\n");
fclose ($connection);
}
return $success?TRUE:FALSE;
}
another_mail("recipient@example.com","My Subject","X-mailer: PHP Script\nX-another-header: Whatever","Test email body.\n\nNote if you actually put a period on a line\nby itself, the function will terminate prematurely.\n\nYou will get a partial email sent though.\n");
?>