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; }
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; }
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; }
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); } }
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; }
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(); }
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; }
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(¤t_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; }
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 }
// 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; }
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; } }
/* * 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; }
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(¤t_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; } } }
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; }
/* 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); }
// 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
/* 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; }
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(); }
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; }