Le protocole HTTP: Client HTTP en visual C++


ce programme est le portage du petit client http en version Visual C++pour windows
- Ce programme propose une implémentation très simple d'une requête http.
- Ce programme a été compilé et exécuté avec visual C++ - C'est très simple à comprendre si vous connaissez le principe de communication des sockets
- ligne de commande: client proxy_name proxy_port host page
e.g: si vous n'utilisez pas de proxy, faites simplement : client www.salemioche.com 80 www.salemioche.com /
- créer un projet et dans les options de link ajouter la librairie 'ws2_32.lib'
- la version gcc de ce programme est disponible : ici
#ifndef _WINSOCKAPI_
#include <winsock.h>
#endif

#include <windows.h>
#include <stdio.h>

#include <initguid.h>


#include <errno.h>
#include <signal.h>

#include <tchar.h>

#define PACKET_SIZE  1024

void bcopy( void * source, void * destination, int size )
{
   char * src = ( char * ) source;
   char * dst = ( char * ) destination;

   for( int i=0; i<size; i++ )
      dst[i] = src[i];
}



void bzero( void * destination, int size )
{
   char * dst = ( char * ) destination;

   for( int i=0; i<size; i++ )
      dst[i] = 0x00;
}


void init(void);
void appli();
int writen(int fd, char *ptr, int n);

int to_server_socket = -1;
char server_name[100];         /* nom du host du serveur */
int port;
char request_host[PACKET_SIZE];
char request_path[PACKET_SIZE];

void main (int argc, char *argv[])
{

struct sockaddr_in serverSockAddr;    /* addresse de la socket */
struct hostent *serverHostEnt;        /* description du host serveur */
long hostAddr;                       /* addr du serveur */
WSADATA wsaData;
WORD wVersionRequested;
int err;

  if ( argc == 5 ) {
   sprintf(server_name,argv[1]);
   sscanf(argv[2],"%d",&port);
   sprintf(request_host,argv[3]);
   sprintf(request_path,argv[4]);

   }
  else
   exit(1);

  printf("CONF %s %d %s %s\n",server_name,port,request_host,request_path);

  wVersionRequested = MAKEWORD( 2, 2 );

  err = WSAStartup( wVersionRequested, &wsaData );
  if ( err != 0 ) {
    printf("ca chie WSAStartup : %X\n",WSAGetLastError());
    exit(1);
  }


     /* initialise a zero serverSockAddr */
  bzero(&serverSockAddr,sizeof(serverSockAddr));
     /* converti l'adresse ip 9.100.1.1 en entier long */
  hostAddr = inet_addr(server_name);
  if ( (long)hostAddr != (long)-1)
      bcopy(&hostAddr,&serverSockAddr.sin_addr,sizeof(hostAddr));
  else     /* si on a donne un nom  */
  {
      serverHostEnt = gethostbyname(server_name);
      if (serverHostEnt == NULL)
      {
          printf("ca chie gethost : %X\n",WSAGetLastError());
          exit(0);
      }
      bcopy(serverHostEnt->h_addr,
            &serverSockAddr.sin_addr,serverHostEnt->h_length);
  }
  serverSockAddr.sin_port = htons(port);         /* host to network port  */
  serverSockAddr.sin_family = AF_INET;            /* AF_*** : INET=internet */

  /* creation de la socket */
  if ( (to_server_socket = socket(AF_INET,SOCK_STREAM,0)) < 0)
  {
      printf("ca chie creation socket client\n");
      exit(0);
  }
  /* requete de connexion */
  if(connect(to_server_socket,(struct sockaddr *)&serverSockAddr,
             sizeof(serverSockAddr))<0)
  {
      printf("ca chie demande de connection\n");
      exit(0);
  }

  appli();

  /* fermeture de la connection */
  shutdown(to_server_socket,2);
  closesocket(to_server_socket);
  WSACleanup( );
}

int readn(int fd, char *ptr, int n);

void appli (void) {
char buffer[PACKET_SIZE+1];
char line[PACKET_SIZE+2];
int rc;
int i = 0;
static isEntete = 1;
char *finEntete;
FILE *bulk, *entete;

        sprintf(buffer,"Vide\n");
        sprintf(line,"GET %s HTTP/1.1\r\n"
           "Host: %s\r\n"
           "Accept: image/gif, image/x-xbitmap, image/jpeg,"
           " image/pjpeg, image/png, */*"
           "\r\n\r\n"
           ,request_path,request_host);

        if ( ( bulk = fopen("bulkhttp","wb")) == NULL ) {
                printf ( "can't open file to write bulk\n" );
                exit(1);
        }
        if ( ( entete = fopen("entete","wb")) == NULL ) {
                fclose(bulk);
                printf ( "can't open file to write entete\n" );
                exit(1);
        }

        send(to_server_socket,line,strlen(line)+1,0);

        do {
                rc = readn(to_server_socket,buffer,PACKET_SIZE);
                if ( isEntete == 1 ) {
                        finEntete = (char *)strstr(buffer,"\r\n\r\n");
                        if ( finEntete != NULL ) {
                                *finEntete = 0x00;
                                fwrite(buffer,1,strlen(buffer),entete);
                                fwrite(finEntete+4,1,rc-strlen(buffer)-4,bulk);
                                isEntete = 0;
                        }
                        else
                                fwrite(buffer,1,rc,bulk);
                        fclose(entete);
                }
                else
                        fwrite(buffer,1,rc,bulk);
        } while ( rc != 0 ) ;
        fclose(bulk);
}

int writen(int fd, char *ptr, int n)
{
int nl, nw;
        nl = n;
        while ( nl > 0 ) {
                nw = send(fd, ptr, nl,0);
                if ( nw <= 0 )
                        return nw;     /*error*/
                nl -= nw;
                ptr += nw;
        }
        return (n-nl);
}

int readn(int fd, char *ptr, int n){
int nl, nr;

        nl = n;
        while ( nl > 0 ) {
                nr = recv(fd,ptr,nl,0);
                if (nr < 0 )
                        return nr;     /*error*/
                else
                        if ( nr == 0 )
                                break;
                nl -= nr;
                ptr += nr;
        }