#include #include #include #include #include #include #include #include #include #include #include "socketFunction.h" /* * createSocketListener * créée un socket, le lie au port d'écoute et passe en mode listening */ int createSocketListener(int port){ int sck; struct sockaddr_in adr; adr.sin_family = AF_INET; adr.sin_addr.s_addr = INADDR_ANY; adr.sin_port = htons(port); if((sck = socket(AF_INET,SOCK_STREAM,0))==-1){ return(-1); } if(bind(sck,(struct sockaddr*)&adr,sizeof(adr))==-1){ return(-2); } if(listen(sck,10)==-1){ return(-3); } return (int)sck; } /* *récupére un header et évite un minimum de requètes foireuses */ int myrecv(int sck, char * buffer, int bufflen, int resv, int timeout){ struct timeval to; fd_set myset; to.tv_sec = 0; to.tv_usec = timeout*1000; //microseconde FD_ZERO(&myset); FD_SET(sck,&myset); if(select(sck+1,&myset,NULL,NULL,&to) <= 0){ printf("myrecv SELECT\n"); return -1; } return recv(sck,buffer,bufflen,0); } char * recvHeader(int sck){ char field[MAX_FIELD_LEN+1]; // + NULLBYTE int totalField=0; char *header=NULL,*ptr; //fd_set myset; //struct timeval to; //to.tv_sec = 0; //to.tv_usec = TIMEOUT*1000; //microseconde //Tant que nous n'avons pas atteint la limite du nombre de champ d'un header while(totalField++ < MAX_HEADER_FIELDS){ int totalLenField=0; char c=0; while(c!='\n'){ //On réinitialise le set (obligatoire sous windows) //FD_ZERO(&myset); //FD_SET(sck,&myset); //if(select(sck+1,&myset,NULL,NULL,&to) <= 0){ // free(header); //si header est nul free n'a pas lieu // printf("SELECT UR MOTHER\n"); // return NULL; //} //if(recv(sck,&c,1,0)==-1){ if(myrecv(sck,&c,1,0,TIMEOUT)==-1){ free(header); printf("RECV HAS SUXED\n"); return NULL; } //on incrémente la longueur du champ et on regarde si le champ du header trop long if(++totalLenField == MAX_FIELD_LEN+1){ free(header); printf("FIELD TROP LONG\n"); return NULL; } field[totalLenField-1]=c; //caractère invalide dans le champ du header if(c== '\0'){ printf("NULL BYTE\n"); free(header); return NULL; } } field[totalLenField]='\0'; if(header!=NULL){ if((ptr = (char*)realloc(header,(strlen(header)+1+totalLenField)*sizeof(char)))==NULL){ free(header); return NULL; } header=ptr; }else{ if((header = (char*)calloc(totalLenField+1,sizeof(char)))==NULL){ return NULL; } } strcat(header,field); // \r\n\r\n == FIN DU HEADER if(strncmp(header+strlen(header)-4,"\r\n\r\n",4)==0) return header; } //Trop de champ ou requête invalide printf("TROP DE FIELD\n"); free(header); return NULL; } //Le header a été contolé avant d'atteindre cette fonction char* getField(char * header, char * fieldName){ int i=0,j; char * fieldValue; //On zape la ligne de methode (1ére APL) while(header[i++]!='\n'); //Tant que nous ne sommes pas à la fin du header while(strncmp(header+i-2,"\r\n\r\n",4)!=0){ j=i; while(header[++i]!=':'); //Le nom du champ est correcte, on copie sa valeur if(strncasecmp(header+j,fieldName,strlen(fieldName)) == 0){ while(header[++j]!='\r'); if((fieldValue = (char*)calloc(j-i,sizeof(char)))!=NULL){ //+2 car on enlève egalement l'espace en trop strncpy(fieldValue,header+i+2,j-i-2); return fieldValue; }else return NULL; } //on passe à la ligne suivante while(header[i++]!='\n'); } return NULL; } //Le header a été contolé avant d'atteindre cette fonction int rmField(char ** header,char *fieldName){ int i=0,j,k=0; char * ptr; //On zape la ligne de methode (1ére APL) while((*header)[i++]!='\n'); //Tant que nous ne sommes pas à la fin du header while(strncmp((*header)+i-2,"\r\n\r\n",4)!=0){ j=i; while((*header)[++i]!=':'); //Le nom du champ est correcte, on enlève le champ if(strncasecmp((*header)+j,fieldName,strlen(fieldName)) == 0){ while((*header)[i++] != '\n'); while((*header)[i+k-1] != '\0'){ (*header)[j+k] = (*header)[i+k]; k++; } //On libère la mémoire gagnée if((ptr=realloc((*header),strlen((*header))+1))==NULL){ free(*header); return -1; } *header=ptr; return 1; } //on passe à la ligne suivante while((*header)[i++]!='\n'); } return -1; } //Le header a été contolé avant d'atteindre cette fonction int setField(char ** header,char *fieldName,char *fieldValue){ //Taille Maximum d'un champ du header char buffer[MAX_FIELD_LEN]; char * ptr; int hLen; /* implementer : fieldValue et fieldName ne doit pas contenir de \r\n */ //On enlève le champ s'il est déjà présent rmField(header,fieldName); hLen=strlen((*header)); //On fabrique notre champ que l'on ajoute à la fin sprintf(buffer,"%s: %s\r\n\r\n",fieldName,fieldValue); //On réalloue la mémoire de notre header if((ptr=realloc((*header),hLen+strlen(buffer)+1))== NULL){ free(*header); return -1; } *header=ptr; strcpy((*header)+hLen-2,buffer); return 1; } int getMethod(char *header){ int i=0; while(header[++i]!=' ' && i<8); if(strncmp(header,"HEAD",i) == 0) return HEAD; if(strncmp(header,"GET",i) == 0) return GET; if(strncmp(header,"POST",i) == 0) return POST; if(strncmp(header,"PUT",i) == 0) return PUT; if(strncmp(header,"DELETE",i) == 0) return DELETE; if(strncmp(header,"TRACE",i) == 0) return TRACE; if(strncmp(header,"OPTIONS",i) == 0) return OPTIONS; if(strncmp(header,"CONNECT",i) == 0) return CONNECT; return -1; } int getIpPortFromHost(char *hostname,unsigned long * ip,int * port){ struct hostent * host; int i=0; char *temp; char cHost[MAX_FIELD_LEN]; while(hostname[++i]!=':' && hostname[i]!='\0' && i <= 1000); if(i>MAX_FIELD_LEN-1) return -1; strncpy(cHost,hostname,i); cHost[i]='\0'; if(hostname[i] != '\0'){ temp=hostname+i+1; i=0; while(temp[++i]!='\0' && i<7); if(i>5){ printf("PORT INCORRECTE%s\n",temp); return -2; } *port=atoi(temp); }else *port=80; if((host = gethostbyname(cHost))==NULL){ printf("HOST NULL %s\n",cHost); return -3; } (*ip) = (*(unsigned long*)host->h_addr); return 1; }