Пример #1
0
void FileNameHandler::onReadFinished(std::tr1::shared_ptr<DenseData> fileContents,
        std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) {

    mStats.resolved++;

    std::tr1::shared_ptr<RemoteFileMetadata> bad;
    if (!fileContents) {
        SILOG(transfer, error, "FileNameHandler couldn't find file '" << request->getURI() << "'");
        callback(bad);
        return;
    }

    FileHeaders emptyHeaders;
    Fingerprint fp = SparseData(fileContents).computeFingerprint();

    //Just treat everything as a single chunk for now
    Range::length_type file_size = fileContents->length();
    Range whole(0, file_size, LENGTH, true);
    Chunk chunk(fp, whole);
    ChunkList chunkList;
    chunkList.push_back(chunk);

    SharedChunkCache::getSingleton().getCache()->addToCache(fp, fileContents);
    std::tr1::shared_ptr<RemoteFileMetadata> met(new RemoteFileMetadata(fp, request->getURI(),
                file_size, chunkList, emptyHeaders));
    callback(met);
}
Пример #2
0
void MeerkatNameHandler::resolve(std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) {
    URL url(request->getURI());
    assert(!url.empty());

    std::string dns_uri_prefix = CDN_DNS_URI_PREFIX;
    std::string host_name = CDN_HOST_NAME;
    Network::Address cdn_addr = mCdnAddr;
    if (url.host() != "") {
        host_name = url.context().hostname();
        std::string service = url.context().service();
        if (service == "") {
            service = CDN_SERVICE;
        }
        Network::Address given_addr(host_name, service);
        cdn_addr = given_addr;
    }

    HttpManager::Headers headers;
    headers["Host"] = host_name;

    HttpManager::getSingleton().head(
        cdn_addr, dns_uri_prefix + url.fullpath(),
        std::tr1::bind(&MeerkatNameHandler::request_finished, this, _1, _2, _3, request, callback),
        headers
    );
}
Пример #3
0
void MeerkatChunkHandler::get(std::tr1::shared_ptr<RemoteFileMetadata> file,
        std::tr1::shared_ptr<Chunk> chunk, ChunkCallback callback) {

    //Check for null arguments
    std::tr1::shared_ptr<DenseData> bad;
    if (!file) {
        SILOG(transfer, error, "HttpChunkHandler get called with null file parameter");
        callback(bad);
        return;
    }
    if (!chunk) {
        SILOG(transfer, error, "HttpChunkHandler get called with null chunk parameter");
        callback(bad);
        return;
    }

    //Make sure chunk given is part of file
    bool foundIt = false;
    const ChunkList & chunks = file->getChunkList();
    for (ChunkList::const_iterator it = chunks.begin(); it != chunks.end(); it++) {
        if(*chunk == *it) {
            foundIt = true;
        }
    }
    if(!foundIt) {
        SILOG(transfer, error, "HttpChunkHandler get called with chunk not present in file metadata");
        callback(bad);
        return;
    }

    //Check to see if it's in the cache first
    SharedChunkCache::getSingleton().getCache()->getData(file->getFingerprint(), chunk->getRange(), std::tr1::bind(
            &MeerkatChunkHandler::cache_check_callback, this, _1, file->getURI(), chunk, callback));
}
Пример #4
0
void AssetDownloadTask::textureDownloaded(std::tr1::shared_ptr<ChunkRequest> request, std::tr1::shared_ptr<const DenseData> response) {
    // Clear the download task
    mActiveDownloads.erase(request->getURI());

    // Lack of response data means failure of some sort
    if (!response) {
        failDownload();
        return;
    }

    // Store data for later use
    mDependencies[request->getURI()].request = request;
    mDependencies[request->getURI()].response = response;

    mRemainingDownloads--;
    if (mRemainingDownloads == 0)
        mCB();
}
Пример #5
0
void FileNameHandler::resolve(std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) {
    URL url(request->getURI());
    assert(!url.empty());
    Filesystem::Path fileRequested(url.fullpath());

    std::tr1::shared_ptr<DiskManager::DiskRequest> read_req(
        new DiskManager::ReadRequest(fileRequested,
            std::tr1::bind(&FileNameHandler::onReadFinished, this, _1, request, callback)));
    DiskManager::getSingleton().addRequest(read_req);
}
Пример #6
0
void FileChunkHandler::onReadFinished(std::tr1::shared_ptr<DenseData> fileContents, std::tr1::shared_ptr<RemoteFileMetadata> file,
        std::tr1::shared_ptr<Chunk> chunk, ChunkCallback callback) {

    mStats.downloaded++;

    std::tr1::shared_ptr<DenseData> bad;
    if (!fileContents) {
        SILOG(transfer, error, "FileChunkHandler couldn't find file '" << file->getURI() << "'");
        callback(bad);
        return;
    }

    SharedChunkCache::getSingleton().getCache()->addToCache(file->getFingerprint(), fileContents);
    callback(fileContents);
}
Пример #7
0
void FileChunkHandler::cache_check_callback(const SparseData* data, std::tr1::shared_ptr<RemoteFileMetadata> file,
            std::tr1::shared_ptr<Chunk> chunk, ChunkCallback callback) {
    if (data) {
        mStats.downloaded++;
        std::tr1::shared_ptr<const DenseData> flattened = data->flatten();
        callback(flattened);
    } else {
        URL url(file->getURI());
        assert(!url.empty());
        Filesystem::Path fileRequested(url.fullpath());

        std::tr1::shared_ptr<DiskManager::DiskRequest> read_req(
            new DiskManager::ReadRequest(fileRequested,
                std::tr1::bind(&FileChunkHandler::onReadFinished, this, _1, file, chunk, callback)));
        DiskManager::getSingleton().addRequest(read_req);
    }
}
Пример #8
0
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) {

    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");
}