InputStreamBodyGenerator.java
/*
* Copyright (c) 2010-2012 Sonatype, Inc. All rights reserved.
*
* This program is licensed to you under the Apache License Version 2.0,
* and you may not use this file except in compliance with the Apache License Version 2.0.
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the Apache License Version 2.0 is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
*/
package org.asynchttpclient.request.body.generator;
import io.netty.buffer.ByteBuf;
import org.asynchttpclient.request.body.Body;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
/**
* A {@link BodyGenerator} which use an {@link InputStream} for reading bytes, without having to read the entire stream in memory.
* <br>
* NOTE: The {@link InputStream} must support the {@link InputStream#mark} and {@link InputStream#reset()} operation. If not, mechanisms like authentication, redirect, or
* resumable download will not work.
*/
public final class InputStreamBodyGenerator implements BodyGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(InputStreamBody.class);
private final InputStream inputStream;
private final long contentLength;
public InputStreamBodyGenerator(InputStream inputStream) {
this(inputStream, -1L);
}
public InputStreamBodyGenerator(InputStream inputStream, long contentLength) {
this.inputStream = inputStream;
this.contentLength = contentLength;
}
public InputStream getInputStream() {
return inputStream;
}
public long getContentLength() {
return contentLength;
}
@Override
public Body createBody() {
return new InputStreamBody(inputStream, contentLength);
}
private static class InputStreamBody implements Body {
private final InputStream inputStream;
private final long contentLength;
private byte[] chunk;
private InputStreamBody(InputStream inputStream, long contentLength) {
this.inputStream = inputStream;
this.contentLength = contentLength;
}
@Override
public long getContentLength() {
return contentLength;
}
@Override
public BodyState transferTo(ByteBuf target) {
// To be safe.
chunk = new byte[target.writableBytes() - 10];
int read = -1;
boolean write = false;
try {
read = inputStream.read(chunk);
} catch (IOException ex) {
LOGGER.warn("Unable to read", ex);
}
if (read > 0) {
target.writeBytes(chunk, 0, read);
write = true;
}
return write ? BodyState.CONTINUE : BodyState.STOP;
}
@Override
public void close() throws IOException {
inputStream.close();
}
}
}