void MeerkatNameHandler::request_finished(std::tr1::shared_ptr<HttpManager::HttpResponse> response, HttpManager::ERR_TYPE error, const boost::system::error_code& boost_error, std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) { mStats.resolved++; mStats.bytesTransferred += (response->getBytesSent() + response->getBytesReceived()); std::tr1::shared_ptr<RemoteFileMetadata> bad; if (error == Transfer::HttpManager::REQUEST_PARSING_FAILED) { SILOG(transfer, error, "Request parsing failed during an HTTP name lookup (" << request->getURI() << ")"); callback(bad); return; } else if (error == Transfer::HttpManager::RESPONSE_PARSING_FAILED) { SILOG(transfer, error, "Response parsing failed during an HTTP name lookup (" << request->getURI() << ")"); callback(bad); return; } else if (error == Transfer::HttpManager::BOOST_ERROR) { SILOG(transfer, error, "A boost error happened during an HTTP name lookup (" << request->getURI() << "). Boost error = " << boost_error.message()); callback(bad); return; } else if (error != HttpManager::SUCCESS) { SILOG(transfer, error, "An unknown error happened during an HTTP name lookup. (" << request->getURI() << ")"); callback(bad); return; } if (response->getHeaders().size() == 0) { SILOG(transfer, error, "There were no headers returned during an HTTP name lookup (" << request->getURI() << ")"); callback(bad); return; } HttpManager::Headers::const_iterator it; it = response->getHeaders().find("Content-Length"); if (it != response->getHeaders().end()) { SILOG(transfer, error, "Content-Length header was present when it shouldn't be during an HTTP name lookup (" << request->getURI() << ")"); callback(bad); return; } if (response->getStatusCode() != 200) { SILOG(transfer, error, "HTTP status code = " << response->getStatusCode() << " instead of 200 during an HTTP name lookup (" << request->getURI() << ")"); callback(bad); return; } it = response->getHeaders().find("File-Size"); if (it == response->getHeaders().end()) { SILOG(transfer, error, "Expected File-Size header not present during an HTTP name lookup (" << request->getURI() << ")"); callback(bad); return; } std::string file_size_str = it->second; it = response->getHeaders().find("Hash"); if (it == response->getHeaders().end()) { SILOG(transfer, error, "Expected Hash header not present during an HTTP name lookup (" << request->getURI() << ")"); callback(bad); return; } std::string hash = it->second; if (response->getData()) { SILOG(transfer, error, "Body present during an HTTP name lookup (" << request->getURI() << ")"); callback(bad); return; } Fingerprint fp; try { fp = Fingerprint::convertFromHex(hash); } catch(std::invalid_argument e) { SILOG(transfer, error, "Hash header didn't contain a valid Fingerprint string (" << request->getURI() << ")"); callback(bad); return; } std::istringstream istream(file_size_str); uint64 file_size; istream >> file_size; std::ostringstream ostream; ostream << file_size; if(ostream.str() != file_size_str) { SILOG(transfer, error, "Error converting File-Size header string to integer (" << request->getURI() << ")"); callback(bad); return; } //Just treat everything as a single chunk for now Range whole(0, file_size, LENGTH, true); Chunk chunk(fp, whole); ChunkList chunkList; chunkList.push_back(chunk); std::tr1::shared_ptr<RemoteFileMetadata> met(new RemoteFileMetadata(fp, request->getURI(), file_size, chunkList, response->getRawHeaders())); callback(met); SILOG(transfer, detailed, "done http name handler request_finished"); }
void MeerkatChunkHandler::request_finished(std::tr1::shared_ptr<HttpManager::HttpResponse> response, HttpManager::ERR_TYPE error, const boost::system::error_code& boost_error, const URI& uri, std::tr1::shared_ptr<Chunk> chunk, bool chunkReq, ChunkCallback callback) { mStats.downloaded++; mStats.bytesTransferred += (response->getBytesSent() + response->getBytesReceived()); std::tr1::shared_ptr<DenseData> bad; std::string reqType = "file request"; if(chunkReq) reqType = "chunk request"; if (error == Transfer::HttpManager::REQUEST_PARSING_FAILED) { SILOG(transfer, error, "Request parsing failed during an HTTP " << reqType << " (" << uri << ")"); callback(bad); return; } else if (error == Transfer::HttpManager::RESPONSE_PARSING_FAILED) { SILOG(transfer, error, "Response parsing failed during an HTTP " << reqType << " (" << uri << ")"); callback(bad); return; } else if (error == Transfer::HttpManager::BOOST_ERROR) { SILOG(transfer, error, "A boost error happened during an HTTP " << reqType << ". Boost error = " << boost_error.message() << " (" << uri << ")"); callback(bad); return; } else if (error != HttpManager::SUCCESS) { SILOG(transfer, error, "An unknown error happened during an HTTP " << reqType << " (" << uri << ")"); callback(bad); return; } if (response->getHeaders().size() == 0) { SILOG(transfer, error, "There were no headers returned during an HTTP " << reqType << " (" << uri << ")"); callback(bad); return; } HttpManager::Headers::const_iterator it; it = response->getHeaders().find("Content-Length"); if (it == response->getHeaders().end()) { SILOG(transfer, error, "Content-Length header was not present when it should be during an HTTP " << reqType << " (" << uri << ")"); callback(bad); return; } if (response->getStatusCode() != 200) { SILOG(transfer, error, "HTTP status code = " << response->getStatusCode() << " instead of 200 during an HTTP " << reqType << " (" << uri << ")"); callback(bad); return; } if (!response->getData()) { SILOG(transfer, error, "Body not present during an HTTP " << reqType << " (" << uri << ")"); callback(bad); return; } it = response->getHeaders().find("Content-Range"); if (chunkReq && it == response->getHeaders().end()) { SILOG(transfer, error, "Expected Content-Range header not present during an HTTP " << reqType << " (" << uri << ")"); callback(bad); return; } else if (chunkReq) { std::string range_str = it->second; bool range_parsed = false; if (range_str.substr(0,6) == "bytes ") { range_str = range_str.substr(6); size_type dashPos = range_str.find('-'); if (dashPos != std::string::npos) { range_str.replace(dashPos, 1, " "); //total file size is optional size_type slashPos = range_str.find('/'); if (slashPos != std::string::npos) { range_str.replace(slashPos, 1, " "); } std::istringstream instream(range_str); uint64 range_start; uint64 range_end; instream >> range_start; instream >> range_end; if (range_start == chunk->getRange().startbyte() && range_end == chunk->getRange().endbyte() && response->getData()->length() == chunk->getRange().length()) { range_parsed = true; } } }