Search in sources :

Example 1 with BadRangeException

use of com.google.appengine.tools.cloudstorage.BadRangeException in project appengine-gcs-client by GoogleCloudPlatform.

the class OauthRawGcsService method readObjectAsync.

/**
 * Might not fill all of dst.
 */
@Override
public Future<GcsFileMetadata> readObjectAsync(final ByteBuffer dst, final GcsFilename filename, long startOffsetBytes, long timeoutMillis) {
    Preconditions.checkArgument(startOffsetBytes >= 0, "%s: offset must be non-negative: %s", this, startOffsetBytes);
    final int n = dst.remaining();
    Preconditions.checkArgument(n > 0, "%s: dst full: %s", this, dst);
    final int want = Math.min(READ_LIMIT_BYTES, n);
    final HTTPRequest req = makeRequest(filename, null, GET, timeoutMillis);
    req.setHeader(new HTTPHeader(RANGE, "bytes=" + startOffsetBytes + "-" + (startOffsetBytes + want - 1)));
    final HTTPRequestInfo info = new HTTPRequestInfo(req);
    return new FutureWrapper<HTTPResponse, GcsFileMetadata>(urlfetch.fetchAsync(req)) {

        @Override
        protected GcsFileMetadata wrap(HTTPResponse resp) throws IOException {
            long totalLength;
            switch(resp.getResponseCode()) {
                case 200:
                    totalLength = getLengthFromHeader(resp, X_GOOG_CONTENT_LENGTH);
                    break;
                case 206:
                    totalLength = getLengthFromContentRange(resp);
                    break;
                case 404:
                    throw new FileNotFoundException("Could not find: " + filename);
                case 416:
                    throw new BadRangeException("Requested Range not satisfiable; perhaps read past EOF? " + URLFetchUtils.describeRequestAndResponse(info, resp));
                default:
                    throw HttpErrorHandler.error(info, resp);
            }
            byte[] content = resp.getContent();
            Preconditions.checkState(content.length <= want, "%s: got %s > wanted %s", this, content.length, want);
            dst.put(content);
            return getMetadataFromResponse(filename, resp, totalLength);
        }

        @Override
        protected Throwable convertException(Throwable e) {
            return OauthRawGcsService.convertException(info, e);
        }
    };
}
Also used : HTTPRequest(com.google.appengine.api.urlfetch.HTTPRequest) HTTPResponse(com.google.appengine.api.urlfetch.HTTPResponse) FutureWrapper(com.google.appengine.api.utils.FutureWrapper) FileNotFoundException(java.io.FileNotFoundException) HTTPRequestInfo(com.google.appengine.tools.cloudstorage.oauth.URLFetchUtils.HTTPRequestInfo) BadRangeException(com.google.appengine.tools.cloudstorage.BadRangeException) HTTPHeader(com.google.appengine.api.urlfetch.HTTPHeader)

Example 2 with BadRangeException

use of com.google.appengine.tools.cloudstorage.BadRangeException in project appengine-gcs-client by GoogleCloudPlatform.

the class LocalRawGcsService method readObjectAsync.

@Override
public Future<GcsFileMetadata> readObjectAsync(ByteBuffer dst, GcsFilename filename, long offset, long timeoutMillis) {
    Preconditions.checkArgument(offset >= 0, "%s: offset must be non-negative: %s", this, offset);
    try {
        ensureInitialized();
        GcsFileMetadata meta = getObjectMetadata(filename, timeoutMillis);
        if (meta == null) {
            return Futures.immediateFailedFuture(new FileNotFoundException(this + ": No such file: " + filename));
        }
        if (offset >= meta.getLength()) {
            return Futures.immediateFailedFuture(new BadRangeException("The requested range cannot be satisfied. bytes=" + Long.toString(offset) + "-" + Long.toString(offset + dst.remaining()) + " the file is only " + meta.getLength()));
        }
        int read = 0;
        try (ReadableByteChannel readChannel = Channels.newChannel(blobStorage.fetchBlob(getBlobKeyForFilename(filename)))) {
            if (offset > 0) {
                long bytesRemaining = offset;
                ByteBuffer seekBuffer = ByteBuffer.allocate(1024);
                while (bytesRemaining > 0) {
                    if (bytesRemaining < seekBuffer.limit()) {
                        seekBuffer.limit((int) bytesRemaining);
                    }
                    read = readChannel.read(seekBuffer);
                    if (read == -1) {
                        return Futures.immediateFailedFuture(new BadRangeException("The requested range cannot be satisfied; seek failed with " + Long.toString(bytesRemaining) + " bytes remaining."));
                    }
                    bytesRemaining -= read;
                    seekBuffer.clear();
                }
                read = 0;
            }
            while (read != -1 && dst.hasRemaining()) {
                read = readChannel.read(dst);
            }
        }
        return Futures.immediateFuture(meta);
    } catch (IOException e) {
        return Futures.immediateFailedFuture(e);
    }
}
Also used : ReadableByteChannel(java.nio.channels.ReadableByteChannel) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) GcsFileMetadata(com.google.appengine.tools.cloudstorage.GcsFileMetadata) BadRangeException(com.google.appengine.tools.cloudstorage.BadRangeException) ByteBuffer(java.nio.ByteBuffer)

Aggregations

BadRangeException (com.google.appengine.tools.cloudstorage.BadRangeException)2 FileNotFoundException (java.io.FileNotFoundException)2 HTTPHeader (com.google.appengine.api.urlfetch.HTTPHeader)1 HTTPRequest (com.google.appengine.api.urlfetch.HTTPRequest)1 HTTPResponse (com.google.appengine.api.urlfetch.HTTPResponse)1 FutureWrapper (com.google.appengine.api.utils.FutureWrapper)1 GcsFileMetadata (com.google.appengine.tools.cloudstorage.GcsFileMetadata)1 HTTPRequestInfo (com.google.appengine.tools.cloudstorage.oauth.URLFetchUtils.HTTPRequestInfo)1 IOException (java.io.IOException)1 ByteBuffer (java.nio.ByteBuffer)1 ReadableByteChannel (java.nio.channels.ReadableByteChannel)1