int main (int argc, char *const argv[]) { puts("TP4 - Franco Risma - Computacion2 - WebServer"); signal(SIGCHLD, SIG_IGN); // Auxiliary vars int option = 0; int protocolo = 0; int erno = 0; // WebServer vars char *ws_port=NULL; char *ws_droot=NULL; int ws_sd=0; int ws_csd=0; if ( Malloc(&ws_port,6) ) { return -1; } if ( Malloc(&ws_droot,25) ) { return -1; } while ((option = getopt(argc, argv, "c:46h")) >= 0) { // -c webServerConfig -4 opv4 -6 ipv6 -h help switch(option) { case 'c': if (debug) puts("Configurando server mediante archivo"); if ( config(optarg,ws_port,ws_droot) < 0) { // DocumentRoot & Port return -1; } break; case '4': if (debug) puts("Configurando server para ipv4"); protocolo = (protocolo == 0) ? 4 : -1; break; case '6': if (debug) puts("Configurando server para ipv6"); protocolo = (protocolo == 0) ? 6 : -1; break; case 'h': if (debug) puts("-4 para ipv4 -6 para ipv6 y -c archivo para configurar puerto y droot"); return 0; default: puts("Sintaxis ambigua. Intente ejecutar con -h para mas detalles"); return 0; } } if (debug) printf("Protocolo: %d\n",protocolo); if (protocolo == -1) { // Protocolo invalido write(STDERR_FILENO,"Protocolo invalido\n",19); return -1; } if (strlen(ws_port) < 1) { //Puerto invalido write(STDERR_FILENO,"Puerto invalido\n",16); return -1; } // Protocolo if ( 0 > protocol_handler(protocolo,&ws_sd,ws_port) ) { return -1; } if (debug) printf("Socket: %d\tPort: %s",ws_sd,ws_port); // Start WebServer listen(ws_sd,5); while ( (ws_csd = accept(ws_sd,NULL,NULL)) > 0 ) { switch ( (erno=fork()) ) { case 0: // HTTP Request handling webServer(ws_droot, ws_csd); return 0; default: close(ws_csd); //El padre cierra el descriptor recien creado para atender el request if (-1 == erno) { perror("ws:fork"); return -1; } printf("Conexion establecida al puerto: %s\n",ws_port); } } return 0; }
/* this is the main client connection loop - one for each connection */ static void *socket_handler(void *cn) { CONN *c = (CONN*) cn; c->buf_len = 0; c->timeout_cnt = 0; debugmsg(DEBUG_SRV, "SRV: socket-handler starting up for fd:%d\n", c->fd); while(c->run && c->d->run) { // keep-alive fd_set rd_set, wr_set; struct timeval tv; tv.tv_sec = SLEEP_STEP; tv.tv_usec = 0; FD_ZERO(&rd_set); FD_ZERO(&wr_set); FD_SET(c->fd, &rd_set); #ifdef SOCKET_WRITE if (c->cq != NULL) FD_SET(c->fd, &wr_set); #endif int ready = select(c->fd+1, &rd_set, &wr_set, NULL, &tv); if(ready<0) { dlog(DLOG_WARNING, "SRV: connection select error: %s\n", strerror(errno)); break; } if(!ready) { /* Timeout */ c->timeout_cnt += SLEEP_STEP; if (c->timeout_cnt > CON_TIMEOUT) { dlog(DLOG_INFO, "SRV: connection timeout: connection reset\n"); break; } continue; } // preform socket read/write on c->fd // NOTE: set c->run = 0; is preferred to return(!0) in protocol_handler; if (FD_ISSET(c->fd, &rd_set)) { debugmsg(DEBUG_SRV, "SRV: read..\n"); if (protocol_handler(c, c->d->userdata)) break; } #ifdef SOCKET_WRITE else // check again if we can write now. if (FD_ISSET(c->fd, &wr_set)) { if (protocol_droid(c, c->d->userdata)) break; } #endif debugmsg(DEBUG_SRV, "SRV: loop:%d\n", c->fd); } debugmsg(DEBUG_SRV, "SRV: protocol ended. closing connection fd:%d\n", c->fd); #ifndef HAVE_WINDOWS close(c->fd); #else closesocket(c->fd); #endif pthread_mutex_lock(&c->d->lock); c->d->num_clients--; pthread_mutex_unlock(&c->d->lock); dlog(DLOG_INFO, "SRV: closed client connection (%u) from %s:%d.\n", c->fd, c->client_address, c->client_port); debugmsg(DEBUG_SRV, "SRV: now %i connections active\n", c->d->num_clients); if (c->client_address) free(c->client_address); free(c); return NULL; /* end close connection */ }