Previous: , Up: Implementing an Insecure HTTP Client   [Index]


1.3.2 Code Listing for the Implementation of an Insecure HTTP Client

This is the full code listing for the Insecure HTTP Client.

  1  /**
  2  *  This test utility does simple (non-encrypted) HTTP
  3  */
  4  
  5  #include <stdio.h>
  6  #include <stdlib.h>
  7  #include <errno.h>
  8  #include <string.h>
  9  #include <sys/types.h>
 10  #include <netdb.h>
 11  #include <sys/socket.h>
 12  #include <netinet/in.h>
 13  #include <unistd.h>
 14  
 15  #define HTTP_PORT        80
 16  #define BUFFER_SIZE     255
 17  #define MAX_GET_COMMAND 255
 18  
 19  /**
 20   * Accept a well-formed URL (e.g. http://www.company.com/index.html) and return
 21   * pointers to the host part and the path part. Note that this function
 22   * modifies the uri itself as well. It returns 0 on success, -1 if the URL is
 23   * found to be malformed in any way.
 24   */
 25  
 26  int parse_url( char *uri, char **host, char **path )
 27  {
 28    char *pos;
 29  
 30    pos = strstr( uri, "//" );
 31  
 32    if ( !pos )
 33      {
 34        return -1;
 35      }
 36  
 37    *host = pos + 2;
 38  
 39    pos = strchr( *host, '/' );
 40  
 41    if ( !pos )
 42      {
 43        *path = NULL;
 44      }
 45    else
 46      {
 47        *pos = '\0';
 48        *path = pos + 1;
 49      }
 50  
 51    return 0;
 52  }
 53  
 54  /**
 55   * Format and send an HTTP get command. The return value will be 0 on
 56   * success, -1 on failure, with errno set appropriately. The caller
 57   * must then retrieve the response.
 58   */
 59  
 60  int http_get( int connection, const char *path, const char *host )
 61  {
 62    static char get_command[ MAX_GET_COMMAND ];
 63  
 64    sprintf( get_command, "GET /%s HTTP/1.1\r\n", path );
 65    if ( send( connection, get_command, strlen( get_command ), 0 ) == -1 )
 66    {
 67      return -1;
 68    }
 69  
 70    sprintf( get_command, "Host: %s\r\n", host );
 71    if ( send( connection, get_command, strlen( get_command ), 0 ) == -1 )
 72    {
 73      return -1;
 74    }
 75  
 76    sprintf( get_command, "Connection: close\r\n\r\n" );
 77    if ( send( connection, get_command, strlen( get_command ), 0 ) == -1 )
 78    {
 79      return -1;
 80    }
 81  
 82    return 0;
 83  }
 84  
 85  /**
 86   * Receive all data available on a connection and dump it to stdout
 87   */
 88  
 89  void display_result( int connection )
 90  {
 91    int received = 0;
 92  
 93    static char recv_buf[ BUFFER_SIZE + 1 ];
 94  
 95    while ( ( received = recv( connection, recv_buf, BUFFER_SIZE, 0 ) ) > 0 )
 96    {
 97      recv_buf[ received ] = '\0';
 98      printf( "%s", recv_buf );
 99    }
100  
101    printf( "\n" );
102  }
103  
104  /**
105   *  Simple command-line HTTP client.
106   */
107  
108  int main( int argc, char *argv[ ] )
109  {
110    int client_connection;
111    char *host, *path;
112    struct hostent *host_name;
113    struct sockaddr_in host_address;
114  
115    if ( argc < 2 )
116      {
117        fprintf( stderr, "Usage: %s: <URL>\n", argv[ 0 ] );
118        return 1;
119      }
120  
121    if ( parse_url( argv[ 1 ], &host, &path ) == -1 )
122      {
123        fprintf( stderr, "Error - malformed URL '%s . \n", argv[ 1 ] );
124        return 1;
125      }
126  
127    printf( "Conecting to host '%s'\n", host );
128  
129  // Step 1: open a socket connection on http port with the destination host
130  
131    client_connection = socket( PF_INET, SOCK_STREAM, 0 );
132  
133    if ( !client_connection )
134    {
135      perror( "Unable to create a local socket" );
136      return 2;
137    }
138  
139    host_name = gethostbyname( host );
140  
141    if ( !host_name )
142    {
143      perror( "Error in name resolution" );
144      return 3;
145    }
146  
147    host_address.sin_family = AF_INET;
148    host_address.sin_port = htons( HTTP_PORT );
149    memcpy( &host_address.sin_addr, host_name->h_addr_list[ 0 ],
150          sizeof( struct in_addr ) );
151  
152    if ( connect( client_connection, ( struct sockaddr * ) &host_address,
153            sizeof( host_address ) ) == -1 )
154    {
155      perror( "Unable to connect to host" );
156      return 4;
157    }
158  
159    printf( "Retrieving document: '%s'\n", path );
160  
161  // Step 2: Issue a GET command
162  
163    http_get( client_connection, path, host );
164  
165    display_result( client_connection );
166  
167    printf( "Shutting down.\n" );
168  
169    if (close( client_connection ) == -1 )
170    {
171      perror( "Error closing client connection" );
172      return 5;
173    }
174  
175    return 0;
176  }
177  

Previous: , Up: Implementing an Insecure HTTP Client   [Index]