Presentation is loading. Please wait.

Presentation is loading. Please wait.

A ‘minimal’ web-server We can glean insights about the operation of the HTTP protocol if we create our own web-server.

Similar presentations


Presentation on theme: "A ‘minimal’ web-server We can glean insights about the operation of the HTTP protocol if we create our own web-server."— Presentation transcript:

1 A ‘minimal’ web-server We can glean insights about the operation of the HTTP protocol if we create our own web-server

2 A web-browser is our ‘client’ Mozilla FirefoxOur ‘mini’ server HTTP request line Request ‘headers’ Optional ‘body’ Request-message (to server) HTTP status line Response ‘headers’ Optional ‘body’ Response-message (to client)

3 TCP server ‘boilerplate’ By now we have seen that any connection oriented ‘server’ has some standard steps to execute by way of ‘connection-setup’ –Initialize a host ‘socket-address’ structure –Create a TCP socket to use for ‘listening’ –Bind the ‘socket-address’ to this socket –Enable the socket to ‘reuse’ its port-number –Convert the socket into a ‘listening’ socket –Accept a ‘connection-request’ from a client

4 ‘helper’ functions We can employ standard library-functions to help setup the internet socket-address data-structure for our server’s host: –‘gethostname()’ –‘gethostbyname()’ –‘inet_ntoa()’ –‘inet_addr()’ –‘htons()’

5 Our ‘sockaddr_in’ setup padded with zeros sin_familysin_portsin_addr struct sockaddr_in

6 Setup our ‘listening’ socket

7 ‘iterative’ server-design ‘accept’ a connection-request from a client ‘receive’ the HTTP request-message validate and process the HTTP command ‘send’ the HTTP response-message ‘close’ the connection with this client We use some new ‘helper’ functions for these steps

8 ‘fdopen()’ To conveniently process the incoming stream of characters in a client’s HTTP request-message (which is organized into lines of text with CRLF as the line-delimiter), and to conveniently reply with similarly organized lines of text, we would like to use the standard ‘buffered’ i/o functions To do this requires substituting ‘streams’ for our TCP ‘connection’ socket, which is accomplished by using the ‘fdopen()’ library-function

9 ‘fdopen()’ and ‘dup()’ To conveniently process the incoming stream of characters in a client’s HTTP request-message (which is organized into lines of text with CRLF as the line-delimiter), and to conveniently reply with similarly organized lines of text, we would like to use the standard ‘buffered’ i/o functions To do this will require us to associate ‘streams’ with our TCP ‘connection’ socket, one for input, one for output, which we can accomplish using the ‘fdopen()’ and ‘dup()’ library-functions

10 Our i/o streams Our connection-socket is named ‘conn’: We associate an input-stream with ‘conn’: And we associate an output-stream with a ‘duplicate’ of our connection-socket ‘conn’: struct sockaddr_incaddr = { 0 }; socklen_tsalen = sizeof( caddr ); intconn = accept( sock, (sockaddr*)&caddr, &calen ); FILE*rx = fdopen( conn, “r” ); FILE*tx = fdopen( dup( conn ), “w” );

11 Request message’s lines Now it’s easy to receive the first ‘line’ of an HTTP request-message sent by our client: The remaining lines (request headers and the empty line) can be received like this: charrequest[ BUFSIZ ] = { 0 }; fgets( request, BUFSIZ, rx ); charheader[ BUFSIZ ] = { 0 }; while ( fgets( request, BUFSIZ, rx ) ) if ( strcmp( header, “\r\n” ) == 0 ) break;

12 Parsing the ‘request’ The HTTP Request-line is comprised of three fields, separated by a blank-space and terminated with the CR/LF delimiter We can use the formatted string-scan function ‘sscanf()’ to parse the request ”\r\n” charcmd[ BUFSIZ ] = { 0 }, arg[ BUFSIZ ] = { 0 }; strcpy( arg, “./” );// for restricting the client’s access if ( sscanf( “%s%s”, cmd, arg+2 ) != 2 ) { perror( “sscanf” ); }

13 Validating the request For now our ‘miniature’ web-server only accepts the basic HTTP ‘GET’ command: if ( strcmp( cmd, “GET” ) != 0 ) { // the HTTP Response status, headers, and empty line fprintf( tx, “HTTP/1.0 501 Not Implemented \r\n” ); fprintf( tx, “Content-type: text/plain \r\n” ); fprintf( tx, “\r\n” ); // the HTTP Response-message’s ‘body’ fprintf( tx, “That one is not yet implemented \r\n” fclose( rx ); fclose( tx ); continue; }

14 ‘nonexistent’ resource? The ‘stat()’ library-function can be used to verify that a requested resource exists struct statinfo = { 0 }; if ( stat( arg, &info ) < 0 )// the target does not exist { // the HTTP Response’s status, headers, and empty line fprintf( tx, “HTTP/1.0 404 Not Found \r\n” ); fprintf( tx, “Content-type: text/plain \r\n” ); fprintf( tx, “\r\n” ); // the HTTP Response-message’s ‘body’ fprintf( tx, “Requested item not found \r\n” fclose( rx ); fclose( tx ); continue; }

15 ‘struct stat’

16 ‘statdemo()’ We have posted a demo-program which lets you see the information about a file which the Linux operating system keeps track of (including the ‘type’ of the file) EXAMPLE: $./statdemo mywebsvr.cpp

17 ‘folder’ or ‘file’? Our server can send its client a directory- listing if that type of resource is requested if ( S_ISDIR( info.st_mode ) ) // the requested resource is a directory { // the HTTP Response’s status, headers, and empty line fprintf( tx, “HTTP/1.0 200 OK \r\n” ); fprintf( tx, “Content-type: text/plain \r\n” ); fprintf( tx, “\r\n” ); // the HTTP Response-message’s ‘body’ fflush( tx ); if ( fork() == 0 ) // child-process will deliver the directory-listing { dup2( conn, 1 ); dup2( conn, 2 ); close( conn ); execlp( “ls”, “ls”, “-l”, arg, NULL ); exit( 1 ); } wait( NULL ); // parent-process will sleep until tge child exits fclose( rx ); fclose( tx ); continue; }

18 A sample web-page We created a tiny webpage example for demonstrating our web-server’s ability to deliver an ‘HTML’ file to a web-browser

19 Delivering an ‘html’ file if ( strcmp( strrchr( arg, ‘.’ ) + 1, “html” ) == 0 ) // the requested resource is an ‘html’ file { // the HTTP Response’s status, headers, and empty line fprintf( tx, “HTTP/1.0 200 OK \r\n” ); fprintf( tx, “Content-type: text/html \r\n” ); fprintf( tx, “\r\n” ); // the HTTP Response-message’s ‘body’ fflush( tx ); if ( fork() == 0 ) // child-process will deliver the file’s contents { dup2( conn, 1 ); dup2( conn, 2 ); close( conn ); execlp( “cat”, “cat”, arg, NULL ); exit( 1 ); } wait( NULL ); // parent-process will sleep until the child exits fclose( rx ); fclose( tx ); continue; }

20 ‘mywebsvr.cpp’ We posted this miniature web-server on our course website for you to download You can use Linux’s ‘Firefox’ browser to see if indeed it can deliver the sample HTML-file (named ‘mywebpage.html’) First start the web-server application, then launch ‘Firefox’ and type in this URL: Your classroom host’s station-number

21 In-class exercise #1 Try using Microsoft’s Internet Explorer to request the ‘mywebpage.html’ document Edit your copy of ‘mywebpage.html’ to add the following attributes within the tag in that HTML document:

22 In-class exercise #2 Copy the file named ‘warrior.jpg’ from our course website into your local directory Then modify the ‘mywebpage.html’ file by adding this extra line in front of : Now extend the functionality of our ‘mini’ web-server by adding a block of new code which enables a child-process to deliver an image-file having the ‘.jpg’ file-suffix

23 Exercise #2 (continued) You can do this with your Editor by using ‘copy-and-paste’ applied to the code-block that delivers an ‘html’ file to a client – just change the ‘html’ file-suffix to ‘jpg’, and change the ‘Content-type’ statement so that ‘text/html’ becomes ‘image/jpeg”


Download ppt "A ‘minimal’ web-server We can glean insights about the operation of the HTTP protocol if we create our own web-server."

Similar presentations


Ads by Google