- /* backup server descriptor set */
- used_fds = serv_fds;
-
- /* loop */
- while(run)
- {
- /* create a working copy of the used fd set */
- read_fds = used_fds;
-
- /* sleep until socket activity */
- if( select(max_fd + 1, &read_fds, NULL, NULL, NULL) == -1 )
- {
- perror("select()");
- exit(1);
- }
-
- /* run through the existing connections looking for data to be read */
- for( cur_fd = 0; cur_fd <= max_fd; cur_fd++ )
- {
- /* is a socket managed by us */
- if( FD_ISSET(cur_fd, &read_fds) )
- {
- /* is one of our listen sockets */
- if( FD_ISSET(cur_fd, &serv_fds) )
- {
- /* handle new connections */
- if( (new_fd = accept(cur_fd, NULL, 0)) != -1 )
- {
- /* add to global client list */
- if( (cl = uh_client_add(new_fd, uh_listener_lookup(cur_fd))) != NULL )
- {
-#ifdef HAVE_TLS
- /* setup client tls context */
- if( conf.tls )
- conf.tls_accept(cl);
-#endif
-
- /* add client socket to global fdset */
- FD_SET(new_fd, &used_fds);
- fd_cloexec(new_fd);
- max_fd = max(max_fd, new_fd);
- }
-
- /* insufficient resources */
- else
- {
- fprintf(stderr,
- "uh_client_add(): Can not manage more than "
- "%i client sockets, connection dropped\n",
- UH_LIMIT_CLIENTS
- );
-
- close(new_fd);
- }
- }
- }
-
- /* is a client socket */
- else
- {
- if( ! (cl = uh_client_lookup(cur_fd)) )
- {
- /* this should not happen! */
- fprintf(stderr,
- "uh_client_lookup(): No entry for fd %i!\n",
- cur_fd);
-
- goto cleanup;
- }
-
- /* parse message header */
- if( (req = uh_http_header_recv(cl)) != NULL )
- {
- /* RFC1918 filtering required? */
- if( conf.rfc1918_filter && sa_rfc1918(&cl->peeraddr) &&
- !sa_rfc1918(&cl->servaddr) )
- {
- uh_http_sendhf(cl, 403, "Forbidden",
- "Rejected request from RFC1918 IP to public server address");
- }
- else
-#ifdef HAVE_LUA
- /* Lua request? */
- if( L && uh_path_match(conf.lua_prefix, req->url) )
- {
- conf.lua_request(cl, req, L);
- }
- else
-#endif
- /* dispatch request */
- if( (pin = uh_path_lookup(cl, req->url)) != NULL )
- {
- /* auth ok? */
- if( uh_auth_check(cl, req, pin) )
- {
-#ifdef HAVE_CGI
- if( uh_path_match(conf.cgi_prefix, pin->name) )
- {
- uh_cgi_request(cl, req, pin);
- }
- else
-#endif
- {
- uh_file_request(cl, req, pin);
- }
- }
- }
-
- /* 404 */
- else
- {
- /* Try to invoke an error handler */
- pin = uh_path_lookup(cl, conf.error_handler);
-
- if( pin && uh_auth_check(cl, req, pin) )
- {
- req->redirect_status = 404;
-
-#ifdef HAVE_CGI
- if( uh_path_match(conf.cgi_prefix, pin->name) )
- {
- uh_cgi_request(cl, req, pin);
- }
- else
-#endif
- {
- uh_file_request(cl, req, pin);
- }
- }
- else
- {
- uh_http_sendhf(cl, 404, "Not Found",
- "No such file or directory");
- }
- }
- }
-
- /* 400 */
- else
- {
- uh_http_sendhf(cl, 400, "Bad Request",
- "Malformed request received");
- }
-
-#ifdef HAVE_TLS
- /* free client tls context */
- if( conf.tls )
- conf.tls_close(cl);
-#endif
-
- cleanup:
-
- /* close client socket */
- close(cur_fd);
- FD_CLR(cur_fd, &used_fds);
-
- /* remove from global client list */
- uh_client_remove(cur_fd);
- }
- }
- }
- }