fix HTTP file upload cleanup on client and server
This commit is contained in:
parent
3749b9ba3a
commit
dab29dbf9f
4 changed files with 25 additions and 29 deletions
|
@ -2,9 +2,11 @@ package org.xbib.net.http.client.netty;
|
|||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.pool.ChannelPoolHandler;
|
||||
import io.netty.handler.codec.http.multipart.HttpDataFactory;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
@ -84,6 +86,14 @@ public class NettyHttpClient implements HttpClient<HttpRequest, HttpResponse>, C
|
|||
return new ChannelInitializer<>() {
|
||||
@Override
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
channel.closeFuture().addListener((ChannelFuture future) -> {
|
||||
Channel ch = future.channel();
|
||||
HttpDataFactory httpDataFactory = ch.attr(NettyHttpClientConfig.ATTRIBUTE_HTTP_DATAFACTORY).get();
|
||||
if (httpDataFactory != null) {
|
||||
logger.log(Level.FINEST, "cleaning http data factory");
|
||||
httpDataFactory.cleanAllHttpData();
|
||||
}
|
||||
});
|
||||
interaction.setSettingsPromise(channel.newPromise());
|
||||
lookupChannelInitializer(httpAddress)
|
||||
.init(channel, httpAddress, getClient(), builder.nettyCustomizer, interaction);
|
||||
|
|
|
@ -2,11 +2,13 @@ package org.xbib.net.http.client.netty;
|
|||
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.channel.WriteBufferWaterMark;
|
||||
import io.netty.handler.codec.http.multipart.HttpDataFactory;
|
||||
import io.netty.handler.codec.http2.Http2Settings;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.proxy.HttpProxyHandler;
|
||||
import io.netty.handler.proxy.Socks4ProxyHandler;
|
||||
import io.netty.handler.proxy.Socks5ProxyHandler;
|
||||
import io.netty.util.AttributeKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.xbib.net.SocketConfig;
|
||||
|
@ -16,6 +18,8 @@ import org.xbib.net.http.client.BackOff;
|
|||
|
||||
public class NettyHttpClientConfig {
|
||||
|
||||
public static final AttributeKey<HttpDataFactory> ATTRIBUTE_HTTP_DATAFACTORY = AttributeKey.valueOf("http_datafactory");
|
||||
|
||||
/**
|
||||
* If frame logging /traffic logging is enabled or not.
|
||||
*/
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package org.xbib.net.http.client.netty.http1;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpChunkedInput;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
|
@ -34,6 +31,7 @@ import org.xbib.net.http.HttpAddress;
|
|||
import org.xbib.net.http.HttpHeaders;
|
||||
import org.xbib.net.http.HttpResponseStatus;
|
||||
import org.xbib.net.http.client.Part;
|
||||
import org.xbib.net.http.client.netty.NettyHttpClientConfig;
|
||||
import org.xbib.net.http.cookie.Cookie;
|
||||
import org.xbib.net.http.client.cookie.CookieDecoder;
|
||||
import org.xbib.net.http.client.cookie.CookieEncoder;
|
||||
|
@ -131,25 +129,16 @@ public class Http1Interaction extends BaseInteraction {
|
|||
}
|
||||
io.netty.handler.codec.http.HttpRequest httpRequest = httpPostRequestEncoder.finalizeRequest();
|
||||
channel.write(httpRequest);
|
||||
} else {
|
||||
channel.write(fullHttpRequest);
|
||||
}
|
||||
channel.write(fullHttpRequest);
|
||||
if (httpPostRequestEncoder != null && httpPostRequestEncoder.isChunked()) {
|
||||
logger.log(Level.FINEST, "finish chunked HTTP POST encoder");
|
||||
channel.write(httpPostRequestEncoder);
|
||||
} else {
|
||||
logger.log(Level.FINEST, "HTTP POST encoder not chunked");
|
||||
}
|
||||
channel.flush();
|
||||
} catch (HttpPostRequestEncoder.ErrorDataEncoderException e) {
|
||||
throw new IOException(e);
|
||||
} finally {
|
||||
if (httpPostRequestEncoder != null) {
|
||||
logger.log(Level.FINEST, "cleaning files of HTTP POST encoder");
|
||||
//httpPostRequestEncoder.cleanFiles();
|
||||
}
|
||||
logger.log(Level.FINEST, "clean all http data");
|
||||
//httpDataFactory.cleanAllHttpData();
|
||||
channel.attr(NettyHttpClientConfig.ATTRIBUTE_HTTP_DATAFACTORY).set(httpDataFactory);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -39,37 +39,29 @@ public class HttpFileUploadHandler extends SimpleChannelInboundHandler<HttpObjec
|
|||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, HttpObject httpObject) {
|
||||
logger.log(Level.FINEST, "checking file upload");
|
||||
HttpRequest httpRequest = null;
|
||||
HttpPostRequestDecoder httpDecoder = null;
|
||||
if (httpObject instanceof HttpRequest) {
|
||||
httpRequest = (HttpRequest) httpObject;
|
||||
// peek into request if we have a POST request
|
||||
if (httpRequest.method() == HttpMethod.POST) {
|
||||
logger.log(Level.FINEST, "checking HTTP POST: success");
|
||||
HttpDataFactory factory = new DefaultHttpDataFactory(nettyHttpServer.getNettyHttpServerConfig().getFileUploadDiskThreshold());
|
||||
httpDecoder = new HttpPostRequestDecoder(factory, httpRequest);
|
||||
}
|
||||
}
|
||||
if (httpDecoder != null) {
|
||||
if (httpObject instanceof HttpContent chunk) {
|
||||
logger.log(Level.FINEST, "got chunk");
|
||||
httpDecoder.offer(chunk);
|
||||
try {
|
||||
while (httpDecoder.hasNext()) {
|
||||
InterfaceHttpData data = httpDecoder.next();
|
||||
logger.log(Level.FINEST, "got data");
|
||||
if (data != null) {
|
||||
try {
|
||||
if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
|
||||
logger.log(Level.FINEST, "got file upload");
|
||||
FileUpload fileUpload = (FileUpload) data;
|
||||
requestReceived(ctx, httpRequest, fileUpload);
|
||||
} else {
|
||||
logger.log(Level.FINEST, "got HTTP data type = " + data.getHttpDataType());
|
||||
}
|
||||
} finally {
|
||||
data.release();
|
||||
if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
|
||||
logger.log(Level.FINEST, "got file upload");
|
||||
FileUpload fileUpload = (FileUpload) data;
|
||||
requestReceived(ctx, httpRequest, fileUpload);
|
||||
} else {
|
||||
logger.log(Level.FINEST, "got HTTP data type = " + data.getHttpDataType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +69,8 @@ public class HttpFileUploadHandler extends SimpleChannelInboundHandler<HttpObjec
|
|||
logger.log(Level.FINEST, "end of data decoder exception");
|
||||
}
|
||||
if (chunk instanceof LastHttpContent) {
|
||||
//httpDecoder.destroy();
|
||||
logger.log(Level.FINEST, "destroying HTTP decode");
|
||||
httpDecoder.destroy();
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.FINEST, "not a HttpContent: " );
|
||||
|
|
Loading…
Reference in a new issue