Aidez moi à tester mon prog pleeease (serveur web, sockets)

Aidez moi à tester mon prog pleeease (serveur web, sockets) - C - Programmation

Marsh Posté le 29-04-2007 à 16:20:14    

Salut tout le monde,
 
j'ai un petit projet consistant à faire un serveur web en c utilisant les socket et je galere a me familiariser avec mon environnement mac (on est sur des stations sun a l'ecole).
 
Si quelqu'un pouvait m'aider à faire fonctionner tout ca ca serait vraiment cool :) (mon code est posté en dessous)
 
Merci d'avance.


Message édité par XTinX le 01-05-2007 à 01:12:17
Reply

Marsh Posté le 29-04-2007 à 16:20:14   

Reply

Marsh Posté le 29-04-2007 à 17:31:06    

Hum je veux pas trop m'avancer sur ca,mais je suis pas sur que sous macos tu aies besoin de linker avec -lsocket et -lnsl. Essaie de compiler sans, ca devrait aller...

Reply

Marsh Posté le 29-04-2007 à 19:06:20    

Ca compile en effet. Par contre comment j'execute mon main ? le terminal m'indique ceci:
 
 socket
-bash: socket: command not found
 

Reply

Marsh Posté le 29-04-2007 à 19:47:38    

./ devant le nom de ton exécutable


---------------
You get so used to things the way they are. And I've always been alone. I guess that makes me lonely.
Reply

Marsh Posté le 30-04-2007 à 15:42:19    

ah ok  :D  c est bon a savoir. Bon si je galère sur mon programme je ferais sans doute encore appel a vous :)
 
Merci

Reply

Marsh Posté le 01-05-2007 à 01:09:40    

Bon, dsl de vous embeter avec ca mais je n'arrive pas a me servir de mon environnement pour executer convenablement mon programme. Pour ceux qui ne voient pas ou je veux en venir, je dois lancer mon programme, puis aller dans mon navigateur et taper une URL du type:  
 
http://hostname:port/rep/
 
ou hostname est le nom de la machine, port le numero de port initialisé dans le programme (3333 ici). Seulement je ne sais pas comment ma machine s'appelle et ou se situe son "root" (emplacement du repertoire rep). Alors si qq1 pouvait tester mon programme ca serait vraiment cool. Ca prend vraiment 2 secondes, on devrait voir les fichiers et les sous repertoires du doissier rep s'afficher.  
 
 
Voici mon code dans son intégralité. Au passage si vous avez des remarques a faire dessus n'hesitez pas !!!!
 
 
 
 
/*
 Systemes et applications reparties  
 Auteur: Renaud DIDIER
*/
 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <string.h>
#include <pthread.h>  
#include <sys/file.h>
#include <time.h>
#include <fcntl.h>
#define TAILLE 1024
 
//variable globale pour le verrou (semaphore d'exclusion mutuelle)
pthread_mutex_t verrou = PTHREAD_MUTEX_INITIALIZER;
 
//variable globale pour la socket
int nsock;  
 
void init_mutex(){
  pthread_mutex_init((&verrou),NULL);  
}
 
void destroy_mutex(){
  pthread_mutex_destroy(&verrou);  
}
 
 
void save_log(char * buffer,char * id){
 int err;
 int fd;
 char * buffer_time=(char*)malloc(sizeof(char)*20);
 char * requete=(char*)malloc(sizeof(char)*TAILLE);
 
 strcpy(requete,buffer);
 //reservation mutex
 if (err = pthread_mutex_lock(&verrou)){
  printf("err5" );
  exit(5);
 }
 
 //ecriture
 
 time_t curtime=time(NULL);
 struct tm*loctime=localtime(&curtime);
 strftime(buffer_time,10,"%I:%M: %p",loctime);  
 printf("ecriture sur fichier de: %s faite par: %s a %s\n",requete,id,buffer_time);
    fd=open("log.txt",O_RDWR|O_CREAT,0755);
  write(fd,"[",1);
    write(fd,requete,strlen(requete));
    write(fd,":",1);
  write(fd,id,strlen(id));
  write(fd,":",1);
  //write(fd,date,strlen(date));
  //write(fd,"]",1);
    close(fd);
 
 
 //liberation mutex
 if (err = pthread_mutex_unlock(&verrou)){
   printf("err6" );
   exit(6);
 }
 
}
 
 
char * recup(char * buffer,char * debut,char * fin){
 char * result;
 char * p_debut;
 char * p_fin;
 int taille;
 p_debut=strstr(buffer,debut);
 p_fin=strstr(buffer,fin);
 
 taille=p_fin-p_debut;
 if(taille>0){
 result=(char*)malloc(sizeof(char)*taille);
 strncpy(result,p_debut,taille);
 strcat(result,"\0" );
 return result;
 }
 else{
  printf("error:%d\n",taille);
  return NULL;  
 }
}
 
char * recup2(char * buffer,char * debut){
 char * p_debut;
 p_debut=strstr(buffer,debut);
 return p_debut;
}
 
 
/* connexion serveur http */
int exec_requete(char * requete,int nsock){
 int sockDesc;
 struct sockaddr_in * adresseInet;
 struct hostent *serveur;
 
 char * destination;
 struct servent *service;
 int retour;
 
 
 destination=(char*)malloc(sizeof(char)*TAILLE);
 
 
 strcpy(destination,requete);
 
 destination+=4;
 
 destination=recup2(destination,"www" );
 printf("destination: %s\n",destination);
 
 if((sockDesc =socket(AF_INET,SOCK_STREAM,PF_UNSPEC)) == -1){
  perror("socket " );
  exit(1);
 }
 
 adresseInet = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
 adresseInet->sin_family =AF_INET;
 
 
 adresseInet->sin_port=htons(80);
 
 serveur=gethostbyname("www.enseeiht.fr" );
 
 bcopy(serveur->h_addr,&adresseInet->sin_addr,serveur->h_length);
 
 if(connect(sockDesc,(struct sockaddr*)adresseInet,sizeof(struct sockaddr_in)) == -1){
  perror("read " );
  exit(3);
 }
 else{
  printf("connection ‚àö¬©tablie\n" );
 
 }
 
 
 //retourne la socket su serveur http
 return sockDesc;
 
 
}
 
void * processus(){
 char * buffer;
 char * buffer2;
 char * cache;
 int retour;
 int retour2;
 char * nvelle_requete;
 int sock_serveur=0;
 char * user=(char*)malloc(sizeof(char)*TAILLE);
 char * save_buffer=(char*)malloc(sizeof(char)*TAILLE);
  printf("***********************************\n" );
  //lecture
  do{
   buffer=(char*)malloc(sizeof(char)*TAILLE);
   //LECTURE
   retour=read(nsock,buffer, TAILLE);
   
 
   //printf("LECTURE DE:\n%s\n",buffer);    
   
   //RECUP destination
   if(!strncmp(buffer,"GET /www",8)){
    printf("RECHERCHE SERVEUR\n" );
    cache=recup(buffer,"GET "," HTTP" );
    sock_serveur=exec_requete(cache,nsock);
    strcpy(save_buffer,buffer);
    strcpy(user,recup(save_buffer,"User-Agent:","Accept:" ));
   }
 
 
   //sauvegarde dans un fichier de logs
   save_log(buffer,user);
   bzero(save_buffer,TAILLE);
 
   write(sock_serveur,buffer,TAILLE);
   //LIBERATION
   bzero(buffer,TAILLE);
   free(buffer);
   
  }while(retour==TAILLE);
 
  printf("lecture ok\n" );
   
  //ecriture de la reponse du serveur au client
  do{
   buffer2=(char*)malloc(sizeof(char)*TAILLE);
 
   retour2=read(sock_serveur,buffer2, TAILLE);
   //printf("ECRITURE DE:\n%s\n",buffer2);  
   write(nsock,buffer2,retour2);
   //printf("taille:%d\n",retour2);
   bzero(buffer2,TAILLE);
   free(buffer2);
  }while(retour2>0);
 
  printf("ecriture ok\n" );
 
  close(sock_serveur);
  close(nsock);
   
  printf("liberation socket\n" );
  printf("***********************************\n\n\n\n" );
 return NULL;
}
 
 
 
 
int main(){
 int sock;
 int len;
 struct sockaddr_in server;
 char * p_host;
 
 init_mutex();
 
 /* creer la socket */
 sock = socket( AF_INET, SOCK_STREAM, 0 );
 
 if( sock == -1){
  printf("erreur ouverture socket serveur \n" );
  exit(2);
 }
 /* reutiliser la socket apres arret du serveur precedent */
 len=1;
 if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &len, sizeof(len)) == -1){
  printf("erreur reutilisation socket" );
  exit(2);
 }
 
 /* donner une adresse a la socket */
 bzero(&server, sizeof(server));
 server.sin_family = AF_INET;
 server.sin_addr.s_addr = INADDR_ANY;
 server.sin_port = htons(3333);
 len = sizeof(server);
 
 if(bind(sock,(struct sockaddr *) &server,len) == -1 ){
  printf("erreur bind socket serveur \n" );
  close(sock);
  exit(2);
 }
 
 /* ecoute avec un seul client */
 listen(sock,1);
 
 /* attente de requete du serveur */
 for(;;){
  //en attente d'une connexion
 nsock = accept(sock,(struct sockaddr *) 0, (int *) 0 );
 printf("connection etablie\n" );
  pthread_t tid;
  int err;  
  /*creation d'un thread pour traiter la connexion (la creation des threads ne marche pas
  if ((err = pthread_create(&tid, NULL, processus,(void *)nsock)))  
  {  
   printf("[E]rreur pthread\n" );
   exit(1);  
  }*/
   processus();
 
 }
 close(sock);
 return 0;
}

Reply

Marsh Posté le 01-05-2007 à 09:26:30    

Ta machine elle s'appelle "localhost" je suppose, si c'est comme sous les autres OS.
 
Ensuite pour le problème "je ne sais pas ou se situe son root" : c'est justement ton serveur web qui doit décider de ça, et traduire ensuite les chemins qui lui sont passés dans les requêtes GET en des chemins relatifs à ce qui est root pour ton serveur. En passant, fait bien gaffe en faisant cette traduction : il ne devrait jamais être possible de sortir du root du serveur web, même en mettant des ".." dans l'url... Sinon énorme faille de sécurité !

Reply

Marsh Posté le 01-05-2007 à 16:05:57    

Bon pour le nom de la machine c'est ok. Par contre le squelette du programme nous a été fournis et je n'ai pas le souvenir d'avoir entré un chemin d'acces. Comment faire ?

Reply

Marsh Posté le 02-05-2007 à 08:05:29    

Je ne comprend pas ton problème... Pour commencer tu peux hardcoder un "document_root". Quand tu reçois une requête du genre "GET /chemin/du/fichier HTTP/1.0", tu colles document_root devant /chemin/du/fichier,et voilà. Après tu améliores le procédé pour empecher le client de remonter en dehors de document_root.

Reply

Marsh Posté le 04-05-2007 à 00:05:12    

En fait j'avais pas prie le bon enoncé ni les bonnes sources :D
 
J ai repris le code et je cherche maintenant a generer des fichiers index avec le contentu de tous les repertoires et sous repertoires d'un chemin racine. Quelqu'un peut m'aider ????

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed