Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for fixed ContentLength #32

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 46 additions & 4 deletions src/main/java/io/tus/java/client/TusUploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public TusUploader(TusClient client, TusUpload upload, URL uploadURL, TusInputSt
setChunkSize(2 * 1024 * 1024);
}

private void openConnection() throws IOException, ProtocolException {
private void openConnection(boolean chunked) throws IOException, ProtocolException {
// Only open a connection, if we have none open.
if(connection != null) {
return;
Expand All @@ -77,7 +77,8 @@ private void openConnection() throws IOException, ProtocolException {
}

connection.setDoOutput(true);
connection.setChunkedStreamingMode(0);
if (chunked)
connection.setChunkedStreamingMode(0);
try {
output = connection.getOutputStream();
} catch(java.net.ProtocolException pe) {
Expand Down Expand Up @@ -159,6 +160,47 @@ public int getRequestPayloadSize() {
return requestPayloadSize;
}

/**
* Upload a part of the file by reading a chunk from the InputStream and writing
* it to the HTTP request's body. If the number of available bytes is lower than the chunk's
* size, all available bytes will be uploaded and nothing more.
* The size of the read chunk can be obtained using {@link #getRequestPayloadSize()} and changed
* using {@link #setRequestPayloadSize(int)}.
* In order to obtain the new offset, use {@link #getOffset()} after this method returns.
*
* @return Number of bytes read and written.
* @throws IOException Thrown if an exception occurs while reading from the source or writing
* to the HTTP request.
*/
public int upload() throws IOException, ProtocolException {
Acconut marked this conversation as resolved.
Show resolved Hide resolved
openConnection(false);

setChunkSize(bytesRemainingForRequest);

int bytesRead = input.read(buffer, bytesRemainingForRequest);
if(bytesRead == -1) {
// No bytes were read since the input stream is empty
return -1;
}

// FIXME connection.setRequestProperty("Content-Length", Long.toString(bytesRead));
gbonnefille marked this conversation as resolved.
Show resolved Hide resolved

// Do not write the entire buffer to the stream since the array will
// be filled up with 0x00s if the number of read bytes is lower then
// the chunk's size.
output.write(buffer, 0, bytesRead);
output.flush();

offset += bytesRead;
bytesRemainingForRequest -= bytesRead;

if(bytesRemainingForRequest <= 0) {
finishConnection();
}

return bytesRead;
}

/**
* Upload a part of the file by reading a chunk from the InputStream and writing
* it to the HTTP request's body. If the number of available bytes is lower than the chunk's
Expand All @@ -174,7 +216,7 @@ public int getRequestPayloadSize() {
* to the HTTP request.
*/
public int uploadChunk() throws IOException, ProtocolException {
openConnection();
openConnection(true);

int bytesToRead = Math.min(getChunkSize(), bytesRemainingForRequest);

Expand Down Expand Up @@ -226,7 +268,7 @@ public int uploadChunk() throws IOException, ProtocolException {
* to the HTTP request.
*/
@Deprecated public int uploadChunk(int chunkSize) throws IOException, ProtocolException {
openConnection();
openConnection(true);

byte[] buf = new byte[chunkSize];
int bytesRead = input.read(buf, chunkSize);
Expand Down
46 changes: 46 additions & 0 deletions src/test/java/io/tus/java/client/TestTusUploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,52 @@ public void testTusUploader() throws IOException, ProtocolException {
uploader.finish();
}

@Test
public void testTusUploaderFixedLength() throws IOException, ProtocolException {
byte[] content = "hello world".getBytes();

mockServer.when(new HttpRequest()
.withPath("/files/fixed")
.withHeader("Tus-Resumable", TusClient.TUS_VERSION)
.withHeader("Upload-Offset", "5")
.withHeader("Content-Type", "application/offset+octet-stream")
.withHeader(isOpenJDK6 ? "": "Expect: 100-continue")
.withBody(Arrays.copyOfRange(content, 5, 10)))
.respond(new HttpResponse()
.withStatusCode(204)
.withHeader("Tus-Resumable", TusClient.TUS_VERSION)
.withHeader("Upload-Offset", "10"));
mockServer.when(new HttpRequest()
.withPath("/files/fixed")
.withHeader("Tus-Resumable", TusClient.TUS_VERSION)
.withHeader("Upload-Offset", "10")
.withHeader("Content-Type", "application/offset+octet-stream")
.withHeader(isOpenJDK6 ? "": "Expect: 100-continue")
.withBody(Arrays.copyOfRange(content, 10, 11)))
.respond(new HttpResponse()
.withStatusCode(204)
.withHeader("Tus-Resumable", TusClient.TUS_VERSION)
.withHeader("Upload-Offset", "11"));

TusClient client = new TusClient();
URL uploadUrl = new URL(mockServerURL + "/fixed");
TusInputStream input = new TusInputStream(new ByteArrayInputStream(content));
long offset = 5;

TusUpload upload = new TusUpload();

TusUploader uploader = new TusUploader(client, upload, uploadUrl, input, offset);

uploader.setRequestPayloadSize(5);
assertEquals(uploader.getRequestPayloadSize(), 5);

assertEquals(5, uploader.upload());
assertEquals(1, uploader.upload());
assertEquals(-1, uploader.upload());
assertEquals(11, uploader.getOffset());
uploader.finish();
}

@Test
public void testTusUploaderClientUploadFinishedCalled() throws IOException, ProtocolException {

Expand Down