Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
197 views
in Technique[技术] by (71.8m points)

file upload - use HttpObjectAggregator conditionally

Netty version: 4.0.37

I have a requirement to have a netty server which handles both simple JSON requests and also large file uploads. HttpObjectAggregator has a limit of 2 GB for a request size, so I would prefer to use the HttpUploadServer example available here.

So, I want the pipeline to conditionally change depending on the type of request coming in. If it's a POST request, and it's a Multipart type of request, I want the request to be handled by the Upload handler and I want to skip all the rest of the handlers. If not, I want it to pass through the HttpObjectAggregator and then be handled by the Default handler.

I thought of creating one single pipeline looking like this:

HttpRequestDecoder
HttpContentDecompressor
FileUploadHandler <--- My handler to handle file uploads
HttpObjectAggregator 
DefaultHandler <---- My handler to handle normal requests, without file body

And inside the "FileUploadHandler", I added the if else logic like this:

private boolean uploadURL(HttpObject object) {
    HttpRequest request = (HttpRequest) object;
    boolean isMultipart = HttpPostRequestDecoder.isMultipart(request);
    if (request.getMethod().equals(HttpMethod.POST) && isMultipart) {
      // To be handled by file upload handler
      return true;
    }
    return false;
  }

public void channelRead0(ChannelHandlerContext channelHandlerContext,
    HttpObject object) throws Exception {

if (!uploadURL(object)) {
    ReferenceCountUtil.retain(object);
    channelHandlerContext.fireChannelRead(object);
} else {
// Handle the File Upload
....

My objective was to make the UploadHandler "pass on" the message to HttpObjectAggregator IF it's anything other than a POST Multipart request with file body. However, this isn't working for a GET request as the request times out after sometime for lack of a response. I don't entirely understand why this is happening, but my guess is that HttpObjectAggregator is not receiving the initial HttpRequest object from my UploadHandler at all? And that in turn, isn't delivering it to the Default Handler either.

  1. Is my approach wrong? Is there a different way of handling this conditional routing, outside of my Upload Handler?
  2. Can I have any handler before HttpObjectAggregator or should all custom/user handlers come AFTER the HttpObjectAggregator?
question from:https://stackoverflow.com/questions/65842439/use-httpobjectaggregator-conditionally

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I did this by using a Decoder before HttpObjectAggregator. The pipeline looks like:

HttpRequestDecoder
HttpContentDecompressor
RequestURLDecoder <--- New decoder to route requests.
FileUploadHandler <--- My handler to handle file uploads
HttpObjectAggregator 
DefaultHandler <---- My handler to handle normal requests, without file body

The new decoder looks at the request and if it's a POST multipart, dynamically modifies the pipeline to remove the Object aggregator and the default handler. If it's not, then it removes the file upload handler.

(list.add(ReferenceCountUtil.retain(object)) is very important!)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...