2008-06-08
This is sample code and a proof of concept, if you are interested in a well crafted webserver written with PHP, I suggest Nanoweb.

Why the hell would one want to write a webserver in PHP?

Well, for the same reason one would write a proof of concept webserver in any other programming language; it needed to be done. Actually, this started out as a test of using sockets for inter-application communication on a network and was written to run using PHP4 on a Macintosh. Since I could either delete the file and be done with it, or share the file and maybe help someone, I'm opting for the share and help.

Here you go.....

#!/usr/bin/env php -q
<?php

//function get_include_contents
// input : path to a php file
// output : the parsed text of the php file
function get_include_contents($filename)
{
echo "parsing: $filenamen";
if (is_file($filename))
{
ob_start();
include $filename;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
return false;
}

function get_file_extension($file)
{
preg_match("/.([a-z0-9.]*)/i",$file,$matches);
$file_extension=$matches[1];
return $file_extension;
}
function get_path_to_file($request)
{
global $pwd;
global $default_http_dir;
return $pwd."/".$default_http_dir.$request;
}
function get_referer($text)
{
preg_match("/10000(/S*)/i",$text,$matches);
$referer = $matches[1];
return $referer;
}


//path to php
$php_path="/usr/local/php5/bin/php";
echo"starting server...n";
//we want to run indefinitely
set_time_limit(0);
//we need to output info to the terminal as soon as we can
ob_implicit_flush();
//define a bunch of variables
//what address are we binding to?
$bind_address='127.0.0.1';
//access port
$port=10000;
//what is the default file?
$default_array= array("index.php","index.htm","index.html");
//set the default dir for files
$default_http_dir = "webroot";
//where are we?
$pwd=trim(`pwd`);

//start connecting sockets
$socket_resource=socket_create(AF_INET,SOCK_STREAM,0) or die("socket_create()failed.");
socket_bind($socket_resource,$bind_address,$port) or die("socket_bind()failed");
socket_listen($socket_resource,5) or die("socket_listen()failed");
echo "Server is up and running ....n";
do //this is the MAIN loop
{
if(($accept_socket_resource=socket_accept($socket_resource))<0)
{
echo "socket_accept() failedn";
break;
}
if(FALSE===($buffer_text=socket_read($accept_socket_resource,2048)))
{
echo "socket_read() failedn";
break;
}
preg_match("/ .+ /i",$buffer_text,$matches);
$full_request = trim($matches[0]);
$request_and_arguments = explode("?",$full_request);
$request = urldecode( $request_and_arguments[0] );
$arguments=$request_and_arguments[1];
// if we have some get vars, lets make a $_GET[] array set
if($arguments)
{
$args_n_vars = explode("&",$arguments);
foreach($args_n_vars as $arg_n_var)
{
list($var,$value) = explode("=",$arg_n_var);
$_GET[$var]=urldecode($value);

}

}

if(substr($request,strlen($request)-1,1)=="/")
{
//find the first default file
foreach($default_array as $default_file)
{
$tfile = stripslashes($pwd)."/".$default_http_dir."/".$default_file;
if( file_exists($tfile) )
{
$request = "/$default_file";
break;
}
}
}

$file_extension = get_file_extension($request);
$path_to_file = get_path_to_file($request);
//what mime type should be returned?
switch($file_extension)
{
case "png":
$mime="image/png";
break;
case "gif":
$mime="image/gif";
break;
case "jpg":
$mime="image/jpeg";
break;
case "zip":
$mime="aplication/zip";
break;
case "exe":
$mime="aplication/exe";
break;
case "bmp":
$mime="image/bmp";
break;
case "mov":
$mime="video/quicktime";
break;
case "mp3":
$mime="video/mpeg";
break;
case "mpeg":
$mime="video/mpeg";
break;
case "txt":
$mime="text/plain";
break;
default:
$mime="text/html";
break;
}
if(file_exists($path_to_file))
{
//we have a file to return to the user
$return_file = true;
//is this a php file?
if($file_extension == "php")
{
//we had better parse the php
//where are we now?
$start_dir= getcwd();
//cd to the php files dir
$php_file_dir = dirname( $path_to_file);
$php_file = basename( $path_to_file );
chdir($php_file_dir);
//run the included PHP file
$file_contents = get_include_contents("$php_file");
$file_length=strlen($file_contents);
//return to the start dir
chdir($start_dir);

}else{
echo "serving: $path_to_file";
$file_contents = file_get_contents($path_to_file);
$file_length=filesize($path_to_file);
}
if($return_file)
{
$today=date("m.d.y");
$output="HTTP/1.0 200 OKrnServer: PHP Proof of ConceptrnDate:$todayrnConnection:closernContent-Length:$file_lengthrnContent-Type:$mimernrn";
socket_send($accept_socket_resource,$output,strlen($output),0);
$start_chunk=0;
while($start_chunk<=$file_length)
{
$text_chunk=substr($file_contents,$start_chunk,2048);
socket_write($accept_socket_resource,$text_chunk,strlen($text_chunk));
$start_chunk+=2048;
}
}
}else{
$output="HTTP/1.0 404 OBJECT NOT FOUNDrnServer: PHP ServerrnConnection: closernrn";
socket_write($accept_socket_resource,$output,strlen($output));
}
socket_close($accept_socket_resource);
}while(true);
socket_close($socket_resource);
?>




Geez, I really don't like looking at my old code since it always makes me think about how I would re-write differently if I were to write it today, and this code is about 3-4 years old.
Comments
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
3 plus 5
Answer:
required
  • Tags:
  • PHP
subscribe
 
2019
2016
2015
2014
2013
2012
2011
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008