Ejemplo n.º 1
0
Archivo: server.c Proyecto: FRisma/lab
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;
}
Ejemplo n.º 2
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 */
}