Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
("InputStreamBodyGenerator adds chunk markers on its own due to issues with Netty's implementation of chunking. This is causing test failures while implementing a Grizzly-based provider.")

Hack the provider
  • Loading branch information
jfarcand committed Jun 27, 2011
1 parent fb05cd6 commit 7c450fc
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 34 deletions.
Expand Up @@ -35,6 +35,7 @@ public class InputStreamBodyGenerator implements BodyGenerator {
private final static byte[] ZERO = "0".getBytes();
private final InputStream inputStream;
private final static Logger logger = LoggerFactory.getLogger(InputStreamBodyGenerator.class);
private boolean patchNettyChunkingIssue = false;

public InputStreamBodyGenerator(InputStream inputStream) {
this.inputStream = inputStream;
Expand Down Expand Up @@ -72,42 +73,44 @@ public long read(ByteBuffer buffer) throws IOException {
logger.warn("Unable to read", ex);
}

if (read == -1) {
// Since we are chuncked, we must output extra bytes before considering the input stream closed.
// chunking requires to end the chunking:
// - A Terminating chunk of "0\r\n".getBytes(),
// - Then a separate packet of "\r\n".getBytes()
if (!eof) {
endDataCount++;
if (endDataCount == 2)
eof = true;

if (endDataCount == 1)
buffer.put(ZERO);

buffer.put(END_PADDING);


return buffer.position();
} else {
if (inputStream.markSupported()) {
inputStream.reset();
if (patchNettyChunkingIssue) {
if (read == -1) {
// Since we are chuncked, we must output extra bytes before considering the input stream closed.
// chunking requires to end the chunking:
// - A Terminating chunk of "0\r\n".getBytes(),
// - Then a separate packet of "\r\n".getBytes()
if (!eof) {
endDataCount++;
if (endDataCount == 2)
eof = true;

if (endDataCount == 1)
buffer.put(ZERO);

buffer.put(END_PADDING);


return buffer.position();
} else {
if (inputStream.markSupported()) {
inputStream.reset();
}
eof = false;
}
eof = false;
return -1;
}
return -1;
}

/**
* Netty 3.2.3 doesn't support chunking encoding properly, so we chunk encoding ourself.
*/
/**
* Netty 3.2.3 doesn't support chunking encoding properly, so we chunk encoding ourself.
*/

buffer.put(Integer.toHexString(read).getBytes());
// Chunking is separated by "<bytesreads>\r\n"
buffer.put(END_PADDING);
buffer.put(chunk, 0, read);
// Was missing the final chunk \r\n.
buffer.put(END_PADDING);
buffer.put(Integer.toHexString(read).getBytes());
// Chunking is separated by "<bytesreads>\r\n"
buffer.put(END_PADDING);
buffer.put(chunk, 0, read);
// Was missing the final chunk \r\n.
buffer.put(END_PADDING);
}

return read;
}
Expand All @@ -116,4 +119,12 @@ public void close() throws IOException {
inputStream.close();
}
}

/**
* HACK: This is required because Netty has issues with chunking.
* @param patchNettyChunkingIssue
*/
public void patchNettyChunkingIssue(boolean patchNettyChunkingIssue){
this.patchNettyChunkingIssue = patchNettyChunkingIssue;
}
}
Expand Up @@ -20,6 +20,7 @@
import com.ning.http.client.AsyncHttpClientConfig;
import com.ning.http.client.AsyncHttpProvider;
import com.ning.http.client.Body;
import com.ning.http.client.BodyGenerator;
import com.ning.http.client.ConnectionsPool;
import com.ning.http.client.Cookie;
import com.ning.http.client.FluentCaseInsensitiveStringsMap;
Expand All @@ -40,6 +41,7 @@
import com.ning.http.client.filter.FilterException;
import com.ning.http.client.filter.IOExceptionFilter;
import com.ning.http.client.filter.ResponseFilter;
import com.ning.http.client.generators.InputStreamBodyGenerator;
import com.ning.http.client.listener.TransferCompletionHandler;
import com.ning.http.client.ntlm.NTLMEngine;
import com.ning.http.client.ntlm.NTLMEngineException;
Expand Down Expand Up @@ -356,9 +358,15 @@ protected final <T> void writeRequest(final Channel channel,

Body body = null;
if (!future.getNettyRequest().getMethod().equals(HttpMethod.CONNECT)) {
if (future.getRequest().getBodyGenerator() != null) {
BodyGenerator bg = future.getRequest().getBodyGenerator();
if (bg != null) {
// Netty issue with chunking.
if (InputStreamBodyGenerator.class.isAssignableFrom(bg.getClass())) {
InputStreamBodyGenerator.class.cast(bg).patchNettyChunkingIssue(true);
}

try {
body = future.getRequest().getBodyGenerator().createBody();
body = bg.createBody();
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
Expand Down

0 comments on commit 7c450fc

Please sign in to comment.