Example #1
0
ast_base * read_if_statement(grammar * g)
{
	ast_base * root = NULL;
	ast_base * expression = NULL;
	ast_base * i_body = NULL;
	ast_base * e_body = NULL;
	token_base * token = NULL;

	token = next(g->l);
	if (token->type != T_OPAR)
	{
		return NULL;
	}
	free_token_opar((token_opar *)token);

	expression = read_boolean_expression(g);
	i_body = read_body(g);

	token = next(g->l);
	if (token->type == T_ELSE) {
		free_token_else((token_else *)token);
		e_body = read_body(g);
	}
	else
	{
		push_back(g->l, token);
	}

	root = (ast_base *) malloc(sizeof(node_if));
	init_node_if((node_if *)root, expression, i_body, e_body);
	return root;
}
Example #2
0
void OpenDocument::read_xml(QString fichier){
    //Comptage des <p>
    p_total = (fichier.count("text:p")/2); // /2 parce qu'on ne compte pas la fermeture
    p_current = 0;

    //Initialisation des variables utiles pour la fonction
    //QString fichier_html;

    QDomDocument *dom = new QDomDocument();
    dom->setContent(fichier);

    QDomElement e = dom->documentElement();
    QDomElement content_styles = e.firstChildElement("office:automatic-styles");

    //On lit les styles
    read_styles(content_styles);

    //On lit le contenu
    QDomElement content_body = e.firstChildElement("office:body");
    QDomElement content_text = content_body.firstChildElement("office:text");
    read_body(content_text);

    //Renvoi du XML traité
    //return fichier_html;
    return;
}
Example #3
0
void CTcpSocketBase::handler_read_body(const boost::system::error_code& error, std::size_t bytes_transferred,int offset) {
	if (!error) {
		int curr_offset = offset + (int)bytes_transferred;
		if (curr_offset < (int)msgRecv.bodylen()) {
			read_body(curr_offset);
		}else {
			msgParse(msgRecv.head(),msgRecv.alllen());
			read_head(0);
		}
	}else {
		delete_self(error);
	}
}
int read_body__(int * id, double * t, double * m,
	      double r[3], double v[3])
{
    body_t *b;
    b = read_body(&parser);
    *id = b->id;
    *t = b->t;
    *m = b->m;
    int k;
    for(k=0;k<3;k++)r[k] = b->r[k];
    for(k=0;k<3;k++)v[k] = b->v[k];
    return 0;
}
Example #5
0
void CTcpSocketBase::handler_read_head(const boost::system::error_code& error, std::size_t bytes_transferred,int offset){
	if (!error) {
		int curr_offset = offset + (int)bytes_transferred; 
		if (curr_offset < (int)msgRecv.headlen()) {
			read_head(curr_offset);
		}else {
			read_body(0);
		}
	}
	else {
		//g_logger.info("read_head socket = [%08x] error = [%s]",this,error.message().c_str());
		delete_self(error);
	}
}
Example #6
0
ast_base * read_function_ast_node(grammar * g)
{
	ast_base * root = NULL;
	ast_base * body = NULL;
	token_base * token = NULL;
	token_function * function_name = NULL;

	token = next(g->l);
	if (token->type != T_INT_TYPE)
	{
		return NULL;
	}
	free_token_int_type((token_int_type *)token);

	token = next(g->l);
	if (token->type != T_FUNCTION)
	{
		return NULL;
	}
	function_name = (token_function *) token;

	token = next(g->l);
	if (token->type != T_OPAR)
	{
		return NULL;
	}
	free_token_opar((token_opar *)token);

	token = next(g->l);
	if (token->type != T_CPAR)
	{
		return NULL;
	}
	free_token_cpar((token_cpar *)token);

	body = read_body(g);
	root = (ast_base *) malloc(sizeof(node_function));

	init_node_function((node_function *)root, function_name->name, body);
	free_token_function(function_name);
	return root;
}
Example #7
0
  void connection::on_body_read( const boost::system::error_code& error, std::size_t bytes_transferred)
  {
    if (error) {
      return stop();
    }

    cancel_timeout();

    bufsz_ += bytes_transferred;

    inbound_.append_body(bodybuf_.data(), bodybuf_.data() + bytes_transferred);
    // handler_.handle_chunk(string_t(bodybuf_.data()));

    // if we read enough bytes as specified in the Content-Length header, process body
    if (bufsz_ >= inbound_.content_length)
    {
      return on_request_read();
    }

    return read_body();
  }
Example #8
0
File: wpl.c Project: J861449197/vlc
static int Demux( demux_t* p_demux )
{
    const char* psz_name;
    int i_type;

    demux_sys_t* p_sys = p_demux->p_sys;
    input_item_t* p_input = GetCurrentItem( p_demux );
    input_item_node_t* p_node = input_item_node_Create( p_input );
    p_sys->psz_prefix = FindPrefix( p_demux );

    do
    {
        i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name );
        if ( i_type == XML_READER_STARTELEM && !strcasecmp( psz_name, "head" ) )
            read_head( p_demux, p_input );
        else if ( i_type == XML_READER_STARTELEM && !strcasecmp( psz_name, "body" ) )
            read_body( p_demux, p_node );
    } while (i_type != XML_READER_ENDELEM || strcasecmp( psz_name, "smil" ) );

    input_item_node_PostAndDelete( p_node );
    input_item_Release( p_input );
    return 0;
}
Example #9
0
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;
        }
    }
}
bool http_connection::loop(unsigned fd)
{
	socket_wrapper::io_vector io_vector[2];
	size_t total = 0;
	size_t count;
	bool ret;

	do {
		logger::instance().log(logger::LOG_DEBUG, "[http_connection::loop] (fd %d) State = %s.", fd, state_to_string(_M_state));

		switch (_M_state) {
			case BEGIN_REQUEST_STATE:
				if ((!_M_readable) && (_M_inp == (off_t) _M_in.count())) {
					return true;
				}

				if (!read_request_line(fd, total)) {
					return false;
				}

				break;
			case READING_HEADERS_STATE:
				if (!_M_readable) {
					return true;
				}

				if (!read_headers(fd, total)) {
					return false;
				}

				break;
			case PROCESSING_REQUEST_STATE:
				if (!process_request(fd)) {
					return false;
				}

				if (_M_error != http_error::OK) {
					total = 0;

					_M_state = PREPARING_ERROR_PAGE_STATE;
				} else {
					if ((_M_state != PREPARING_HTTP_REQUEST_STATE) && (_M_state != READING_BODY_STATE) && (_M_state != READING_CHUNKED_BODY_STATE)) {
						if (!modify(fd, tcp_server::WRITE)) {
							return false;
						}

						total = 0;
					}
				}

				break;
			case READING_BODY_STATE:
				if (!_M_readable) {
					return true;
				}

				if (!read_body(fd, total)) {
					return false;
				}

				break;
			case READING_CHUNKED_BODY_STATE:
				if (!_M_readable) {
					return true;
				}

				if (!read_chunked_body(fd, total)) {
					return false;
				}

				break;
			case PREPARING_HTTP_REQUEST_STATE:
				if (!prepare_http_request(fd)) {
					_M_state = PREPARING_ERROR_PAGE_STATE;
				} else {
					_M_state = WAITING_FOR_BACKEND_STATE;
				}

				break;
			case WAITING_FOR_BACKEND_STATE:
				return true;
			case PREPARING_ERROR_PAGE_STATE:
				if ((!prepare_error_page()) || (!modify(fd, tcp_server::WRITE))) {
					return false;
				}

				break;
			case SENDING_TWO_BUFFERS_STATE:
				if (!_M_writable) {
					return true;
				}

				io_vector[0].iov_base = _M_out.data();
				io_vector[0].iov_len = _M_out.count();

				io_vector[1].iov_base = _M_bodyp->data();
				io_vector[1].iov_len = _M_bodyp->count();

				if (!writev(fd, io_vector, 2, total)) {
					return false;
				} else if (_M_outp == (off_t) (_M_out.count() + _M_bodyp->count())) {
					_M_state = REQUEST_COMPLETED_STATE;
				}

				break;
			case SENDING_HEADERS_STATE:
				if (!_M_writable) {
					return true;
				}

				if (!write(fd, total)) {
					return false;
				} else if (_M_outp == (off_t) _M_out.count()) {
					if (_M_method == http_method::HEAD) {
						_M_state = REQUEST_COMPLETED_STATE;
					} else if (_M_error != http_error::OK) {
						_M_state = REQUEST_COMPLETED_STATE;
					} else if (_M_filesize == 0) {
						_M_state = REQUEST_COMPLETED_STATE;
					} else {
						if (_M_ranges.count() == 0) {
							_M_outp = 0;
						} else {
							const range_list::range* range = _M_ranges.get(0);
							_M_outp = range->from;
						}

						_M_state = SENDING_BODY_STATE;
					}
				}

				break;
			case SENDING_BODY_STATE:
				if (!_M_writable) {
					return true;
				}

				if (!sendfile(fd, _M_fd, _M_filesize, &_M_ranges, _M_nrange, total)) {
					return false;
				} else {
					size_t nranges = _M_ranges.count();

					if (nranges == 0) {
						if (_M_outp == _M_filesize) {
							socket_wrapper::uncork(fd);

							_M_state = REQUEST_COMPLETED_STATE;
						}
					} else {
						const range_list::range* range = _M_ranges.get(_M_nrange);
						if (_M_outp == range->to + 1) {
							if (nranges == 1) {
								socket_wrapper::uncork(fd);

								_M_state = REQUEST_COMPLETED_STATE;
							} else {
								_M_out.reset();

								// Last part?
								if (++_M_nrange == nranges) {
									if (!_M_out.format("\r\n--%0*u--\r\n", http_headers::BOUNDARY_WIDTH, _M_boundary)) {
										return false;
									}

									_M_state = SENDING_MULTIPART_FOOTER_STATE;
								} else {
									if (!build_part_header()) {
										return false;
									}

									_M_state = SENDING_PART_HEADER_STATE;
								}

								_M_outp = 0;
							}
						}
					}
				}

				break;
			case SENDING_PART_HEADER_STATE:
				if (!_M_writable) {
					return true;
				}

				if (!write(fd, total)) {
					return false;
				} else if (_M_outp == (off_t) _M_out.count()) {
					const range_list::range* range = _M_ranges.get(_M_nrange);
					_M_outp = range->from;

					_M_state = SENDING_BODY_STATE;
				}

				break;
			case SENDING_MULTIPART_FOOTER_STATE:
				if (!_M_writable) {
					return true;
				}

				if (!write(fd, total)) {
					return false;
				} else if (_M_outp == (off_t) _M_out.count()) {
					socket_wrapper::uncork(fd);

					_M_state = REQUEST_COMPLETED_STATE;
				}

				break;
			case SENDING_BACKEND_HEADERS_STATE:
				if (!_M_writable) {
					return true;
				}

				if ((!_M_payload_in_memory) || (_M_filesize == 0) || (_M_method == http_method::HEAD)) {
					count = _M_out.count();

					ret = write(fd, total);
				} else {
					io_vector[0].iov_base = _M_out.data();
					io_vector[0].iov_len = _M_out.count();

					if (_M_error == http_error::OK) {
						io_vector[1].iov_base = _M_body.data() + _M_backend_response_header_size;
					} else {
						io_vector[1].iov_base = _M_bodyp->data();
					}

					io_vector[1].iov_len = _M_filesize;

					count = io_vector[0].iov_len + io_vector[1].iov_len;

					ret = writev(fd, io_vector, 2, total);
				}

				if (!ret) {
					return false;
				} else if (_M_outp == (off_t) count) {
					if (_M_payload_in_memory) {
						_M_state = REQUEST_COMPLETED_STATE;
					} else {
						_M_outp = 0;

						_M_state = SENDING_BACKEND_BODY_STATE;
					}
				}

				break;
			case SENDING_BACKEND_BODY_STATE:
				if (!_M_writable) {
					return true;
				}

				if (!sendfile(fd, _M_tmpfile, _M_filesize, total)) {
					return false;
				} else if (_M_outp == _M_filesize) {
					socket_wrapper::uncork(fd);

					_M_state = REQUEST_COMPLETED_STATE;
				}

				break;
			case REQUEST_COMPLETED_STATE:
				if ((_M_vhost) && (_M_vhost->log_requests)) {
					_M_vhost->log->log(*this, fd);
				}

				// Close connection?
				if (!_M_keep_alive) {
					return false;
				} else {
					if (!modify(fd, tcp_server::READ)) {
						return false;
					}

					reset();

					// If there is more data in the input buffer...
					size_t left = _M_in.count() - _M_inp;
					if (left > 0) {
						// Move data at the beginning of the buffer.
						char* data = _M_in.data();
						memmove(data, data + _M_inp, left);
						_M_in.set_count(left);
					} else {
						_M_in.reset();
					}

					_M_inp = 0;
				}

				break;
		}
	} while (!_M_in_ready_list);

	return true;
}
Example #11
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
}
Example #12
0
// Parses an '302' response
// @param reference a pointer to the beginning of the message
// @param response a pointer to the current location in parsing
// @param status the status of the message
// @param message the message of the message
// @return 1 if the parse was succesful, -1 otherwise
static int parse_302(char **reference, char **response, char **status,
                     char **message, csv_record **response_list) {
    
    char* key;      // The key of the header
    char *length;   // The length of the body of the response
    
    *message = strdup(read_message(response));
    
    key = read_key(response);
    
    // Store the length
    if (strcmp(key, KEY_LENGTH) == 0) {
        
        length = strdup(read_value(response));
        
    } //end if
    
    // The 'Length' key is missing
    else {
        
        syslog(LOG_DEBUG, "Expected key 'Length', got '%s'. Invalid protocol.", key);
        
        free(*status);
        free(*message);
        free(*reference);
        
        *status = NULL;
        *message = NULL;
        *reference = NULL;
        
        return -1;
        
    } //end else
    
    key = read_key(response);
    
    // Expecting an empty string between two newlines
    if (strcmp(key, "") == 0) {
        
        *response_list = read_body(response);
        
        // Completed parsing the message
        if (*response_list != NULL) {
            
            free(length);
            free(*reference);
            
            length = NULL;
            *reference = NULL;
            
            return 1;
            
        } //end if
        
        // Completed parsing the message (Length listed as 0)
        else if (*response_list == NULL && atoi(length) == 0) {
            
            free(length);
            free(*reference);
            
            length = NULL;
            *reference = NULL;
            
            return 1;
            
        } //end else if
        
        // The body of the response is missing
        else {
            
            syslog(LOG_DEBUG, "Expected body of length '%s', got '%s'. Invalid protocol.",
                   length, *response);
            
            free(*status);
            free(*message);
            free(length);
            free(*reference);
            
            *status = NULL;
            *message = NULL;
            length = NULL;
            *reference = NULL;
            
            return -1;
            
        } //end else
        
    } //end if
    
    // Found something extra
    else {
        
        syslog(LOG_DEBUG, "Expected empty key, got '%s'. Invalid protocol.", key);
        
        free(*status);
        free(*message);
        free(length);
        free(*reference);
        
        *status = NULL;
        *message = NULL;
        length = NULL;
        *reference = NULL;
        
        return -1;
        
    } //end else
    
} //end parse_302
bool proxy_connection::loop(unsigned fd)
{
	size_t total = 0;
	size_t count;
	int error;
	bool ret;

	do {
		logger::instance().log(logger::LOG_DEBUG, "[proxy_connection::loop] (fd %d) State = %s.", fd, state_to_string(_M_state));

		switch (_M_state) {
			case CONNECTING_STATE:
				if (!_M_client) {
					return false;
				}

				if ((!socket_wrapper::get_socket_error(fd, error)) || (error)) {
					logger::instance().log(logger::LOG_WARNING, "(fd %d) Connection to backend failed with error: %d.", fd, error);

#if !PROXY
					_M_client->_M_rule->backends.connection_failed(fd);
#endif

					_M_client->_M_error = http_error::GATEWAY_TIMEOUT;
					_M_state = PREPARING_ERROR_PAGE_STATE;
				} else {
					if (!_M_client->_M_payload_in_memory) {
						socket_wrapper::cork(fd);
					}

					_M_state = SENDING_HEADERS_STATE;
				}

				break;
			case SENDING_HEADERS_STATE:
				if (!_M_writable) {
					return true;
				}

				if ((!_M_client->_M_payload_in_memory) || (_M_client->_M_request_body_size == 0)) {
					count = _M_out.count();

					ret = write(fd, total);
				} else {
					socket_wrapper::io_vector io_vector[2];

					io_vector[0].iov_base = _M_out.data();
					io_vector[0].iov_len = _M_out.count();

					io_vector[1].iov_base = _M_client->_M_in.data() + _M_client->_M_request_header_size;
					io_vector[1].iov_len = _M_client->_M_request_body_size;

					count = io_vector[0].iov_len + io_vector[1].iov_len;

					ret = writev(fd, io_vector, 2, total);
				}

				if (!ret) {
					_M_client->_M_error = http_error::GATEWAY_TIMEOUT;
					_M_state = PREPARING_ERROR_PAGE_STATE;
				} else {
					_M_client->_M_timestamp = now::_M_time;

					if (_M_outp == (off_t) count) {
						if (_M_client->_M_payload_in_memory) {
							if (!modify(fd, tcp_server::READ)) {
								_M_client->_M_error = http_error::INTERNAL_SERVER_ERROR;
								_M_state = PREPARING_ERROR_PAGE_STATE;
							} else {
								_M_client->_M_body.reset();

								_M_state = READING_STATUS_LINE_STATE;
							}
						} else {
							_M_outp = 0;

							_M_state = SENDING_BODY_STATE;
						}
					}
				}

				break;
			case SENDING_BODY_STATE:
				if (!_M_writable) {
					return true;
				}

				if (!sendfile(fd, _M_client->_M_tmpfile, _M_client->_M_request_body_size, total)) {
					_M_client->_M_error = http_error::GATEWAY_TIMEOUT;
					_M_state = PREPARING_ERROR_PAGE_STATE;
				} else {
					_M_client->_M_timestamp = now::_M_time;

					if (_M_outp == (off_t) _M_client->_M_request_body_size) {
						// We don't need the client's temporary file anymore.
						static_cast<http_server*>(_M_server)->_M_tmpfiles.close(_M_client->_M_tmpfile);
						_M_client->_M_tmpfile = -1;

						socket_wrapper::uncork(fd);

						if (!modify(fd, tcp_server::READ)) {
							_M_client->_M_error = http_error::INTERNAL_SERVER_ERROR;
							_M_state = PREPARING_ERROR_PAGE_STATE;
						} else {
							_M_client->_M_body.reset();

							_M_state = READING_STATUS_LINE_STATE;
						}
					}
				}

				break;
			case READING_STATUS_LINE_STATE:
				if (!_M_readable) {
					return true;
				}

				if (!read_status_line(fd, total)) {
					_M_state = PREPARING_ERROR_PAGE_STATE;
				}

				break;
			case READING_HEADERS_STATE:
				if (!_M_readable) {
					return true;
				}

				if (!read_headers(fd, total)) {
					_M_state = PREPARING_ERROR_PAGE_STATE;
				}

				break;
			case PROCESSING_RESPONSE_STATE:
				if (!process_response(fd)) {
					_M_state = PREPARING_ERROR_PAGE_STATE;
				}

				break;
			case READING_BODY_STATE:
				if (!_M_readable) {
					return true;
				}

				if (!read_body(fd, total)) {
					_M_state = PREPARING_ERROR_PAGE_STATE;
				}

				break;
			case READING_CHUNKED_BODY_STATE:
				if (!_M_readable) {
					return true;
				}

				if (!read_chunked_body(fd, total)) {
					_M_state = PREPARING_ERROR_PAGE_STATE;
				}

				break;
			case READING_UNKNOWN_SIZE_BODY_STATE:
				if (!_M_readable) {
					return true;
				}

				if (!read_unknown_size_body(fd, total)) {
					_M_state = PREPARING_ERROR_PAGE_STATE;
				}

				break;
			case PREPARING_ERROR_PAGE_STATE:
				if (!http_error::build_page(_M_client)) {
					return false;
				}

				_M_client->_M_response_header_size = _M_client->_M_out.count();

				if ((_M_client->_M_method == http_method::HEAD) || (_M_client->_M_bodyp->count() == 0)) {
					_M_client->_M_filesize = 0;
				} else {
					_M_client->_M_filesize = _M_client->_M_bodyp->count();
				}

				_M_client->_M_payload_in_memory = 1;

				_M_client->_M_in_ready_list = 1;

				_M_client->_M_state = http_connection::SENDING_BACKEND_HEADERS_STATE;

				return false;
			case RESPONSE_COMPLETED_STATE:
				if (!prepare_http_response(fd)) {
					_M_client->_M_error = http_error::INTERNAL_SERVER_ERROR;
					_M_state = PREPARING_ERROR_PAGE_STATE;
				} else {
					_M_client->_M_in_ready_list = 1;

					_M_client->_M_tmpfile = _M_tmpfile;
					_M_tmpfile = -1;

					_M_client->_M_state = http_connection::SENDING_BACKEND_HEADERS_STATE;

					if (!_M_client->_M_payload_in_memory) {
						socket_wrapper::cork(_M_fd);
					}

					return false;
				}

				break;
		}
	} while (!_M_in_ready_list);

	return true;
}
Example #14
0
bool http_client::body_gets(string& out, bool nonl /* = true */,
	size_t* size /* = NULL */)
{
	if (buf_ == NULL)
		buf_ = new string(4096);

	size_t len, size_saved = out.length();

	// 首先判断是否已经读完 HTTP 数据体
	if (body_finish_)
	{
		if (buf_->empty())
		{
			if (size)
				*size = 0;
			return false;
		}

		// 当读缓冲区数据非空时,先尝试从中获取一行数据
		if (buf_->scan_line(out, nonl, &len) == true)
		{
			if (size)
				*size = out.length() - size_saved;
			return true;
		}

		// 如果不能读到完整行数据且 HTTP 数据体读完的情况下则将读
		// 缓冲区内的数据都拷贝至目标缓冲区
		out.append(buf_);
		buf_->clear();

		if (size)
			*size = out.length() - size_saved;

		return true;
	}

	// 继续读 HTTP 数据体,并尝试从中读取一行数据

	len = 0;

	while (true)
	{
		if (!buf_->empty())
		{
			if (buf_->scan_line(out, nonl, &len) == true)
			{
				if (size)
					*size = out.length() - size_saved;
				return true;
			}

			// 为了减少下次循环时调用 scan_line 的字符串查找次数,
			// 将读缓冲区中的数据先拷贝至目标缓冲区中

			len += buf_->length();
			out.append(buf_);
			buf_->clear();
		}

		if (body_finish_)
		{
			if (size)
				*size = len;
			return len > 0 ? true : false;
		}

		if (read_body(*buf_, false) <= 0)
			body_finish_ = true;
		else
			body_finish_ = false;
	}
}
Example #15
0
/*
 * Helper function to send http request as a proxy
 * The headers from the original request will be copied (except for Host & sensitive headers)
 * and the body of the request will also be copied
 * The data will be set on response_data, content_size, response_headers
 * Unlike post_request_helper, response_data doesn't have to be free as it being allocated using apr
 * Returns CURLcode
 */
CURLcode redirect_helper(CURL* curl, const char *base_url, const char *uri, const char *vid, px_config *conf, request_rec *r, const char **response_data, apr_array_header_t **response_headers, int *content_size) {
    const char *url = apr_pstrcat(r->pool, base_url, uri, NULL);
    struct response_t response;
    struct curl_slist *headers = NULL;
    long status_code;
    char errbuf[CURL_ERROR_SIZE];
    errbuf[0] = 0;

    response.data = malloc(1);
    response.size = 0;
    response.headers = apr_array_make(r->pool, 0, sizeof(char*));
    response.r = r;
    response.server = r->server;

    // Prepare headers
    const apr_array_header_t *header_arr = apr_table_elts(r->headers_in);

    if (header_arr) {
        for (int i = 0; i < header_arr->nelts; i++) {
            apr_table_entry_t h = APR_ARRAY_IDX(header_arr, i, apr_table_entry_t);

            // Remove sensitive headers
            if (strcasecmp(h.key, "Host") == 0) {
                continue;
            }

            bool skip = false;
            for (int j = 0; j < conf->sensitive_header_keys->nelts; j++) {
                const char *s = APR_ARRAY_IDX(conf->sensitive_header_keys, j, char*);

                if (strcasecmp(h.key, s) == 0) {
                    skip = true;
                    break;
                }
            }

            if (skip) {
                continue;
            }

            headers = curl_slist_append(headers, apr_psprintf(r->pool, "%s: %s", h.key, h.val));
        }
    }

    // append vid cookie
    if (vid) {
        px_log_debug_fmt("attaching vid header 'Cookie: pxvid=%s'", vid);
        headers = curl_slist_append(headers, apr_psprintf(r->pool, "Cookie: pxvid=%s;", vid));
    }

    // Attach first party logics
    headers = curl_slist_append(headers, apr_psprintf(r->pool, "%s: %s", FIRST_PARTY_HEADER, FIRST_PARTY_HEADER_VALUE));
    headers = curl_slist_append(headers, apr_psprintf(r->pool, "%s: %s", ENFORCER_TRUE_IP, get_request_ip(r, conf)));

    const char *xff = apr_table_get(r->headers_in, "X-Forwarded-For");
    if (xff) {
        headers = curl_slist_append(headers, apr_psprintf(r->pool, "%s: %s,%s", "X-Forwarded-For", xff, r->useragent_ip));
    } else {
        headers = curl_slist_append(headers, apr_psprintf(r->pool, "%s: %s", "X-Forwarded-For", r->useragent_ip));
    }
    headers = curl_slist_append(headers, apr_psprintf(r->pool, "%s: %s", "Host", &base_url[8]));

    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_URL, url);

    // Case we have body
    char *body;
    int body_res = read_body(r, &body);
    if (body_res == 0 && strcmp(r->method, "POST") == 0) {
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
    }

    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, conf->connect_timeout_ms);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, conf->api_timeout_ms);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response_cb);
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*) &response);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void*) &response);
    if (conf->proxy_url) {
        curl_easy_setopt(curl, CURLOPT_PROXY, conf->proxy_url);
    }
    CURLcode status = curl_easy_perform(curl);
    curl_slist_free_all(headers);

    if (status == CURLE_OK) {
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status_code);
        px_log_debug_fmt("status: %lu, url: %s", status_code, url);
        if (status_code == HTTP_OK) {
            if (response_data != NULL) {
                *response_headers = response.headers;
                *response_data = apr_pstrmemdup(r->pool, response.data, response.size);
                *content_size = response.size;
            }
        } else {
            status = CURLE_HTTP_RETURNED_ERROR;
        }
    } else {
        update_and_notify_health_check(conf);
        size_t len = strlen(errbuf);
        if (len) {
            px_log_debug_fmt("failed: %s", errbuf);
        } else {
            px_log_debug_fmt("failed: %s", curl_easy_strerror(status));
        }
    }
    free(response.data);
    return status;
}
Example #16
0
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;
        }
    }
}
Example #17
0
 int request_parser::parse(request_parser::parsed_data& toFill) const
 {
   // Read boundary and body
   size_t boundaryLen, bodyLen;
   char* boundary,* body;
   boundary = get_boundary(boundaryLen);
   int httpCode = read_body(body, bodyLen);
   if (!boundary)
     return (HTTP_BAD_REQUEST);
   if ((OK) != httpCode)
     return httpCode;
   
   // Example of body starts with next three lines:
   //   -----------------------------75180758514773109461831266709 /*this is boundary*/
   //   Content-Disposition: form-data; name="fileToUpload"; filename="main.cpp" 
   //   Content-Type: text/x-c++src
   // To parse data we can skip first 'boundaryLen' bytes and then extract first line.
   // From that line we want to fetch value of filename. Next, we get to the last line
   // and move past it. Until we reach a new boundary we read all that data as a file data.
   
   // Skip boundary
   body += boundaryLen;
   while (*body == '\n' || *body == '\r') ++body;
   
   // Find file name attribute
   auto range = boost::ifind_first(body, "filename=\"");
   if (range.empty()) return (HTTP_BAD_REQUEST);
   
   // Initialize file name and size
   char* filename = range.end();
   get<FILE_NAME>(toFill) = filename;
   while (*filename != '\"') ++filename;
   get<FILE_NAME_LEN>(toFill) = static_cast<size_t>(filename - range.end());
   
   // Skip two lines (this line and Content-Type line)
   body = filename + 1;
   while (*body != '\n' && *body != '\r') ++body; // Move to the end of line
   while (*body == '\n' || *body == '\r') ++body; // Move to next line skipping new line chars (skipped FIRST line at the end)
   while (*body != '\n' && *body != '\r') ++body; // Move to the end of line
   while (*body == '\n' || *body == '\r') ++body; // Move to next line skipping new line chars (skipped TWO lines in total)
   
   // Find next boundary, that will be end of file. File begins at 'body'
   get<FILE_CONTENT>(toFill) = body;
   range = boost::find_first(body, boundary);
   get<FILE_CONTENT_LEN>(toFill) = range.begin() - get<FILE_CONTENT>(toFill);
   
   // Move to the next line
   body = range.end();
   while (*body == '\n' || *body == '\r') ++body;
   
   // Skip 2 lines
   while (*body != '\n' && *body != '\r') ++body; // Move to the end of line
   while (*body == '\n' || *body == '\r') ++body; // Move to next line skipping new line chars (skipped FIRST line at the end)
   while (*body != '\n' && *body != '\r') ++body; // Move to the end of line
   while (*body == '\n' || *body == '\r') ++body; // Move to next line skipping new line chars (skipped TWO lines in total)
   
   // Find next boundary, content of tests.xml begins at 'body'
   get<TESTS_CONTENT>(toFill) = body;
   range = boost::find_first(body, boundary);
   get<TESTS_CONTENT_LEN>(toFill) = range.begin() - get<TESTS_CONTENT>(toFill);
   return 0;
 }
Example #18
0
/*
 Load a new strip of pixel data into the buffer.
 */
void *loadstrip(picstruct *field)

{
	tabstruct *tab;
	checkstruct *check;
	int y, w, flags, interpflag;
	PIXTYPE *data, *wdata, *rmsdata;

	tab = field->tab;
	w = field->width;
	flags = field->flags;
	interpflag = 0; //(wfield && wfield->interp_flag);
	wdata = NULL; /* To avoid gcc -Wall warnings */

	if (!field->y)
	{
		/*- First strip */
		int nbpix;

		nbpix = w * field->stripheight;

		if (flags ^ FLAG_FIELD) {

			/*---- Allocate space for the frame-buffer */
			/*
			if (!(field->strip = (PIXTYPE *) malloc(
					field->stripheight * field->width * sizeof(PIXTYPE))))
				error(EXIT_FAILURE,
						"Not enough memory for the image buffer of ",
						field->rfilename); */

			data = field->strip;
			/*---- We assume weight data have been read just before */
			/*
			if (interpflag)
				wdata = wfield->strip;
			if (flags & BACKRMS_FIELD)
				for (y = 0, rmsdata = data; y < field->stripheight;
						y++, rmsdata += w)
					backrmsline(field, y, rmsdata);
			else if (flags & INTERP_FIELD)
				copydata(field, 0, nbpix);
			else *///true

				//read_body(tab, data, nbpix);

			//flag is in DETECT_FIELD | MEASURE_FIELD
			//if (flags & (WEIGHT_FIELD | RMS_FIELD | BACKRMS_FIELD | VAR_FIELD)) //false
			//	weight_to_var(field, data, nbpix);

			if ((flags & MEASURE_FIELD)
					&& (check = prefs.check[CHECK_IDENTICAL]))	//false
				writecheck(check, data, nbpix);

			for (y = 0; y < field->stripheight; y++, data += w) {
				/*------ This is the only place where one can pick-up safely the current bkg */
				if (flags & (MEASURE_FIELD | DETECT_FIELD))
					subbackline(field, y, data);

				/*------ Go to interpolation process */
				/*
				if (interpflag) {
					interpolate(field, wfield, data, wdata);
					wdata += w;
				}*/
				/*------ Check-image stuff */
				if (prefs.check_flag) {		//false

					if (flags & MEASURE_FIELD) {
						if ((check = prefs.check[CHECK_BACKGROUND]))
							writecheck(check, field->backline, w);
						if ((check = prefs.check[CHECK_SUBTRACTED]))
							writecheck(check, data, w);
						if ((check = prefs.check[CHECK_APERTURES]))
							writecheck(check, data, w);
						if ((check = prefs.check[CHECK_SUBPSFPROTOS]))
							writecheck(check, data, w);
						if ((check = prefs.check[CHECK_SUBPCPROTOS]))
							writecheck(check, data, w);
						if ((check = prefs.check[CHECK_SUBPROFILES]))
							writecheck(check, data, w);
					}
					if ((flags & DETECT_FIELD) && (check =
							prefs.check[CHECK_BACKRMS])) {  //false

						backrmsline(field, y, (PIXTYPE *) check->pix);
						writecheck(check, (PIXTYPE*)(check->pix), w);
					}
				}
			}
		}
		else {
			if (!(field->fstrip = (FLAGTYPE *) malloc(
					field->stripheight * field->width * sizeof(FLAGTYPE))))
				error(EXIT_FAILURE, "Not enough memory for the flag buffer of ",
						field->rfilename);
			read_ibody(field->tab, field->fstrip, nbpix);
		}

		field->ymax = field->stripheight;

		if (field->ymax < field->height)
			field->stripysclim = field->stripheight - field->stripmargin;
	} else {

		/*- other strips */
		if (flags ^ FLAG_FIELD) {
			data = field->strip + field->stripylim * w;
			/*---- We assume weight data have been read just before */
			//if (interpflag)
			//	wdata = wfield->strip + field->stripylim * w;

			/*---- copy to Check-image the "oldest" line before it is replaced */
			if ((flags & MEASURE_FIELD) && (check =
					prefs.check[CHECK_SUBOBJECTS]))
				writecheck(check, data, w);

			if (flags & BACKRMS_FIELD)
				backrmsline(field, field->ymax, data);
			else if (flags & INTERP_FIELD)
				copydata(field, field->stripylim * w, w);
			else
				read_body(tab, data, w);

			//if (flags & (WEIGHT_FIELD | RMS_FIELD | BACKRMS_FIELD | VAR_FIELD))
			//	weight_to_var(field, data, w);

			if ((flags & MEASURE_FIELD)
					&& (check = prefs.check[CHECK_IDENTICAL]))
				writecheck(check, data, w);
			/*---- Interpolate and subtract the background at current line */
			if (flags & (MEASURE_FIELD | DETECT_FIELD))
				subbackline(field, field->ymax, data);

			//if (interpflag)
			//	interpolate(field, wfield, data, wdata);
			/*---- Check-image stuff */
			if (prefs.check_flag) {
				if (flags & MEASURE_FIELD) {
					if ((check = prefs.check[CHECK_BACKGROUND]))
						writecheck(check, field->backline, w);
					if ((check = prefs.check[CHECK_SUBTRACTED]))
						writecheck(check, data, w);
					if ((check = prefs.check[CHECK_APERTURES]))
						writecheck(check, data, w);
					if ((check = prefs.check[CHECK_SUBPSFPROTOS]))
						writecheck(check, data, w);
					if ((check = prefs.check[CHECK_SUBPCPROTOS]))
						writecheck(check, data, w);
					if ((check = prefs.check[CHECK_SUBPROFILES]))
						writecheck(check, data, w);
				}
				if ((flags & DETECT_FIELD) && (check =
						prefs.check[CHECK_BACKRMS])) {
					backrmsline(field, field->ymax, (PIXTYPE *) check->pix);
					writecheck(check, (PIXTYPE*)(check->pix), w);
				}
			}
		} else
			read_ibody(tab, field->fstrip + field->stripylim * w, w);

		field->stripylim = (++field->ymin) % field->stripheight;
		if ((++field->ymax) < field->height)
			field->stripysclim = (++field->stripysclim) % field->stripheight;
	}

	return (flags ^ FLAG_FIELD) ?
			(void *) (field->strip + field->stripy * w) :
			(void *) (field->fstrip + field->stripy * w);
}
Example #19
0
// Parses an 'List' request
// @param reference a pointer to the beginning of the message
// @param request a pointer to the current location in parsing
// @param command the command of the message
// @param token the client's token
// @return 1 if the parse was succesful, -1 otherwise
static int parse_list(char **reference, char **request, char **command, char **token,
                      csv_record **request_list) {
    
    char* key;      // The key of the header
    char *length;   // The length of the body
    
    key = read_key(request);
    
    // Store the token
    if (strcmp(key, KEY_TOKEN) == 0) {
        
        *token = strdup(read_value(request));
        
    } //end if
    
    // The 'Token' key is missing
    else {
        
        syslog(LOG_DEBUG, "Expected key 'Token', got '%s'. Invalid protocol.", key);
        
        free(*command);
        free(*reference);
        
        *command = NULL;
        *reference = NULL;
        
        return -1;
        
    } //end else
    
    key = read_key(request);
    
    // Store the length
    if (strcmp(key, KEY_LENGTH) == 0) {
        
        length = strdup(read_value(request));
        
    } //end if
    
    // The 'Length' key is missing
    else {
        
        syslog(LOG_DEBUG, "Expected key 'Length', got '%s'. Invalid protocol.", key);
        
        free(*command);
        free(*token);
        free(*reference);
        
        *command = NULL;
        *token = NULL;
        *reference = NULL;
        
        return -1;
        
    } //end else
    
    key = read_key(request);
    
    // Expecting an empty string between two newlines
    if (strcmp(key, "") == 0) {
        
        *request_list = read_body(request);
        
        // Completed parsing the message
        if (*request_list != NULL) {
            
            free(length);
            free(*reference);
            
            length = NULL;
            *reference = NULL;
            
            return 1;
            
        } //end if
        
        // The body of the request is missing
        else {
            
            syslog(LOG_DEBUG, "Expected body of length '%s', got '%s'. Invalid protocol.",
                   length, *request);
            
            free(*command);
            free(*token);
            free(length);
            free(*reference);
            
            *command = NULL;
            *token = NULL;
            length = NULL;
            *reference = NULL;
            
            return -1;
            
        } //end else
        
    } //end if
    
    // Found something extra
    else {
        
        syslog(LOG_DEBUG, "Expected empty key, got '%s'. Invalid protocol.", key);
        
        free(*command);
        free(*token);
        free(length);
        free(*reference);
        
        *command = NULL;
        *token = NULL;
        length = NULL;
        *reference = NULL;
        
        return -1;
        
    } //end else
    
} //end parse_list
Example #20
0
/* handle a file descriptor event */
int httpd_handle_event(fd_set *rset, fd_set *wset, fd_sets_t *fds)
{
   
    struct REQUEST      *req, *prev, *tmp;
    int                 length;
    int opt = 0;
   
    now = time(NULL);

    /* new connection ? */
    if ((rset != NULL) && FD_ISSET(slisten, rset)) {
        req = malloc(sizeof(struct REQUEST));
        if (NULL == req) {
            /* oom: let the request sit in the listen queue */
#ifdef DEBUG
            fprintf(stderr,"oom\n");
#endif
        } else {
            memset(req,0,sizeof(struct REQUEST));
            if ((req->fd = accept(slisten,NULL,&opt)) == -1) {
                if (EAGAIN != errno) {
                    log_error_func(1, LOG_WARNING,"accept",NULL);
                }
                free(req);
            } else {
                fcntl(req->fd,F_SETFL,O_NONBLOCK);
                req->bfd = -1;
                req->state = STATE_READ_HEADER;
                req->ping = now;
                req->lifespan = -1;
                req->next = conns;
                conns = req;
                curr_conn++;
#ifdef DEBUG
                fprintf(stderr,"%03d/%d: new request (%d)\n",req->fd,req->state,curr_conn);
#endif
#ifdef USE_SSL
                if (with_ssl) {
                    open_ssl_session(req);
                }
#endif
                length = sizeof(req->peer);
                if (getpeername(req->fd,(struct sockaddr*)&(req->peer),&length) == -1) {
                    log_error_func(1, LOG_WARNING,"getpeername",NULL);
                    req->state = STATE_CLOSE;
                }
                getnameinfo((struct sockaddr*)&req->peer,length,
                            req->peerhost,64,req->peerserv,8,
                            NI_NUMERICHOST | NI_NUMERICSERV);
#ifdef DEBUG
                fprintf(stderr,"%03d/%d: connect from (%s)\n",
                        req->fd,req->state,req->peerhost);
#endif

                /* host auth callback */
                if (access_check_func != NULL) {
                    if (access_check_func(req->peerhost, NULL) < 0) {
                        /* read request */
                        read_header(req,0);
                        req->ping = now;
                        /* reply with access denied and close connection */
                        mkerror(req,403,0);
                        write_request(req);	     
                        req->state = STATE_CLOSE;
                    }
                }
	 
                FD_SET(req->fd, &fds->rset); 
                if (req->fd > fds->max) {
                    fds->max = req->fd;
                }
            }
        }
    }
    
    /* check active connections */
    for (req = conns, prev = NULL; req != NULL;) {

        /* I/O */
        if ((rset != NULL) && FD_ISSET(req->fd, rset)) {
            if (req->state == STATE_KEEPALIVE) {
                req->state = STATE_READ_HEADER;
            }

            if (req->state == STATE_READ_HEADER) {
                while (read_header(req,0) > 0);
            }
          
            if (req->state == STATE_READ_BODY) {
                while (read_body(req, 0) >0);
            }
            
            req->ping = now;
        }
      
        if ((wset != NULL) && FD_ISSET(req->fd, wset)) {
            write_request(req);
            req->ping = now;
        }

        /* check timeouts */
        if (req->state == STATE_KEEPALIVE) {
            if (now > req->ping + keepalive_time ||
                curr_conn > max_conn * 9 / 10) {
#ifdef DEBUG
                fprintf(stderr,"%03d/%d: keepalive timeout\n",req->fd,req->state);
#endif
                req->state = STATE_CLOSE;
            }
        } else {
            if (now > req->ping + timeout) {
                if ((req->state == STATE_READ_HEADER) ||
                    (req->state == STATE_READ_BODY)) {
                    mkerror(req,408,0);
                } else {
                    log_error_func(0,LOG_INFO,"network timeout",req->peerhost);
                    req->state = STATE_CLOSE;
                }
            }
        }

        /* parsing */
      parsing:
      
        if (req->state == STATE_PARSE_HEADER) {
            parse_request(req, server_host);
        }

        /* body parsing */
        if (req->state == STATE_PARSE_BODY) {
            parse_request_body(req);
        }

        if (req->state == STATE_WRITE_HEADER) {
            /* switch to writing */
            FD_CLR(req->fd, &fds->rset);
            FD_SET(req->fd, &fds->wset);
            
            write_request(req);
        }
        

        /* handle finished requests */
        if (req->state == STATE_FINISHED && !req->keep_alive) {
            req->state = STATE_CLOSE;
        }
        if (req->state == STATE_FINISHED) {
            /* access log hook */
            if (log_request_func != NULL) {
                log_request_func(req, now);
            }

            /* switch to reading */
            FD_CLR(req->fd, &fds->wset);
            FD_SET(req->fd, &fds->rset);
            
            /* cleanup */
            req->auth[0]       = 0;
            req->if_modified   = 0;
            req->if_unmodified = 0;
            req->if_range      = 0;
            req->range_hdr     = NULL;
            req->ranges        = 0;
            if (req->r_start) { 
                free(req->r_start); 
                req->r_start = NULL; 
            }
            if (req->r_end) { 
                free(req->r_end);   
                req->r_end   = NULL; 
            }
            if (req->r_head) { 
                free(req->r_head);  
                req->r_head  = NULL; 
            }
            if (req->r_hlen) { 
                free(req->r_hlen);  
                req->r_hlen  = NULL; 
            }
            list_free(&req->header);
	
            if (req->bfd != -1) {
                close(req->bfd);
                req->bfd  = -1;
            }
	
            /* free memory of response body */
            if ((req->status<400) && (req->body != NULL)) {
                free(req->body);
                req->body = NULL;
            }
            req->written   = 0;
            req->head_only = 0;
            req->rh        = 0;
            req->rb        = 0;
            req->hostname[0] = 0;
            req->path[0]     = 0;
            req->query[0]    = 0;
            req->lifespan = -1;

            if (req->hdata == (req->lreq + req->lbreq)) {
                /* ok, wait for the next one ... */
#ifdef DEBUG
                fprintf(stderr,"%03d/%d: keepalive wait\n",req->fd,req->state);
#endif
                req->state = STATE_KEEPALIVE;
                req->hdata = 0;
                req->lreq  = 0;
                req->lbreq = 0;

#ifdef TCP_CORK
                if (req->tcp_cork == 1) {
                    req->tcp_cork = 0;
#ifdef DEBUG
                    fprintf(stderr,"%03d/%d: tcp_cork=%d\n",req->fd,req->state,req->tcp_cork);
#endif
                    setsockopt(req->fd,SOL_TCP,TCP_CORK,&req->tcp_cork,sizeof(int));
                }
#endif
            } else {
                /* there is a pipelined request in the queue ... */
#ifdef DEBUG
                fprintf(stderr,"%03d/%d: keepalive pipeline\n",req->fd,req->state);
#endif
                req->state = STATE_READ_HEADER;
                memmove(req->hreq,req->hreq + req->lreq + req->lbreq,
                        req->hdata - (req->lreq + req->lbreq));
                req->hdata -= req->lreq + req->lbreq;
                req->lreq  =  0;
                read_header(req,1);
                goto parsing;
            }
        }
      
        /* connections to close */
        if (req->state == STATE_CLOSE) {
            /* access log hook */
            /*if (log_request_func != NULL) {
                log_request_func(req, now);
                }*/

            FD_CLR(req->fd, &fds->rset);
            FD_CLR(req->fd, &fds->wset);
            /* leave max as is */

            /* cleanup */
            close(req->fd);
#ifdef USE_SSL
            if (with_ssl) {
                SSL_free(req->ssl_s);
            }
#endif
            if (req->bfd != -1) {
                close(req->bfd);
#ifdef USE_SSL
                if (with_ssl) {
                    BIO_vfree(req->bio_in);
                }
#endif
            }
	
            curr_conn--;
#ifdef DEBUG
            fprintf(stderr,"%03d/%d: done (%d)\n",req->fd,req->state,curr_conn);
#endif
            /* unlink from list */
            tmp = req;
            if (prev == NULL) {
                conns = req->next;
                req = conns;
            } else {
                prev->next = req->next;
                req = req->next;
            }
            /* free memory  */
            if (tmp->r_start) {
                free(tmp->r_start);
            }
            if (tmp->r_end) {  
                free(tmp->r_end);
            }
            if (tmp->r_head) { 
                free(tmp->r_head);
            }
            if (tmp->r_hlen) { 
                free(tmp->r_hlen);
            }
            list_free(&tmp->header);
            free(tmp);
        } else {
            prev = req;
            req = req->next;
        }
    }

    return 0;
}
Example #21
0
  void
  connection::on_header_read(const boost::system::error_code& e, std::size_t bytes_transferred)
  {
    if (e) {
      return stop();
    }

    cancel_timeout();

    boost::tribool result;
    std::string trailer;

    // debug() << "received " << bytes_transferred << " bytes";
    result = parser_.parse_header(headbuf_.data(), headbuf_.data() + bytes_transferred, trailer);

    // parser failed processing the header for some reason
    if (!result)
    {
      debug() << "invalid request header, rejecting";
      return reject(reply::bad_request);
    }

    // header is incomplete, need more feed
    else if (result == boost::indeterminate)
    {
      return read_header();
    }

    // header was successfully parsed, now let's validate it
    if (!inbound_.validate())
    {
      reply::status_type t;

      // track the error
      switch(inbound_.status)
      {
        case request::status_t::invalid_method:
          error() << "request has a non-supported method '" << inbound_ << "', aborting";
          t = reply::not_implemented;
        break;
        case request::status_t::invalid_format:
          error() << "request has a non-supported format '" << inbound_.format_str << "', aborting";
          t = reply::not_implemented;
        break;
        case request::status_t::missing_length:
          info()
          << "request does not specify a Content-Length, can not attempt indeterminate body reading, aborting";
          t = reply::bad_request;
        break;
        case request::status_t::invalid_length:
        error() << "request has 0 Content-Length, aborting";
          t = reply::bad_request;
        break;
        default:
          error() << "unknown request status: " << (int)inbound_.status << ", investigate!";
          t = reply::internal_server_error;
      }

      return reject(t);
    }

    // set up the UUID logging
    // __set_uuid(inbound_.uuid);

    handler_.init();

    // process any trailing bytes that were not part of the HTTP header
    size_t trailing_bytes = trailer.size();
    if (trailing_bytes > 0)
    {
      std::istringstream buf(trailer);
      buf.read(bodybuf_.data(), trailing_bytes);

      debug()
        << "there are " << trailing_bytes << "bytes of trailing data"
        << " and req clength is " << inbound_.content_length << "b";

      inbound_.append_body(bodybuf_.data(), bodybuf_.data() + trailer.size());

      // did the trailer contain the whole request body?
      if (trailer.size() == inbound_.content_length)
        return on_request_read();

      bufsz_ += trailing_bytes;
    }

    reading_timer_.start();

    return read_body();
  }
Example #22
0
int retrieve_stock_price(struct stock_price* price_info, char* url, parse_body_string_fun parse_body_string)
{
	int nret = 0;
	struct request * request = NULL;
	char *host_name = NULL;
	char *full_path = NULL;

	char *request_string = NULL;
	char *response_string = NULL;
	char *body_string = NULL;
	int body_size;
	char *p = NULL;

	struct ghbnwt_context *ctx = NULL;
	struct sockaddr_in sa;

	int res;
	int bufsize;

	int sock;

	url_parse (url, &host_name, &full_path);
	request = prepare_request(host_name, full_path);
	nret = 1;

	// Get server's ip adress.
	ctx =(struct ghbnwt_context *) malloc(sizeof(struct ghbnwt_context));
	ctx->host_name = host_name;
	ctx->hptr = gethostbyname (ctx->host_name);
	if (!ctx->hptr)
	{
		nret = -1;
		goto exit;
	}

	// Get socket descriptor.
	sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);

	// Connect to server.
	memset(&sa, 0, sizeof(sa));
	sa.sin_family = AF_INET;
	sa.sin_port = htons (80);
	memcpy (&sa.sin_addr, *ctx->hptr->h_addr_list, 4);
	if(-1 == connect (sock, (const struct sockaddr *)&sa, sizeof(sa)))
	{
		nret = -1;
		goto exit;
	}

	// Send request.
	p = request_string = organize_request_string(request);
	bufsize = strlen(request_string);
	res = 0;
	while (bufsize > 0)
	{
		res = send(sock, p, bufsize, 0);
		if (res <= 0)
			break;
		p += res;
		bufsize -= res;
	}

	// Receive response.
	response_string = receive_response(sock, &body_string, &body_size);
	if (response_string == NULL)
	{
		nret = -1;
	}
	else if (parse_response(response_string) == 200)
	{
		body_string = read_body(sock, body_string, body_size);
		if (body_string)
		{
			// Parse string of body
			if (body_string)
				parse_body_string(price_info, body_string);
		}
	}
	else
	{
		nret = -1;
	}

exit:
	// Close a connection.
	close(sock);

	// Reclaim heap memory space.
	free(host_name);
	free(full_path);
	free(request->headers);
	free(request);
	free(request_string);
	free(response_string);
	free(body_string);

	return nret;
}