com.king.platform.net.http.integration.HttpPostWithInputStreamBody.java Source code

Java tutorial

Introduction

Here is the source code for com.king.platform.net.http.integration.HttpPostWithInputStreamBody.java

Source

// Copyright (C) king.com Ltd 2015
// https://github.com/king/king-http-client
// Author: Magnus Gustafsson
// License: Apache 2.0, https://raw.github.com/king/king-http-client/LICENSE-APACHE

package com.king.platform.net.http.integration;

import com.king.platform.net.http.HttpClient;
import com.king.platform.net.http.netty.request.HttpBody;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelProgressivePromise;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Random;
import java.util.concurrent.atomic.AtomicReference;

import static org.junit.Assert.*;

public class HttpPostWithInputStreamBody {
    IntegrationServer integrationServer;
    private HttpClient httpClient;
    private int port;

    private String okBody = "EVERYTHING IS OKAY!";
    private byte[] content;

    @Before
    public void setUp() throws Exception {
        content = new byte[1024 * 16];
        new Random().nextBytes(content);

        integrationServer = new JettyIntegrationServer();
        integrationServer.start();
        port = integrationServer.getPort();

        httpClient = new TestingHttpClientFactory().create();
        httpClient.start();

    }

    @Test
    public void postBody() throws Exception {
        final AtomicReference<byte[]> bodyContent = new AtomicReference<>();
        integrationServer.addServlet(new HttpServlet() {
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException {
                byte[] body = readPostBody(req);
                bodyContent.set(body);
                resp.getWriter().write(okBody);
                resp.getWriter().flush();
            }
        }, "/testOk");

        BlockingHttpCallback httpCallback = new BlockingHttpCallback();
        httpClient.createPost("http://localhost:" + port + "/testOk").content(content).build()
                .withHttpCallback(httpCallback).execute();

        httpCallback.waitForCompletion();

        assertArrayEquals(content, bodyContent.get());
        assertEquals(200, httpCallback.getStatusCode());

    }

    private byte[] readPostBody(HttpServletRequest req) throws IOException {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            byte[] data = new byte[4096];
            int bytesRead;
            while ((bytesRead = req.getInputStream().read(data, 0, data.length)) >= 0) {
                baos.write(data, 0, bytesRead);
            }

            return baos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }

    }

    @Test
    public void postBodyAsStream() throws Exception {
        final AtomicReference<byte[]> bodyContent = new AtomicReference<>();
        integrationServer.addServlet(new HttpServlet() {
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException {
                byte[] body = readPostBody(req);
                bodyContent.set(body);

                resp.getWriter().write(okBody);
                resp.getWriter().flush();
            }
        }, "/testOk");

        BlockingHttpCallback httpCallback = new BlockingHttpCallback();
        httpClient.createPost("http://localhost:" + port + "/testOk").content(new ByteArrayInputStream(content))
                .build().withHttpCallback(httpCallback).execute();

        httpCallback.waitForCompletion();

        assertArrayEquals(content, bodyContent.get());
        assertEquals(200, httpCallback.getStatusCode());

    }

    @Test
    public void postBodyCustomHttpBody() throws Exception {
        final AtomicReference<byte[]> bodyContent = new AtomicReference<>();
        integrationServer.addServlet(new HttpServlet() {
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException {
                byte[] body = readPostBody(req);
                bodyContent.set(body);

                resp.getWriter().write(okBody);
                resp.getWriter().flush();
            }
        }, "/testOk");

        BlockingHttpCallback httpCallback = new BlockingHttpCallback();
        httpClient.createPost("http://localhost:" + port + "/testOk").content(new HttpBody() {
            @Override
            public long getContentLength() {
                return content.length;
            }

            @Override
            public String getContentType() {
                return "application/binary";
            }

            @Override
            public Charset getCharacterEncoding() {
                return StandardCharsets.ISO_8859_1;
            }

            @Override
            public ChannelFuture writeContent(final ChannelHandlerContext ctx, boolean isSecure)
                    throws IOException {
                final ChannelProgressivePromise promise = ctx.newProgressivePromise();
                promise.setProgress(0, content.length);
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        int index = 0;
                        int length = 1024;
                        while (true) {
                            ByteBuf byteBuf = ctx.alloc().buffer(length).writeBytes(content, index, length);
                            ctx.writeAndFlush(byteBuf).awaitUninterruptibly();
                            index += length;
                            if (index >= content.length) {
                                break;
                            }

                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException ignored) {
                            }

                            promise.setProgress(index, content.length);
                        }

                        promise.setSuccess();
                    }
                }).start();

                return promise;
            }
        }).build().withHttpCallback(httpCallback).execute();

        httpCallback.waitForCompletion();

        assertArrayEquals(content, bodyContent.get());
        assertEquals(200, httpCallback.getStatusCode());
    }

    @Test
    public void postBodyWithContentType() throws Exception {
        final AtomicReference<String> contentTypeValue = new AtomicReference<>();
        integrationServer.addServlet(new HttpServlet() {
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException {
                contentTypeValue.set(req.getContentType());

                resp.getWriter().write(okBody);
                resp.getWriter().flush();
            }
        }, "/testOk");

        BlockingHttpCallback httpCallback = new BlockingHttpCallback();
        String contentType = "text/unit test";

        httpClient.createPost("http://localhost:" + port + "/testOk").content(content).contentType(contentType)
                .build().withHttpCallback(httpCallback).execute();

        httpCallback.waitForCompletion();

        assertEquals(okBody, httpCallback.getBody());
        assertEquals(200, httpCallback.getStatusCode());
        assertTrue(contentTypeValue.get().startsWith(contentType));

    }

    @After
    public void tearDown() throws Exception {
        integrationServer.shutdown();
        httpClient.shutdown();

    }

}