netty5/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpDataFactory.java
Frederic Bregier caa1505020 Get uploaded size while upload is in progress
Proposal to fix issue #3636

Motivations:
Currently, while adding the next buffers to the decoder
(`decoder.offer()`), there is no way to access to the current HTTP
object being decoded since it can only be available currently once fully
decoded by `decoder.hasNext()`.
Some could want to know the progression on the overall transfer but also
per HTTP object.
While overall progression could be done using (if available) the global
Content-Length of the request and taking into account each HttpContent
size, the per HttpData object progression is unknown.

Modifications:
1) For HTTP object, `AbstractHttpData` has 2 protected properties named
`definedSize` and `size`, respectively the supposely final size and the
current (decoded until now) size.
This provides a new method `definedSize()` to get the current value for
`definedSize`. The `size` attribute is reachable by the `length()`
method.

Note however there are 2 different ways that currently managed the
`definedSize`:
a) `Attribute`: it is reset each time the value is less than actual
(when a buffer is added, the value is increased) since the final length
is not known (no Content-Length)
b) `FileUpload`: it is set at startup from the lengh provided

So these differences could lead in wrong perception;
a) `Attribute`: definedSize = size always
b) `FileUpload`: definedSize >= size always

Therefore the comment tries to explain clearly the different behaviors.

2) In the InterfaceHttpPostRequestDecoder (and the derived classes), I
add a new method: `decoder.currentPartialHttpData()` which will return a
`InterfaceHttpData` (if any) as the current `Attribute` or `FileUpload`
(the 2 generic types), which will allow then the programmer to check
according to the real type (instance of) the 2 methods `definedSize()`
and `length()`.

This method check if currentFileUpload or currentAttribute are null and
returns the one (only one could be not null) that is not null.

Note that if this method returns null, it might mean 2 situations:
a) the last `HttpData` (whatever attribute or file upload) is already
finished and therefore accessible through `next()`
b) there is not yet any `HttpData` in decoding (body not yet parsed for
instance)

Result:
The developper has more access and therefore control on the current
upload.
The coding from developper side could looks like in the example in
HttpUloadServerHandler.
2015-06-12 14:16:07 +02:00

94 lines
2.9 KiB
Java

/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.handler.codec.http.multipart;
import io.netty.handler.codec.http.HttpRequest;
import java.nio.charset.Charset;
/**
* Interface to enable creation of InterfaceHttpData objects
*/
public interface HttpDataFactory {
/**
* To set a max size limitation on fields. Exceeding it will generate an ErrorDataDecoderException.
* A value of -1 means no limitation (default).
*/
void setMaxLimit(long max);
/**
*
* @param request associated request
* @return a new Attribute with no value
*/
Attribute createAttribute(HttpRequest request, String name);
/**
* @param request associated request
* @param name name of the attribute
* @param definedSize defined size from request for this attribute
* @return a new Attribute with no value
*/
Attribute createAttribute(HttpRequest request, String name, long definedSize);
/**
* @param request associated request
* @return a new Attribute
*/
Attribute createAttribute(HttpRequest request, String name, String value);
/**
* @param request associated request
* @param size the size of the Uploaded file
* @return a new FileUpload
*/
FileUpload createFileUpload(HttpRequest request, String name, String filename,
String contentType, String contentTransferEncoding, Charset charset,
long size);
/**
* Remove the given InterfaceHttpData from clean list (will not delete the file, except if the file
* is still a temporary one as setup at construction)
* @param request associated request
*/
void removeHttpDataFromClean(HttpRequest request, InterfaceHttpData data);
/**
* Remove all InterfaceHttpData from virtual File storage from clean list for the request
*
* @param request associated request
*/
void cleanRequestHttpData(HttpRequest request);
/**
* Remove all InterfaceHttpData from virtual File storage from clean list for all requests
*/
void cleanAllHttpData();
/**
* @deprecated Use {@link #cleanRequestHttpData(HttpRequest)} instead.
*/
@Deprecated
void cleanRequestHttpDatas(HttpRequest request);
/**
* @deprecated Use {@link #cleanAllHttpData()} instead.
*/
@Deprecated
void cleanAllHttpDatas();
}