int fetcher_handler::handle_input (ACE_HANDLE fd) { char buf[_input_buffer_size]; ACE_OS::last_error(0); ssize_t recv_cnt = this->peer().recv(buf, sizeof(buf) - 1); ACE_DEBUG((LM_DEBUG, "fetcher_handler: recv returned %d\n", recv_cnt)); if (recv_cnt < 0 && ACE_OS::last_error () != EWOULDBLOCK) { ACE_ERROR((LM_ERROR, "fetcher_handler: %p\n", "recv")); _handler->handle_error(handler::err_socket, "recv failed"); return -1; } if (recv_cnt == 0) { ACE_DEBUG((LM_DEBUG, "fetcher_handler: Close received\n")); _handle_response(); return -1; } if (_recv_mb->copy(buf, recv_cnt)) { ACE_ERROR((LM_ERROR, "fetcher_handler: could not copy data to " "receive buffer, space: %d, data len: %d\n", _recv_mb->space(), recv_cnt)); _handler->handle_error(handler::err_out_of_memory, "copying data failed"); return -1; } return 0; }
bool HTTPRequest::_update_connection() { switch( client->get_status() ) { case HTTPClient::STATUS_DISCONNECTED: { return true; //end it, since it's doing something } break; case HTTPClient::STATUS_RESOLVING: { client->poll(); //must wait return false; } break; case HTTPClient::STATUS_CANT_RESOLVE: { call_deferred("emit_signal","request_completed",RESULT_CANT_RESOLVE,0,StringArray(),ByteArray()); return true; } break; case HTTPClient::STATUS_CONNECTING: { client->poll(); //must wait return false; } break; //connecting to ip case HTTPClient::STATUS_CANT_CONNECT: { call_deferred("emit_signal","request_completed",RESULT_CANT_CONNECT,0,StringArray(),ByteArray()); return true; } break; case HTTPClient::STATUS_CONNECTED: { if (request_sent) { if (!got_response) { //no body bool ret_value; if (_handle_response(&ret_value)) return ret_value; call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,ByteArray()); return true; } if (got_response && body_len<0) { //chunked transfer is done call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,body); return true; } call_deferred("emit_signal","request_completed",RESULT_CHUNKED_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray()); return true; //request migh have been done } else { //did not request yet, do request Error err = client->request(HTTPClient::METHOD_GET,request_string,headers); if (err!=OK) { call_deferred("emit_signal","request_completed",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray()); return true; } request_sent=true; return false; } } break; //connected: { } break requests only accepted here case HTTPClient::STATUS_REQUESTING: { //must wait, it's requesting client->poll(); return false; } break; // request in progress case HTTPClient::STATUS_BODY: { if (!got_response) { bool ret_value; if (_handle_response(&ret_value)) return ret_value; if (!client->is_response_chunked() && client->get_response_body_length()==0) { call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,ByteArray()); return true; } if (client->is_response_chunked()) { body_len=-1; //no body len because chunked, change your webserver configuration if you want body len } else { body_len=client->get_response_body_length(); if (body_size_limit>=0 && body_len>body_size_limit) { call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray()); return true; } } if (download_to_file!=String()) { file=FileAccess::open(download_to_file,FileAccess::WRITE); if (!file) { call_deferred("emit_signal","request_completed",RESULT_DOWNLOAD_FILE_CANT_OPEN,response_code,response_headers,ByteArray()); } } } //print_line("BODY: "+itos(body.size())); client->poll(); ByteArray chunk = client->read_response_body_chunk(); downloaded+=chunk.size(); if (file) { ByteArray::Read r=chunk.read(); file->store_buffer(r.ptr(),chunk.size()); if (file->get_error()!=OK) { call_deferred("emit_signal","request_completed",RESULT_DOWNLOAD_FILE_WRITE_ERROR,response_code,response_headers,ByteArray()); return true; } } else { body.append_array(chunk); } if (body_size_limit>=0 && downloaded>body_size_limit) { call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray()); return true; } if (body_len>=0) { if (downloaded==body_len) { call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,body); return true; } /*if (body.size()>=body_len) { call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray()); return true; }*/ } return false; } break; // request resulted in body: { } break which must be read case HTTPClient::STATUS_CONNECTION_ERROR: { call_deferred("emit_signal","request_completed",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray()); return true; } break; case HTTPClient::STATUS_SSL_HANDSHAKE_ERROR: { call_deferred("emit_signal","request_completed",RESULT_SSL_HANDSHAKE_ERROR,0,StringArray(),ByteArray()); return true; } break; } ERR_FAIL_V(false); }