Search in sources :

Example 21 with HttpPostRequestEncoder

use of io.netty.handler.codec.http.multipart.HttpPostRequestEncoder in project ambry by linkedin.

the class NettyMultipartRequestTest method sizeLimitationTest.

/**
 * Tests to make sure the max allowed size for multipart requests is enforced.
 * @throws Exception
 */
// Disabling test because the encoded size is different at different times and it is hard to predict. Need a better
// test
// @Test
public void sizeLimitationTest() throws Exception {
    int blobPartSize = 1024;
    byte[] bytes = TestUtils.getRandomBytes(blobPartSize);
    int encodedSize = getEncodedSize(bytes);
    long[] maxSizesAllowed = { encodedSize + 1, encodedSize, encodedSize - 1, 0 };
    for (long maxSizeAllowed : maxSizesAllowed) {
        InMemoryFile[] files = { new InMemoryFile(RestUtils.MultipartPost.BLOB_PART, ByteBuffer.wrap(bytes)) };
        HttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/");
        HttpPostRequestEncoder encoder = createEncoder(httpRequest, files);
        NettyMultipartRequest request = new NettyMultipartRequest(encoder.finalizeRequest(), new MockChannel(), NETTY_METRICS, Collections.emptySet(), maxSizeAllowed);
        assertTrue("Request channel is not open", request.isOpen());
        long currentSizeAdded = 0;
        boolean failedToAdd = false;
        while (!encoder.isEndOfInput()) {
            HttpContent httpContent = encoder.readChunk(PooledByteBufAllocator.DEFAULT);
            int readableBytes = httpContent.content().readableBytes();
            if (currentSizeAdded + readableBytes <= maxSizeAllowed) {
                request.addContent(httpContent);
            } else {
                assertTrue("Max size [" + maxSizeAllowed + "] must be lesser than content size: " + encodedSize, maxSizeAllowed < encodedSize);
                try {
                    request.addContent(httpContent);
                    fail("Should have failed to add content of size [" + encodedSize + "] because it is over the max size allowed: " + maxSizeAllowed);
                } catch (RestServiceException e) {
                    failedToAdd = true;
                    assertEquals("Unexpected RestServiceErrorCode", RestServiceErrorCode.RequestTooLarge, e.getErrorCode());
                    break;
                }
            }
            currentSizeAdded += readableBytes;
        }
        assertEquals("Success state not as expected. maxSizeAllowed=[" + maxSizeAllowed + "], encodedSize expected=[" + encodedSize + "], actual size added=[" + currentSizeAdded + "]", maxSizeAllowed < encodedSize, failedToAdd);
    }
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) DefaultHttpRequest(io.netty.handler.codec.http.DefaultHttpRequest) HttpRequest(io.netty.handler.codec.http.HttpRequest) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) HttpPostRequestEncoder(io.netty.handler.codec.http.multipart.HttpPostRequestEncoder) HttpContent(io.netty.handler.codec.http.HttpContent) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent)

Example 22 with HttpPostRequestEncoder

use of io.netty.handler.codec.http.multipart.HttpPostRequestEncoder in project ambry by linkedin.

the class NettyMultipartRequestTest method getEncodedSize.

// sizeLimitationTest() helpers
/**
 * Gets the encoded size for a set of bytes
 * @param bytes the bytes to encode.
 * @return the encoded size
 * @throws Exception
 */
private int getEncodedSize(byte[] bytes) throws Exception {
    int encodedSize = 0;
    InMemoryFile[] files = { new InMemoryFile(RestUtils.MultipartPost.BLOB_PART, ByteBuffer.wrap(bytes)) };
    HttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/");
    HttpPostRequestEncoder encoder = createEncoder(httpRequest, files);
    encoder.finalizeRequest();
    while (!encoder.isEndOfInput()) {
        HttpContent httpContent = encoder.readChunk(PooledByteBufAllocator.DEFAULT);
        encodedSize += httpContent.content().readableBytes();
    }
    return encodedSize;
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) DefaultHttpRequest(io.netty.handler.codec.http.DefaultHttpRequest) HttpRequest(io.netty.handler.codec.http.HttpRequest) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) HttpPostRequestEncoder(io.netty.handler.codec.http.multipart.HttpPostRequestEncoder) HttpContent(io.netty.handler.codec.http.HttpContent) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent)

Example 23 with HttpPostRequestEncoder

use of io.netty.handler.codec.http.multipart.HttpPostRequestEncoder in project ambry by linkedin.

the class NettyMultipartRequestTest method createEncoder.

/**
 * Creates a {@link HttpPostRequestEncoder} that encodes the given {@code request} and {@code parts}.
 * @param request the {@link HttpRequest} containing headers and other metadata about the request.
 * @param parts the {@link InMemoryFile}s that will form the parts of the request.
 * @return a {@link HttpPostRequestEncoder} that can encode the {@code request} and {@code parts}.
 * @throws HttpPostRequestEncoder.ErrorDataEncoderException
 * @throws IOException
 */
private HttpPostRequestEncoder createEncoder(HttpRequest request, InMemoryFile[] parts) throws HttpPostRequestEncoder.ErrorDataEncoderException, IOException {
    HttpDataFactory httpDataFactory = new DefaultHttpDataFactory(false);
    HttpPostRequestEncoder encoder = new HttpPostRequestEncoder(httpDataFactory, request, true);
    if (parts != null) {
        for (InMemoryFile part : parts) {
            FileUpload fileUpload = new MemoryFileUpload(part.name, part.name, "application/octet-stream", "", Charset.forName("UTF-8"), part.content.remaining());
            fileUpload.setContent(Unpooled.wrappedBuffer(part.content));
            encoder.addBodyHttpData(fileUpload);
        }
    }
    return encoder;
}
Also used : HttpPostRequestEncoder(io.netty.handler.codec.http.multipart.HttpPostRequestEncoder) DefaultHttpDataFactory(io.netty.handler.codec.http.multipart.DefaultHttpDataFactory) MemoryFileUpload(io.netty.handler.codec.http.multipart.MemoryFileUpload) MemoryFileUpload(io.netty.handler.codec.http.multipart.MemoryFileUpload) FileUpload(io.netty.handler.codec.http.multipart.FileUpload) DefaultHttpDataFactory(io.netty.handler.codec.http.multipart.DefaultHttpDataFactory) HttpDataFactory(io.netty.handler.codec.http.multipart.HttpDataFactory)

Example 24 with HttpPostRequestEncoder

use of io.netty.handler.codec.http.multipart.HttpPostRequestEncoder in project ambry by linkedin.

the class NettyMultipartRequestTest method prepareTest.

/**
 * Tests different scenarios with {@link NettyMultipartRequest#prepare()}.
 * Currently tests:
 * 1. Idempotency of {@link NettyMultipartRequest#prepare()}.
 * 2. Exception scenarios of {@link NettyMultipartRequest#prepare()}.
 * @throws Exception
 */
@Test
public void prepareTest() throws Exception {
    // prepare half baked data
    HttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/");
    HttpPostRequestEncoder encoder = createEncoder(httpRequest, null);
    NettyMultipartRequest request = new NettyMultipartRequest(encoder.finalizeRequest(), new MockChannel(), NETTY_METRICS, Collections.emptySet(), Long.MAX_VALUE);
    assertTrue("Request channel is not open", request.isOpen());
    // insert random data
    HttpContent httpContent = new DefaultHttpContent(Unpooled.wrappedBuffer(TestUtils.getRandomBytes(10)));
    request.addContent(httpContent);
    // prepare should fail
    try {
        request.prepare();
        fail("Preparing request should have failed");
    } catch (HttpPostRequestDecoder.NotEnoughDataDecoderException e) {
        assertEquals("Reference count is not as expected", 1, httpContent.refCnt());
    } finally {
        closeRequestAndValidate(request);
    }
    // more than one blob part
    HttpHeaders httpHeaders = new DefaultHttpHeaders();
    httpHeaders.set(RestUtils.Headers.BLOB_SIZE, 256);
    InMemoryFile[] files = new InMemoryFile[2];
    files[0] = new InMemoryFile(RestUtils.MultipartPost.BLOB_PART, ByteBuffer.wrap(TestUtils.getRandomBytes(256)));
    files[1] = new InMemoryFile(RestUtils.MultipartPost.BLOB_PART, ByteBuffer.wrap(TestUtils.getRandomBytes(256)));
    request = createRequest(httpHeaders, files);
    assertEquals("Request size does not match", 256, request.getSize());
    try {
        request.prepare();
        fail("Prepare should have failed because there was more than one " + RestUtils.MultipartPost.BLOB_PART);
    } catch (RestServiceException e) {
        assertEquals("Unexpected RestServiceErrorCode", RestServiceErrorCode.BadRequest, e.getErrorCode());
    } finally {
        closeRequestAndValidate(request);
    }
    // more than one part named "part-1"
    files = new InMemoryFile[2];
    files[0] = new InMemoryFile("Part-1", ByteBuffer.wrap(TestUtils.getRandomBytes(256)));
    files[1] = new InMemoryFile("Part-1", ByteBuffer.wrap(TestUtils.getRandomBytes(256)));
    request = createRequest(null, files);
    try {
        request.prepare();
        fail("Prepare should have failed because there was more than one part named Part-1");
    } catch (RestServiceException e) {
        assertEquals("Unexpected RestServiceErrorCode", RestServiceErrorCode.BadRequest, e.getErrorCode());
    } finally {
        closeRequestAndValidate(request);
    }
    // size of blob does not match the advertized size
    httpHeaders = new DefaultHttpHeaders();
    httpHeaders.set(RestUtils.Headers.BLOB_SIZE, 256);
    files = new InMemoryFile[1];
    files[0] = new InMemoryFile(RestUtils.MultipartPost.BLOB_PART, ByteBuffer.wrap(TestUtils.getRandomBytes(128)));
    request = createRequest(httpHeaders, files);
    try {
        request.prepare();
        fail("Prepare should have failed because the size advertised does not match the actual size");
    } catch (RestServiceException e) {
        assertEquals("Unexpected RestServiceErrorCode", RestServiceErrorCode.BadRequest, e.getErrorCode());
    } finally {
        closeRequestAndValidate(request);
    }
    // non fileupload (file attribute present)
    httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/");
    httpRequest.headers().set(RestUtils.Headers.BLOB_SIZE, 256);
    files = new InMemoryFile[1];
    files[0] = new InMemoryFile(RestUtils.MultipartPost.BLOB_PART, ByteBuffer.wrap(TestUtils.getRandomBytes(256)));
    encoder = createEncoder(httpRequest, files);
    encoder.addBodyAttribute("dummyKey", "dummyValue");
    request = new NettyMultipartRequest(encoder.finalizeRequest(), new MockChannel(), NETTY_METRICS, Collections.emptySet(), Long.MAX_VALUE);
    assertTrue("Request channel is not open", request.isOpen());
    while (!encoder.isEndOfInput()) {
        // Sending null for ctx because the encoder is OK with that.
        request.addContent(encoder.readChunk(PooledByteBufAllocator.DEFAULT));
    }
    try {
        request.prepare();
        fail("Prepare should have failed because there was non fileupload");
    } catch (RestServiceException e) {
        assertEquals("Unexpected RestServiceErrorCode", RestServiceErrorCode.BadRequest, e.getErrorCode());
    } finally {
        closeRequestAndValidate(request);
    }
    // size of blob is not set. Prepare should succeed.
    httpHeaders = new DefaultHttpHeaders();
    files = new InMemoryFile[1];
    files[0] = new InMemoryFile(RestUtils.MultipartPost.BLOB_PART, ByteBuffer.wrap(TestUtils.getRandomBytes(128)));
    request = createRequest(httpHeaders, files);
    try {
        request.prepare();
    } finally {
        closeRequestAndValidate(request);
    }
}
Also used : DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) DefaultHttpRequest(io.netty.handler.codec.http.DefaultHttpRequest) HttpRequest(io.netty.handler.codec.http.HttpRequest) HttpHeaders(io.netty.handler.codec.http.HttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) HttpPostRequestEncoder(io.netty.handler.codec.http.multipart.HttpPostRequestEncoder) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent) HttpPostRequestDecoder(io.netty.handler.codec.http.multipart.HttpPostRequestDecoder) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) HttpContent(io.netty.handler.codec.http.HttpContent) DefaultHttpContent(io.netty.handler.codec.http.DefaultHttpContent) Test(org.junit.Test)

Example 25 with HttpPostRequestEncoder

use of io.netty.handler.codec.http.multipart.HttpPostRequestEncoder in project ambry by linkedin.

the class NettyMessageProcessorTest method createEncoder.

// multipartPostTest() helpers.
/**
 * Creates a {@link HttpPostRequestEncoder} that encodes the given {@code request} and {@code blobContent}.
 * @param request the {@link HttpRequest} containing headers and other metadata about the request.
 * @param blobContent the {@link ByteBuffer} that represents the content of the blob.
 * @return a {@link HttpPostRequestEncoder} that can encode the {@code request} and {@code blobContent}.
 * @throws HttpPostRequestEncoder.ErrorDataEncoderException
 * @throws IOException
 */
private HttpPostRequestEncoder createEncoder(HttpRequest request, ByteBuffer blobContent) throws HttpPostRequestEncoder.ErrorDataEncoderException, IOException {
    HttpDataFactory httpDataFactory = new DefaultHttpDataFactory(false);
    HttpPostRequestEncoder encoder = new HttpPostRequestEncoder(httpDataFactory, request, true);
    FileUpload fileUpload = new MemoryFileUpload(RestUtils.MultipartPost.BLOB_PART, RestUtils.MultipartPost.BLOB_PART, "application/octet-stream", "", Charset.forName("UTF-8"), blobContent.remaining());
    fileUpload.setContent(Unpooled.wrappedBuffer(blobContent));
    encoder.addBodyHttpData(fileUpload);
    return encoder;
}
Also used : HttpPostRequestEncoder(io.netty.handler.codec.http.multipart.HttpPostRequestEncoder) DefaultHttpDataFactory(io.netty.handler.codec.http.multipart.DefaultHttpDataFactory) MemoryFileUpload(io.netty.handler.codec.http.multipart.MemoryFileUpload) MemoryFileUpload(io.netty.handler.codec.http.multipart.MemoryFileUpload) FileUpload(io.netty.handler.codec.http.multipart.FileUpload) HttpDataFactory(io.netty.handler.codec.http.multipart.HttpDataFactory) DefaultHttpDataFactory(io.netty.handler.codec.http.multipart.DefaultHttpDataFactory)

Aggregations

HttpPostRequestEncoder (io.netty.handler.codec.http.multipart.HttpPostRequestEncoder)38 HttpRequest (io.netty.handler.codec.http.HttpRequest)20 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)16 DefaultHttpRequest (io.netty.handler.codec.http.DefaultHttpRequest)13 DefaultHttpDataFactory (io.netty.handler.codec.http.multipart.DefaultHttpDataFactory)9 MemoryFileUpload (io.netty.handler.codec.http.multipart.MemoryFileUpload)9 Channel (io.netty.channel.Channel)8 ChannelFuture (io.netty.channel.ChannelFuture)8 HttpDataFactory (io.netty.handler.codec.http.multipart.HttpDataFactory)7 File (java.io.File)7 IOException (java.io.IOException)7 FullHttpRequest (io.netty.handler.codec.http.FullHttpRequest)6 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)5 FileUpload (io.netty.handler.codec.http.multipart.FileUpload)5 InterfaceHttpData (io.netty.handler.codec.http.multipart.InterfaceHttpData)5 Test (org.junit.Test)5 ByteBuf (io.netty.buffer.ByteBuf)4 URISyntaxException (java.net.URISyntaxException)4 ByteBuffer (java.nio.ByteBuffer)4 ResponseParts (com.github.ambry.rest.NettyClient.ResponseParts)3