To register for an Internet.com membership to receive newsletters and white papers, use the Register button ABOVE.
To participate in the message forums BELOW, click here
PHPBuilder.com  
 

 

Go Back   PHPBuilder.com > PHP Help > Code Critique

Code Critique Having someone critique your code is always a great way to hone the skills. Stop in and post your code to see what your peers may have done differently.

Reply
 
Thread Tools Rate Thread Display Modes
Old 02-06-2004, 05:39 AM   #1
bubblenut
Copyleft Commie
 
bubblenut's Avatar
 
Join Date: Oct 2003
Location: London
Posts: 2,370
Webserver

Yea, I know, not really practilcle but what the hell. I have a couple of changes which should be made to it. Rather than storing the number of threads in a file (lots of head movements with all that reading an writing) could use environment variables like so (exec("THREADCOUNT=".$threadcount), also have another variable, set to true just after the line $sock->socket=socket_accept($sock), to tell the webserver class whether or not to start another thread as at the moment this will open up the full $MAX_THREADS regardless of whether anyone is waiting to be served.
There was another thing I thought of last night but I can't remember it now. I'm sure there are a lot of holes to be found though.
here goes Webserver.php
PHP Code:
<?php
class Webserver {
    var
$MAX_THREADS=10;
    var
$THREAD_C_FILE='./threadcount';
    var
$ERRFILE='./webserver_err';

    var
$port=80;

    function
Webserver($port=false)
    {
        
//check provided port number is a num
        
if($port && $port%10==0) {
            
$this->port=$port;
        }
        
//create a listener socket on port
        
$listen=socket_create_listen($port);
        
//initialize the thread count file
        
$fh=fopen($this->THREAD_C_FILE,'w');
        
fwrite($fh,'0');
        
fclose($fh);
        
//start the webserver
        
while(true) {
            
//check the number of open threads
            
$num=$this->getOpenThreads();
            
//if the number of open threads is low enough start another
            
if($num<$this->MAX_THREADS) {
                
//forkit!!
                
exec('/usr/bin/php -q ./Listener.php '.$this->port.' '.$this->THREAD_C_FILE.' &');
                
//keep tryin untill any lock is lifted
                
while(!$fh=fopen($this->THREAD_C_FILE,'w')) {}
                
fwrite($fh,++$num);
                
fclose($fh);
            }
        }
    }
    
    function
getOpenThreads()
    {
        
//keep trying untill any lock is lifted
        
while(!$fh=fopen($this->THREAD_C_FILE,'r')) {}
        
$num=fread($fh);
        
fclose($fh);
        if(
is_numeric($num)) {
            return
$num;
        } else {
            
//FAIL
            
$this->ERR('BAD THREAD COUNT: '.$num."\n");
        }
    }

    function
ERR($string)
    {
        
$fh=fopen($this->ERRFILE,'a+');
        
fwrite($fh,$string."\n");
        
fclose($fh);
        exit(
0);
    }
}
$webserver=new Webserver();
?>
And That calls Listener.php
PHP Code:
<?php

class Listener
{
    var
$THREAD_C_FILE;
    var
$ERRFILE='./listen_err';
    
    var
$port;
    var
$socket;
    var
$request;
    var
$error;
    

    function
Listener($port, $thread_c_file)
    {
        
$this->setPort($port);
        
$this->setThreadCFile($thread_c_file);
        
$this->createListener();
        if(
$this->getRequest()) {
            
$this->sendFile();
        } else {
            
$this->sendError();
        }
        
$this->decrementCount();
        
$this->close();
    }
    
    function
close()
    {
        exit(
0);
    }
        
    function
decrementCount()
    {
        while(!
$fh=fopen($this->THREAD_C_FILE,'w+')) {}
        
$num=fread($fh,filesize($this->THREAD_C_FILE));
        if(!
is_numeric($num)) {
            
$this->ERR("THREAD COUNT FILE FKUP:\n"); //not much else to say really :/
        
}
        
fwrite($fh,--$num);
        
fclose($fh);
    }
        
    function
sendFile()
    {
        
$fh=fopen($this->request,'r');
        while(
$data=fread($fh,1024)) {
            
socket_write($this->socket,$data);
        }
    }
    
    function
sendError()
    {
        
socket_write($this->socket,$this->error);
    }

    function
getRequest()
    {
        while(
$data=socket_read($this->socket)) {
            
$request.=$data;
        }
        if(
preg_match('/^GET \/?(\S*).*/',$request,$matches)) {
            
$request=$matches[1];
            if(
substr($request,-1)=='/' || $request=='')
                
$request.='index.php';
            if(
is_file($request)) {
                
$this->request=$request;
                return
true;
            } else {
                
$this->error='404 Object Not Found\n';
                return
false;
            }
        } else {
            
$this->error='400 Bad Request\n';
            return
false;
        }
    }        
            
    function
createListener()
    {
        if(
$sock=socket_create_listen($this->port)) {
            
$this->socket=socket_accept($sock);
            return
true;
        } else {
            
$this->ERR("CREATE LISTENER !1: ".socket_strerror(socket_last_error()));
        }
    }
            
    function
setPort($port)
    {
        if(
is_numeric($port)) {
            
$this->port=(int)$port;
            return
true;
        }
        
//FAIL
        
$this->ERR("BAD PORT NO.: ".$port);
    }
    
    function
setThreadCFile($thread_c_file)
    {
        if(
is_file($thread_c_file)) {
            if(
is_readable($thread_c_file)) {
                
$this->THREAD_C_FILE=$thread_c_file;
                return
true;
            }
        }
        
//FAIL
        
$this->ERR("BAD THREAD_C_FILE: ".$thread_c_file);
    }

    function
ERR($string)
    {
        
$fh=fopen($this->ERRFILE,'a+');
        
fwrite($fh,$string."\n");
        
fclose($fh);
        exit(
0);
    }
}
$listener=new Listener($argv[1],$argv[2]);
?>
Cheers Guys
Bubble
__________________
If at first it doesn't work, slap it with a dirty hack.

Moral of the week: Never let a moral of the week go on for more than a week, it's even sillier than feeding the admins.

My Blog
bubblenut is offline   Reply With Quote
Old 02-06-2004, 04:00 PM   #2
bbaassiri
Senior Member
 
bbaassiri's Avatar
 
Join Date: Oct 2002
Location: canada
Posts: 165
2 small things as for code perpective; your check for valid port number does not include valid range 1-65536. As for you opening if file handles you should really check for error conditions cause your code will happily execute with an invalid file handle

my 2 cents
bbaassiri is offline   Reply With Quote
Old 02-06-2004, 08:31 PM   #3
OhLordy
Country Bumpkin
 
OhLordy's Avatar
 
Join Date: Feb 2003
Location: Surrey / UK
Posts: 511
I'm at home now and forgot my bubblenut password so I'm using an old account.
Thanks for the input bbaassiri I didn't know about port number limits so that's usefull to know even outside this project. With regards to the checking file handles do you just mean in the Webserver constructor or for the fopens in the while loops as well? I was thinking about putting a max limit on the number of times it could try fopen on the file but haven't got around to it. Sorted things out a little now, I had to put all the data (number of open threads and whether or not to open a new thread, used to restrict Webserver) in a file becasue found that if I set environment variables as I said before then they didn't seem to last through to when I needed them, they seemed to disapeat straight after the shell_exec().
Git it up and running and tried to access it with http://localhost:1234/index.php (I'm using port 1234 obviously) but it's not working in the slightest yet.
I'll keep you posted. Any more thoughts would be greatly apreciated.
Bubble
__________________
Bubble
Honest, it is me. I'm a muppet! I've forgoten my passoword and my email address is my work one so I can't get it while I'm at home.
OhLordy is offline   Reply With Quote
Old 02-06-2004, 09:52 PM   #4
Moonglobe
Better fan than rebelo!
 
Moonglobe's Avatar
 
Join Date: Apr 2003
Location: brain://localhost:left-side
Posts: 2,381
isn't having multiple accounts a no-no arround here?
__________________
there's no place i can be, since i found serenity.
Moonglobe is offline   Reply With Quote
Old 02-06-2004, 10:38 PM   #5
OhLordy
Country Bumpkin
 
OhLordy's Avatar
 
Join Date: Feb 2003
Location: Surrey / UK
Posts: 511
dunno ... didn't know; I can happily have the OhLordy account deleted as of Monday when I'll be able to get the password for my bubblenut account so I can bring it home.
__________________
Bubble
Honest, it is me. I'm a muppet! I've forgoten my passoword and my email address is my work one so I can't get it while I'm at home.
OhLordy is offline   Reply With Quote
Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Forum Jump


All times are GMT -4. The time now is 04:39 PM.






Acceptable Use Policy

internet.comMediabistrojusttechjobs.comGraphics.com

WebMediaBrands Corporate Info


Advertise | Newsletters | Feedback | Submit News

Legal Notices | Licensing | Permissions | Privacy Policy


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.