1 // Copyright 2015 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.net; 6 7 import java.io.Closeable; 8 import java.io.IOException; 9 import java.nio.ByteBuffer; 10 11 /** 12 * Abstract class allowing the embedder to provide an upload body to {@link UrlRequest}. It supports 13 * both non-chunked (size known in advanced) and chunked (size not known in advance) uploads. Be 14 * aware that not all servers support chunked uploads. 15 * 16 * <p>An upload is either always chunked, across multiple uploads if the data 17 * ends up being sent more than once, or never chunked. 18 */ 19 public abstract class UploadDataProvider implements Closeable { 20 /** 21 * If this is a non-chunked upload, returns the length of the upload. Must always return -1 if 22 * this is a chunked upload. 23 * 24 * @return the length of the upload for non-chunked uploads, -1 otherwise. 25 * @throws IOException if any IOException occurred during the process. 26 */ getLength()27 public abstract long getLength() throws IOException; 28 29 /** 30 * Reads upload data into {@code byteBuffer}. Upon completion, the buffer's position is updated 31 * to the end of the bytes that were read. The buffer's limit is not changed. Each call of this 32 * method must be followed be a single call, either synchronous or asynchronous, to {@code 33 * uploadDataSink}: {@link UploadDataSink#onReadSucceeded} on success or {@link 34 * UploadDataSink#onReadError} on failure. Neither read nor rewind will be called until one of 35 * those methods or the other is called. Even if the associated {@link UrlRequest} is canceled, 36 * one or the other must still be called before resources can be safely freed. Throwing an 37 * exception will also result in resources being freed and the request being errored out. 38 * 39 * @param uploadDataSink The object to notify when the read has completed, successfully or 40 * otherwise. 41 * @param byteBuffer The buffer to copy the read bytes into. Do not change byteBuffer's limit. 42 * @throws IOException if any IOException occurred during the process. {@link 43 * UrlRequest.Callback#onFailed} will be called with the thrown exception set as the cause of 44 * the 45 * {@link CallbackException}. 46 */ read(UploadDataSink uploadDataSink, ByteBuffer byteBuffer)47 public abstract void read(UploadDataSink uploadDataSink, ByteBuffer byteBuffer) 48 throws IOException; 49 50 /** 51 * Rewinds upload data to the beginning. Invoked when Cronet requires the upload data 52 * provider to be in an equivalent state to as if {@link #read} was never called yet. 53 * 54 * <p>To signal that the operation has finished, implementations of this function must call 55 * {@link UploadDataSink#onRewindSucceeded} to indicate success, or 56 * {@link UploadDataSink#onRewindError} on failure. Even if the associated {@link UrlRequest} is 57 * canceled, one or the other must still be called before resources can be safely freed. 58 * Throwing an exception from the method is equivalent to calling {@code onRewindError}. 59 * If rewinding is not supported (for instance, if reading from a one-off stream), this 60 * should call {@link UploadDataSink#onRewindError} immediately. 61 * 62 * <p>The implementer can safely assume that neither {@link #read} nor a concurrent 63 * {@link #rewind} call will be issued until they notify the sink that rewinding has finished, 64 * as described in the previous paragraph. 65 * 66 * <p>This method is used internally by Cronet if the body needs to be uploaded multiple times. This 67 * can occur in many different situations, for instance when following redirects, or when retrying 68 * requests after a timeout or a network disconnect. Note that while implementing rewinding is 69 * generally optional, requests which end up requiring it will fail unless rewinding is implemented. 70 * 71 * @param uploadDataSink The object to notify when the rewind operation has completed, 72 * successfully or otherwise. 73 * @throws IOException if any IOException occurred during the process. {@link 74 * UrlRequest.Callback#onFailed} will be called with the thrown exception set as the cause of 75 * the {@link CallbackException}. 76 */ rewind(UploadDataSink uploadDataSink)77 public abstract void rewind(UploadDataSink uploadDataSink) throws IOException; 78 79 /** 80 * Called when this UploadDataProvider is no longer needed by a request, so that resources (like 81 * a file) can be explicitly released. 82 * 83 * @throws IOException if any IOException occurred during the process. This will cause the 84 * request 85 * to fail if it is not yet complete; otherwise it will be logged. 86 */ 87 @Override close()88 public void close() throws IOException {} 89 } 90