Posts

Showing posts from March 19, 2009

Authentication over HTTP

Image
HTTP authentication traditionally takes the form of .htaccess files scattered around various directories webmasters want to keep private. A typical .htaccess file, combined with a .htpasswd file, contains information about users that are allowed access to a directory and their password. Even though Apache allows you to customise these permissions, the system is far from flexible - hand-editing files each time you add users, or having to group authorised users together by password is a little behind the times. HTTP authentication is mostly just a matter of sending special HTTP headers to your client asking them to provide access codes, and it is straightforward to implement in PHP as long as you have configured PHP to run as an Apache module (see previous issue for our installation guide). Let's look at basic authentication by creating the file auth.php, which should look like this: if (!isset( $_SERVER [ 'PHP_AUTH_USER' ])) { header ( "WWW-Authenticat...

Reading queued headers

array headers_list ( void ) We already looked at the headers_sent() function, which tells us whether or not HTTP headers have already been sent to the client. This function duplicates that functionality, but, crucially, also returns headers that have yet to be sent, which when you think about it is a bit more useful. As you can see from the prototype, it takes no parameters, and returns an array. That array contains a numerically indexed list of the headers that are ready for sending, which means we can extend our previous example like this: header ( "Expires: Sat, 22 Dec 1979 05:30:00 GMT" ); echo "This is some text for output. " ; if (! headers_sent ( $filename , $linenum )) { // if no headers have been sent, send one // this will not execute, as we sent the Expires header. header ( "Location: www.yoursite.com" ); exit; } else { echo "Headers alr...

Sending custom headers Using PHP

string header ( string header_to_send [, bool replace [, int http_response_code ]]) bool headers_sent ( [string &file [, int &line ]]) As well as status codes, there are a variety of special HTTP headers you can send that give you greater control. For example, the "Location" header instructs browsers to request a different URL, the "Content-Type" header tells browsers what kind of content they are about to receive, and the "WWW-Authenticate" header tells browsers that they need to send some authentication information to proceed. Each of these headers is combined with the HTTP status code to form the header of a HTTP response. This is then followed by two carriage return/line feeds, \r\n\r\n, then the actual content. For example, here is what I got when I sent a request to the popular hardware discussion site, tomshardware.com: HTTP/1.1 200 OK Date: Thu, 31 Jul 2003 21:35:46 GMT Server: Apache/1.3.26 (Unix) mod_...

Host and IP resolution

string gethostbyaddr ( string ip_address ) string gethostbyname ( string hostname ) string gethostbynamel ( string hostname ) There are three functions designed to specifically resolve web host information, and these are gethostbyaddr() , gethostbyname() and gethostbynamel() (that is a lower-case L, by the way). All three take one parameter, and the first two complement each other perfectly - gethostbyname() returns the IP address of a server you specify, and gethostbyaddr() returns the domain name of an IP address you specify. Here is an example of their usage: $sdip = gethostbyname ( "slashdot.org" ); $sddomain = gethostbyaddr ( $sdip ); print "IP: $sdip\n" ; print "Domain: $sddomain\n" ; ?> That should output the following: IP: 66.35.250.150 Domain: slashdot.org By default, gethostbyname() returns the first value IP address for a host, but i...

Domain resolution functions

int dns_check_record ( string host [, string type ]) int dns_get_mx ( string hostname , array mxhosts [, array &weight ]) int dns_get_record ( string hostname [, int type [, array &authns , array &addtl ]]) There are three helpful Domain Name System (DNS) functions that allow you to check and retrieve specific information about other servers on the Internet or the local network. These are dns_check_record() , dns_get_mx() , dns_get_record() , and, sadly, all three are not supported on Windows. The first two from that list, dns_check_record() and dns_get_mx() , both work in roughly the same way - the former returns true if it finds a DNS record for the domain you specify in parameter one, and the latter returns true if it finds an MX record for the domain specified in parameter one, and places the full list of MX servers into a second parameter as an array. If you did not know already, the Domain Name System (DNS), is what turns...

Sockets can be powerful

OK, so a ROT13 system is not very helpful, so I would not be surprised if you were wondering whether sockets could be made to do anything useful . Well, consider what socket applications you use - what relies on sockets to work? One of the simplest systems is a web server - an application that listens for requests on a given port, and serves up the files that are asked for. Naturally web servers do a lot more than that - they have to receive POST data, handle file uploads, permissions, filters, and lots more, but we're only interested in the most basic task: serving files. Your average HTTP request will look like this: GET /somefile.txt HTTP/1.1 HOST: www.foo.com Out of all that, we can ignore everything but "/somefile.txt" - that is the file we need to serve up. So, our server waits listening for connections and requests, sending out files as appropriate. Each HTTP response needs to take a very specific format because HTTP splits its response into "...

Sockets can be servers

Image
resource socket_create_listen ( int port [, int backlog ]) resource socket_accept ( resource socket ) int socket_write ( resource socket , int length [, int length ]) string socket_read ( resource socket , int length [, int type ]) void socket_close ( resource socket ) We have just covered the basic use of sockets in PHP, and the next step is to move onto the advanced, more flexible sockets that allow you to create more advanced networking scripts with PHP. There are several functions of interest here: socket_create_listen() , socket_accept() , socket_write() , socket_read() , and socket_close() . In order, those functions create and instruct a socket to listen on a given port, receive a client connecting to the socket, write text out to the client, read text sent by the client, and close the socket. The sockets system starts with socket_create_listen() , which takes a port number to listen on as its only parameter. T...

Sockets aren't all about HTTP

While receiving compressed content is not a particularly amazing thing to do with fsockopen() , it should at least demonstrate the fact that it gives you a lot more control over your sockets than simply using fopen() . For example, if we wanted to do something other than read HTTP, we just need to change the port number - here is a script that reads in Whois information about a site: $fp = fsockopen ( "whois.networksolutions.com" , 43 ); if ( $fp ) { fwrite ( $fp , "microsoft.com\n" ); while (! feof ( $fp )) { print fread ( $fp , 256 ); } fclose ( $fp ); } else { print "Fatal error\n" ; } ?> It looks similar to the last one, as I am sure you can see. The difference is that this time we connect to the Whois database of Network Solutions, which contains registrar information for .com, .net, and .org domains, and we query it for information on micro...

Making a simple search Engine Using PHP

We've now looked at both fopen() and fsockopen() , both of which are great for reading in content from websites. However, thanks to the way streams work in PHP, you can read remote data in with a huge selection of functions - even down to the relatively lowly file_get_contents() . To show off this functionality, I wrote a very simple search engine that spiders websites by pulling out hyperlinks and inserting data into a MySQL table. The code is very, very simple, and very naive - it's here to demonstrate a point, not be a perfect search engine, so please don't base your own efforts on it! = array( "http://www.google.com" ); $parsed = array(); $sitesvisited = 0 ; mysql_connect ( "localhost" , "phpuser" , "alm65z" ); mysql_select_db ( "phpdb" ); mysql_query ( "DROP TABLE simplesearch;" ); mysql_query ( "CREATE TABLE simplesearch (URL CHAR(255), Contents TEXT);" ); mysql_query ( "AL...

Sockets are files

resource fsockopen ( string target , int port [, int error_number [, string error_string [, float timeout ]]]) The simplest way to work with sockets is using them as if they were files. In fact, if you are using Unix, sockets actually are files, whereas in Windows this behaviour is just emulated. If you read about file_get_contents() and fopen() in the Files chapter, I have some great news for you: pretty much everything you learnt there can be applied directly to sockets, which means you can fread() and fwrite() to files as you would a normal file. Take a look at the following code: = fsockopen ( "google.com" , 80 ); if ( $fp ) { fwrite ( $fp , "GET / HTTP/1.1\r\nHOST: slashdot.org\r\n\r\n" ); while (! feof ( $fp )) { print fread ( $fp , 256 ); } fclose ( $fp ); } else { print "Fatal error\n" ; } ?> That script performs the same function as the original fopen() script, with the exception that fsockopen() ...

PHP Networks

Networks The Internet is really just one big network, albeit the largest and most convoluted one ever created, and there are a variety of different protocols that allow communication. The most common protocol is HTTP, followed by FTP, but there are literally dozens of others, each with their own specific purpose. PHP has a number of ways to work over a network - the most common protocols have special functions to make often-used functionality easy, but it is possible to use PHP to write any kind of data over any kind of protocol. The topics covered in this chapter are: * What sockets are, and basic socket use * How to use sockets outside of HTTP * How to create a basic server using PHP * Creating a web server * Helpful network-related functions * HTTP-specific and FTP-specific functions * The Curl library Sockets Surprising as this may come to some of you, your connection to the Internet is not handled by well-traine...