Le protocole HTTP: Client GCC
Ce programme propose une implémentation très simple d'une requête http.
- Ce programme a été compilé et exécuté avec
succé sous Aix, window95, windows 2000 et linux
- la compilation se fait avec gcc: ggc -o clientHttp client.c
- C'est très simple à comprendre si vous connaissez le principe de
communication des sockets UNIX
- 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 /index.htm
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define CONF_FILE "http.host"
#define PACKET_SIZE 1024
void requete(void);
int to_server_socket = -1;
char server_name[100]; // nom du host du serveur
int port = 80;
char request_host[PACKET_SIZE];
char request_path[PACKET_SIZE];
int main (int argc, char *argv[])
{
struct sockaddr_in serverSockAddr;
struct hostent *serverHostEnt;
unsigned long hostAddr;
if ( argc == 5 ) { // we use a proxy
sprintf(server_name,argv[1]);
sscanf(argv[2],"%d",&port);
sprintf(request_host,argv[3]);
sprintf(request_path,argv[4]);
} else if ( argc == 3 ) { // we don't
sprintf(server_name,argv[1]);
sprintf(request_host,argv[1]);
sprintf(request_path,argv[2]);
}
else
exit(1);
/* initialise a zero serverSockAddr */
bzero((void *)&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((void *)&hostAddr,(void *)&serverSockAddr.sin_addr,
sizeof(hostAddr));
else /* si on a donné un nom */
{
serverHostEnt = gethostbyname(server_name);
if (serverHostEnt == NULL) {
printf("probleme gethost\n");
exit(1);
}
bcopy((void *)serverHostEnt->h_addr,
(void *)&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("probleme de creation socket client\n");
exit(2);
}
/* requete de connexion */
if(connect(to_server_socket,(struct sockaddr *)&serverSockAddr,
sizeof(serverSockAddr))<0)
{
printf("probleme demande de connection\n");
exit(3);
}
requete();
/* fermeture de la connection */
shutdown(to_server_socket,2);
close(to_server_socket);
return 1;
}
int readn(int fd, char *ptr, int n);
void requete (void) {
char buffer[PACKET_SIZE+1];
char line[PACKET_SIZE+2];
int rc;
static unsigned char 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"
// authentification sample
// "Authorization: Basic cHVibGljOg\r\n"
"\r\n"
,request_path,request_host);
printf(line);
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 readn(int fd, char *ptr, int n){
int nl, nr;
nl = n;
while ( nl > 0 ) {
nr = read(fd,ptr,nl);
if (nr < 0 )
return nr; /*error*/
else
if ( nr == 0 )
break;
nl -= nr;
ptr += nr;
}
*ptr = 0x00;
return (n-nl);
}
|