コード例 #1
0
void process_requests(void)
{
	int retval = 0;
	request *current, *trailer;

	current = request_ready;

	while (current) {
#ifdef CRASHDEBUG
		crashdebug_current = current;
#endif		
		if (current->buffer_end) {
			req_flush(current);
			if (current->status == CLOSE)
				retval = 0;
			else
				retval = 1;
		} else {
			switch (current->status) {
			case READ_HEADER:
			case ONE_CR:
			case ONE_LF:
			case TWO_CR:
				retval = read_header(current);
				break;
			case BODY_READ:
				retval = read_body(current);
				break;
			case BODY_WRITE:
				retval = write_body(current);
				break;
			case WRITE:
				retval = process_get(current);
				break;
			case PIPE_READ:
				retval = read_from_pipe(current);
				break;
			case PIPE_WRITE:
				retval = write_from_pipe(current);
				break;
			default:
				retval = 0;
#if 0
				fprintf(stderr, "Unknown status (%d), closing!\n",
						current->status);
#endif
				break;
			}
		}
		
		if (lame_duck_mode)
			SQUASH_KA(current);

		switch (retval) {
		case -1:				/* request blocked */
			trailer = current;
			current = current->next;
			block_request(trailer);
			break;
		default:			/* everything else means an error, jump ship */
			send_r_error(current);
			/* fall-through */
		case 0:				/* request complete */
			trailer = current;
			current = current->next;
			free_request(&request_ready, trailer);
			break;
		case 1:				/* more to do */
			current->time_last = time_counter;
			current = current->next;
			break;
		}
	}
#ifdef CRASHDEBUG
		crashdebug_current = current;
#endif
}
コード例 #2
0
ファイル: request.c プロジェクト: pretendchang/IoTGateway
void process_requests(int server_sock)
{
    int retval = 0;
    request *current, *trailer;

    if (pending_requests) {
        get_request(server_sock);
#ifdef ORIGINAL_BEHAVIOR
        pending_requests = 0;
#endif
    }

    current = request_ready;

    while (current) {
        time(&current_time);
        retval = 1;             /* emulate "success" in case we don't have to flush */

        if (current->buffer_end && /* there is data in the buffer */
            current->status < TIMED_OUT) {
            retval = req_flush(current);
            /*
             * retval can be -2=error, -1=blocked, or bytes left
             */
            if (retval == -2) { /* error */
                current->status = DEAD;
                retval = 0;
            } else if (retval >= 0) {
                /* notice the >= which is different from below?
                   Here, we may just be flushing headers.
                   We don't want to return 0 because we are not DONE
                   or DEAD */
                retval = 1;
            }
        }

        if (retval == 1) {
            switch (current->status) {
            case READ_HEADER:
            case ONE_CR:
            case ONE_LF:
            case TWO_CR:
                retval = read_header(current);
                break;
            case BODY_READ:
                retval = read_body(current);
                break;
            case BODY_WRITE:
                retval = write_body(current);
                break;
            case WRITE:
                retval = process_get(current);
                break;
            case PIPE_READ:
                retval = read_from_pipe(current);
                break;
            case PIPE_WRITE:
                retval = write_from_pipe(current);
                break;
            case IOSHUFFLE:
#ifdef HAVE_SENDFILE
                retval = io_shuffle_sendfile(current);
#else
                retval = io_shuffle(current);
#endif
                break;
            case DONE:
                /* a non-status that will terminate the request */
                retval = req_flush(current);
                /*
                 * retval can be -2=error, -1=blocked, or bytes left
                 */
                if (retval == -2) { /* error */
                    current->status = DEAD;
                    retval = 0;
                } else if (retval > 0) {
                    retval = 1;
                }
                break;
            case TIMED_OUT:
            case DEAD:
                retval = 0;
                current->buffer_end = 0;
                SQUASH_KA(current);
                break;
            default:
                retval = 0;
                fprintf(stderr, "Unknown status (%d), "
                        "closing!\n", current->status);
                current->status = DEAD;
                break;
            }

        }

        if (sigterm_flag)
        {
          SQUASH_KA(current);
        }

        /* we put this here instead of after the switch so that
         * if we are on the last request, and get_request is successful,
         * current->next is valid!
         */
        if (pending_requests)
            get_request(server_sock);

        switch (retval) {
        case -1:               /* request blocked */
            trailer = current;
            current = current->next;
            block_request(trailer);
            break;
        case 0:                /* request complete */
            current->time_last = current_time;
            trailer = current;
            current = current->next;
            free_request(trailer);
            break;
        case 1:                /* more to do */
            current->time_last = current_time;
            current = current->next;
            break;
        default:
            log_error_doc(current);
            fprintf(stderr, "Unknown retval in process.c - "
                    "Status: %d, retval: %d\n", current->status, retval);
            current->status = DEAD;
            current = current->next;
            break;
        }
    }
}
コード例 #3
0
void free_request(request ** list_head_addr, request * req)
{
	if (req->buffer_end)
		return;

	dequeue(list_head_addr, req);	/* dequeue from ready or block list */

	if (req->buffer_end)
		FD_CLR(req->fd, &block_write_fdset);
	else {
		switch (req->status) {
		case PIPE_WRITE:
		case WRITE:
			FD_CLR(req->fd, &block_write_fdset);
			break;
		case PIPE_READ:
			FD_CLR(req->data_fd, &block_read_fdset);
			break;
		case BODY_WRITE:
			FD_CLR(req->post_data_fd, &block_write_fdset);
			break;
		default:
			FD_CLR(req->fd, &block_read_fdset);
		}
	}

	if (req->logline)			/* access log */
		log_access(req);

	if (req->data_mem)
		munmap(req->data_mem, req->filesize);
	
	if (req->data_fd)
		close(req->data_fd);
	
	if (req->response_status >= 400)
		status.errors++;

	if ((req->keepalive == KA_ACTIVE) &&
		(req->response_status < 400) &&
		(++req->kacount < ka_max)) {

		request *conn;

		conn = new_request();
		conn->fd = req->fd;
		conn->status = READ_HEADER;
		conn->header_line = conn->client_stream;
		conn->time_last = time_counter;
		conn->kacount = req->kacount;
#ifdef SERVER_SSL
		conn->ssl = req->ssl; /*MN*/
#endif /*SERVER_SSL*/
		
		/* we don't need to reset the fd parms for conn->fd because
		   we already did that for req */
		/* for log file and possible use by CGI programs */
		
		strcpy(conn->remote_ip_addr, req->remote_ip_addr);

		/* for possible use by CGI programs */
		conn->remote_port = req->remote_port;
		
		if (req->local_ip_addr)
			conn->local_ip_addr = strdup(req->local_ip_addr);

		status.requests++;
		
		if (conn->kacount + 1 == ka_max)
			SQUASH_KA(conn);
				
		conn->pipeline_start = req->client_stream_pos - 
								req->pipeline_start;
		
		if (conn->pipeline_start) {
			memcpy(conn->client_stream,
				req->client_stream + req->pipeline_start,
				conn->pipeline_start);			
			enqueue(&request_ready, conn);				
		} else
			block_request(conn);
	} else{
		if (req->fd != -1) {
			status.connections--;
			safe_close(req->fd);
		}
		req->fd = -1;
#ifdef SERVER_SSL
		SSL_free(req->ssl);
#endif /*SERVER_SSL*/
	}

	if (req->cgi_env) {
		int i = COMMON_CGI_VARS;
		req->cgi_env[req->cgi_env_index]=0;
		while (req->cgi_env[i])
		{
			free(req->cgi_env[i++]);
		}
		free(req->cgi_env);
	}
	if (req->pathname)
		free(req->pathname);
	if (req->path_info)
		free(req->path_info);
	if (req->path_translated)
		free(req->path_translated);
	if (req->script_name)
		free(req->script_name);
	if (req->query_string)
		free(req->query_string);
	if (req->local_ip_addr)
		free(req->local_ip_addr);
/*
 *	need to clean up if anything went wrong
 */
	if (req->post_file_name) {
		unlink(req->post_file_name);
		free(req->post_file_name);
		close(req->post_data_fd);
		req->post_data_fd = -1;
		req->post_file_name = NULL;
	}

	enqueue(&request_free, req);	/* put request on the free list */

	return;
}
コード例 #4
0
ファイル: request.c プロジェクト: dulton/boa_onvif
void process_requests(int server_s, struct soap *soap)/*by SeanHou*/
{
    /* :TODO:Monday, December 01, 2014 11:17:36 HKT:SeanHou:  */
    int OnvifEN = 0;
    int lookupindex = 0;
    char service_uri[100] = "";

    memset((void*)&soap->peer, 0, sizeof(soap->peer));
    soap->socket = SOAP_INVALID_SOCKET;
    soap->error  = SOAP_OK;
    soap->errmode = 0;
    soap->keep_alive = 0;

    fprintf(stderr, "Warning:" \
            "(==>%s).\n", __func__);

    /* :TODO:End---  */
    int retval = 0;
    request *current, *trailer;

    if (pending_requests) {
        get_request(server_s);
#ifdef ORIGINAL_BEHAVIOR
        pending_requests = 0;
#endif
    }

    current = request_ready;

    while (current) {
        /* :TODO:Monday, December 01, 2014 11:18:42 HKT:SeanHou: juge is onvif */
        OnvifEN = isonvif(current->client_stream, service_uri, &lookupindex);
        if(OnvifEN == 1)
        {
            fprintf(stderr, "[boa:onvif] Warning: is onvif line[%d]remote port[%d]h2ns[%d]remote ip[%s]\n", __LINE__, current->remote_port, htons(current->remote_port), current->remote_ip_addr);
            struct sockaddr_in onvif_client_addr;
            memset(&onvif_client_addr, 0, sizeof(onvif_client_addr));
            onvif_client_addr.sin_family = AF_INET;
            onvif_client_addr.sin_port = htons(current->remote_port);//随机端口
            onvif_client_addr.sin_addr.s_addr = inet_addr(current->remote_ip_addr);//

            soap->socket = current->fd;
            soap->peer = onvif_client_addr;
            if (soap_valid_socket(soap->socket))
            {
                soap->ip = ntohl(soap->peer.sin_addr.s_addr);
                soap->port = (int)ntohs(soap->peer.sin_port);
                soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
            }


            g_onvif_buffer = (char *)soap_malloc(soap, sizeof(current->client_stream));
            strcpy(g_onvif_buffer, current->client_stream);//mark

            soap_begin_recv(soap);
            if (soap_envelope_begin_in(soap))
            {
                soap_send_fault(soap);
            }
            if (soap_recv_header(soap))
            {
                soap_send_fault(soap);
            }
            if (soap_body_begin_in(soap))
            {
                soap_send_fault(soap);
            }

            int errorCode = 0;
            if (errorCode = soap_serve_request(soap))
            {
                fprintf(stderr, "[boa:onvif]soap_serve_request fail, errorCode %d \n", errorCode);
                soap_send_fault(soap);
            }

            memset(current->client_stream, 0, CLIENT_STREAM_SIZE );

            soap_dealloc(soap, NULL);
            soap_destroy(soap);      
            soap_end(soap);
            current->status = DONE;
            close(soap->socket);
            continue;
        }
        /* :TODO:End---  */
        time(&current_time);
        if (current->buffer_end && /* there is data in the buffer */
                current->status != DEAD && current->status != DONE) {
            retval = req_flush(current);
            /*
             * retval can be -2=error, -1=blocked, or bytes left
             */
            if (retval == -2) { /* error */
                current->status = DEAD;
                retval = 0;
            } else if (retval >= 0) {
                /* notice the >= which is different from below?
                   Here, we may just be flushing headers.
                   We don't want to return 0 because we are not DONE
                   or DEAD */

                retval = 1;
            }
        } else {
            switch (current->status) {
                case READ_HEADER:
                case ONE_CR:
                case ONE_LF:
                case TWO_CR:
                    retval = read_header(current);
                    break;
                case BODY_READ:
                    retval = read_body(current);
                    break;
                case BODY_WRITE:
                    retval = write_body(current);
                    break;
                case WRITE:
                    retval = process_get(current);
                    break;
                case PIPE_READ:
                    retval = read_from_pipe(current);
                    break;
                case PIPE_WRITE:
                    retval = write_from_pipe(current);
                    break;
                case DONE:
                    /* a non-status that will terminate the request */
                    retval = req_flush(current);
                    /*
                     * retval can be -2=error, -1=blocked, or bytes left
                     */
                    if (retval == -2) { /* error */
                        current->status = DEAD;
                        retval = 0;
                    } else if (retval > 0) {
                        retval = 1;
                    }
                    break;
                case DEAD:
                    retval = 0;
                    current->buffer_end = 0;
                    SQUASH_KA(current);
                    break;
                default:
                    retval = 0;
                    fprintf(stderr, "Unknown status (%d), "
                            "closing!\n", current->status);
                    current->status = DEAD;
                    break;
            }

        }

        if (sigterm_flag)
            SQUASH_KA(current);

        /* we put this here instead of after the switch so that
         * if we are on the last request, and get_request is successful,
         * current->next is valid!
         */
        if (pending_requests)
            get_request(server_s);

        switch (retval) {
            case -1:               /* request blocked */
                trailer = current;
                current = current->next;
                block_request(trailer);
                break;
            case 0:                /* request complete */
                current->time_last = current_time;
                trailer = current;
                current = current->next;
                free_request(&request_ready, trailer);
                break;
            case 1:                /* more to do */
                current->time_last = current_time;
                current = current->next;
                break;
            default:
                log_error_time();
                fprintf(stderr, "Unknown retval in process.c - "
                        "Status: %d, retval: %d\n", current->status, retval);
                current = current->next;
                break;
        }
    }
}