|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2012 Sonatype, Inc. All rights reserved. |
| 2 | + * Copyright (c) 2012-2013 Sonatype, Inc. All rights reserved. |
3 | 3 | *
|
4 | 4 | * This program is licensed to you under the Apache License Version 2.0,
|
5 | 5 | * and you may not use this file except in compliance with the Apache License Version 2.0.
|
|
16 | 16 | import static com.ning.http.util.MiscUtil.isNonEmpty;
|
17 | 17 |
|
18 | 18 | import com.ning.http.client.AsyncHttpClient;
|
| 19 | +import com.ning.http.client.Part; |
| 20 | +import com.ning.http.multipart.MultipartBody; |
19 | 21 | import com.ning.org.jboss.netty.handler.codec.http.CookieDecoder;
|
20 | 22 | import com.ning.http.client.AsyncHandler;
|
21 | 23 | import com.ning.http.client.AsyncHttpClientConfig;
|
@@ -2072,31 +2074,64 @@ public boolean handlesBodyType(final Request request) {
|
2072 | 2074 | return isNonEmpty(request.getParts());
|
2073 | 2075 | }
|
2074 | 2076 |
|
2075 |
| - @SuppressWarnings({"unchecked"}) |
2076 | 2077 | public boolean doHandle(final FilterChainContext ctx,
|
2077 |
| - final Request request, |
2078 |
| - final HttpRequestPacket requestPacket) |
2079 |
| - throws IOException { |
2080 |
| - |
2081 |
| - MultipartRequestEntity mre = |
2082 |
| - AsyncHttpProviderUtils.createMultipartRequestEntity( |
2083 |
| - request.getParts(), |
2084 |
| - request.getHeaders()); |
2085 |
| - requestPacket.setContentLengthLong(mre.getContentLength()); |
2086 |
| - requestPacket.setContentType(mre.getContentType()); |
2087 |
| - final MemoryManager mm = ctx.getMemoryManager(); |
2088 |
| - Buffer b = mm.allocate(512); |
2089 |
| - BufferOutputStream o = new BufferOutputStream(mm, b, true); |
2090 |
| - mre.writeRequest(o); |
2091 |
| - b = o.getBuffer(); |
2092 |
| - b.trim(); |
2093 |
| - if (b.hasRemaining()) { |
2094 |
| - final HttpContent content = requestPacket.httpContentBuilder().content(b).build(); |
2095 |
| - content.setLast(true); |
2096 |
| - ctx.write(content, ((!requestPacket.isCommitted()) ? ctx.getTransportContext().getCompletionHandler() : null)); |
| 2078 | + final Request request, |
| 2079 | + final HttpRequestPacket requestPacket) |
| 2080 | + throws IOException { |
| 2081 | + |
| 2082 | + final List<Part> parts = request.getParts(); |
| 2083 | + final MultipartRequestEntity mre = AsyncHttpProviderUtils.createMultipartRequestEntity(parts, request.getHeaders()); |
| 2084 | + final long contentLength = mre.getContentLength(); |
| 2085 | + final String contentType = mre.getContentType(); |
| 2086 | + requestPacket.setContentLengthLong(contentLength); |
| 2087 | + requestPacket.setContentType(contentType); |
| 2088 | + if (LOGGER.isDebugEnabled()) { |
| 2089 | + LOGGER.debug("REQUEST(modified): contentLength={}, contentType={}", new Object[]{requestPacket.getContentLength(), requestPacket.getContentType()}); |
2097 | 2090 | }
|
2098 | 2091 |
|
2099 |
| - return true; |
| 2092 | + final FeedableBodyGenerator generator = new FeedableBodyGenerator() { |
| 2093 | + @Override |
| 2094 | + public Body createBody() throws IOException { |
| 2095 | + return new MultipartBody(parts, contentType, String.valueOf(contentLength)); |
| 2096 | + } |
| 2097 | + }; |
| 2098 | + generator.setFeeder(new FeedableBodyGenerator.BaseFeeder(generator) { |
| 2099 | + @Override |
| 2100 | + public void flush() throws IOException { |
| 2101 | + final Body bodyLocal = feedableBodyGenerator.createBody(); |
| 2102 | + try { |
| 2103 | + final MemoryManager mm = ctx.getMemoryManager(); |
| 2104 | + boolean last = false; |
| 2105 | + while (!last) { |
| 2106 | + Buffer buffer = mm.allocate(BodyHandler.MAX_CHUNK_SIZE); |
| 2107 | + buffer.allowBufferDispose(true); |
| 2108 | + final long readBytes = bodyLocal.read(buffer.toByteBuffer()); |
| 2109 | + if (readBytes > 0) { |
| 2110 | + buffer.position((int) readBytes); |
| 2111 | + buffer.trim(); |
| 2112 | + } else { |
| 2113 | + buffer.dispose(); |
| 2114 | + if (readBytes < 0) { |
| 2115 | + last = true; |
| 2116 | + buffer = Buffers.EMPTY_BUFFER; |
| 2117 | + } else { |
| 2118 | + throw new IllegalStateException("MultipartBody unexpectedly returned 0 bytes available"); |
| 2119 | + } |
| 2120 | + } |
| 2121 | + feed(buffer, last); |
| 2122 | + } |
| 2123 | + } finally { |
| 2124 | + if (bodyLocal != null) { |
| 2125 | + try { |
| 2126 | + bodyLocal.close(); |
| 2127 | + } catch (IOException ignore) { |
| 2128 | + } |
| 2129 | + } |
| 2130 | + } |
| 2131 | + } |
| 2132 | + }); |
| 2133 | + generator.initializeAsynchronousTransfer(ctx, requestPacket); |
| 2134 | + return false; |
2100 | 2135 | }
|
2101 | 2136 |
|
2102 | 2137 | } // END PartsBodyHandler
|
|
0 commit comments