Java tutorial
/* * Copyright (c) 2011 Sergey Prilukin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package anhttpclient; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import anhttpclient.impl.DefaultWebBrowser; import anhttpclient.impl.request.HttpDeleteWebRequest; import anhttpclient.impl.request.HttpGetWebRequest; import anhttpclient.impl.request.HttpHeadWebRequest; import anhttpclient.impl.request.HttpOptionsWebRequest; import anhttpclient.impl.request.HttpPostWebRequest; import anhttpclient.impl.request.HttpPutWebRequest; import anhttpclient.impl.request.HttpTraceWebRequest; import anhttpserver.ByteArrayHandlerAdapter; import anhttpserver.DefaultHttpServer; import anhttpserver.HttpRequestContext; import anhttpserver.HttpServer; import org.apache.http.cookie.Cookie; import org.apache.http.protocol.HTTP; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.GZIPOutputStream; /** * Tests http client * * @author Sergey Prilukin */ public class AnhttpclientTest { private WebBrowser wb; private Properties defaultHeaders; private Map<RequestMethod, Class<? extends WebRequest>> allRequests; private HttpServer server; @Before public void initialize() throws Exception { InputStream headersAsStream = Thread.currentThread().getContextClassLoader() .getResourceAsStream("anhttpclient/defaultheaders.properties"); defaultHeaders = new Properties(); defaultHeaders.load(headersAsStream); wb = new DefaultWebBrowser(); wb.setDefaultHeaders(defaultHeaders); wb.setSocketTimeout(100); allRequests = new HashMap<RequestMethod, Class<? extends WebRequest>>(7); allRequests.put(RequestMethod.GET, HttpGetWebRequest.class); allRequests.put(RequestMethod.POST, HttpPostWebRequest.class); allRequests.put(RequestMethod.DELETE, HttpDeleteWebRequest.class); allRequests.put(RequestMethod.HEAD, HttpHeadWebRequest.class); allRequests.put(RequestMethod.OPTIONS, HttpOptionsWebRequest.class); allRequests.put(RequestMethod.PUT, HttpPutWebRequest.class); allRequests.put(RequestMethod.TRACE, HttpTraceWebRequest.class); server = new DefaultHttpServer(); server.start(); } @After public void finish() { server.stop(); } @Test public void testRequestMethodsAndDefaultHeadersAndHostAndResponseText() throws Exception { final String methodParamName = "method"; final String responseText = "Hello from SimpleHttperver"; server.addHandler("/index", new ByteArrayHandlerAdapter() { public byte[] getResponseAsByteArray(HttpRequestContext httpRequestContext) throws IOException { URI requestURI = httpRequestContext.getRequestURI(); assertEquals(methodParamName, requestURI.getQuery().split("=")[0]); String method = requestURI.getQuery().split("=")[1]; assertEquals("Method should be " + method, method, httpRequestContext.getRequestMethod()); //In PUT and POST methods Content-length headers should be added int headersSize = method.equals(RequestMethod.POST.toString()) || method.equals(RequestMethod.PUT.toString()) ? defaultHeaders.size() + 1 : defaultHeaders.size(); assertEquals("Count of request headers is incorrect", headersSize, httpRequestContext.getRequestHeaders().size() - 1); assertEquals("Host request header is unexpected", httpRequestContext.getRequestHeaders().get("Host").get(0), DefaultHttpServer.DEFAULT_HOST + ":" + server.getPort()); for (Map.Entry<String, List<String>> entry : httpRequestContext.getRequestHeaders().entrySet()) { if ("Content-length".equalsIgnoreCase(entry.getKey())) { //assertEquals(httpRequestContext.getRequestBody().length, // Integer.valueOf(entry.getValue().get(0)).intValue()); continue; } else if ("Host".equalsIgnoreCase(entry.getKey())) { continue; } //Test default headers assertEquals(String.format("sent header [%s] not equals to received one", entry.getKey()), defaultHeaders.get(entry.getKey()), entry.getValue().get(0)); } return responseText.getBytes(); } }); for (Map.Entry<RequestMethod, Class<? extends WebRequest>> entry : allRequests.entrySet()) { WebRequest req = entry.getValue().newInstance(); req.setUrl(server.getBaseUrl() + "/index"); req.addParam(methodParamName, entry.getKey().toString()); WebResponse resp = wb.getResponse(req); if (!entry.getKey().equals(RequestMethod.HEAD)) { assertEquals("Response from server is incorrect", responseText, resp.getText()); } else { assertNull(resp.getBytes()); } } } @Test public void testFormParamsRequest() throws Exception { final Map<String, String> params = new HashMap<String, String>(); params.put("email", "sss@ggg.com"); params.put("space", "aaa bbb"); params.put("russian", ""); params.put("some_chars", "!@#$%^&*()_+|"); server.addHandler("/formParams", new ByteArrayHandlerAdapter() { public byte[] getResponseAsByteArray(HttpRequestContext httpRequestContext) throws IOException { assertEquals("Form should be url-encoded", "application/x-www-form-urlencoded; charset=UTF-8", httpRequestContext.getRequestHeaders().get(HTTP.CONTENT_TYPE).get(0)); assertEquals(httpRequestContext.getRequestBody().length, Integer .valueOf(httpRequestContext.getRequestHeaders().get("Content-length").get(0)).intValue()); try { String postParams = new String(httpRequestContext.getRequestBody()); String[] paramValuePairs = postParams.split("\\&"); for (String paramValuePair : paramValuePairs) { String[] paramValueArray = paramValuePair.split("\\="); String param = paramValueArray[0]; String value = java.net.URLDecoder.decode(paramValueArray[1], "UTF-8"); assertEquals("incorrect param value", value, params.get(param)); } } catch (IOException e) { throw new RuntimeException(e); } return "OK".getBytes(); } }); for (Map.Entry<RequestMethod, Class<? extends WebRequest>> entry : allRequests.entrySet()) { if (entry.getKey().equals(RequestMethod.POST) || entry.getKey().equals(RequestMethod.PUT)) { EntityEnclosingWebRequest req = (EntityEnclosingWebRequest) entry.getValue().newInstance(); req.setUrl(server.getBaseUrl() + "/formParams"); req.addFormParams(params); wb.getResponse(req); } } } @Test public void testGzipResponse() throws Exception { final String responseText = "Hello from SimpleHttperver"; server.addHandler("/gzip", new ByteArrayHandlerAdapter() { public byte[] getResponseAsByteArray(HttpRequestContext httpRequestContext) { byte[] out; try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStream os = new GZIPOutputStream(baos); os.write(responseText.getBytes()); os.flush(); os.close(); out = baos.toByteArray(); } catch (IOException e) { throw new RuntimeException(e); } setResponseHeader("Content-Encoding", "gzip", httpRequestContext); return out; } }); WebRequest req = new HttpGetWebRequest(server.getBaseUrl() + "/gzip"); WebResponse resp = wb.getResponse(req); assertEquals("Response from server is incorrect", responseText, resp.getText()); } @Test public void testPostWithBodyRequest() throws Exception { final String requestParam1 = "Test request body"; final String requestParam2 = "Test request body string"; final byte[] body = requestParam1.getBytes(); final String requestBody = "--zeNfQFxOvIRY_1tTWU-9ArUdJpMkKi9\n" + "Content-Disposition: form-data; name=\"param1\"\n" + "Content-Type: application/octet-stream\n" + "Content-Transfer-Encoding: binary\n" + "\n" + "Test request body\n" + "--zeNfQFxOvIRY_1tTWU-9ArUdJpMkKi9\n" + "Content-Disposition: form-data; name=\"param2\"\n" + "Content-Type: text/plain; charset=US-ASCII\n" + "Content-Transfer-Encoding: 8bit\n" + "\n" + "Test request body string\n" + "--zeNfQFxOvIRY_1tTWU-9ArUdJpMkKi9--"; server.addHandler("/postWithBody", new ByteArrayHandlerAdapter() { public byte[] getResponseAsByteArray(HttpRequestContext httpRequestContext) { byte[] body = httpRequestContext.getRequestBody(); assertEquals(requestBody.replaceAll("--.*", "").replaceAll("[\\r\\n]+", "\\n"), new String(body).replaceAll("--.*", "").replaceAll("[\\r\\n]+", "\\n")); assertEquals("Method should be POST", "POST", httpRequestContext.getRequestMethod()); assertTrue(httpRequestContext.getRequestHeaders().get(HTTP.CONTENT_TYPE).get(0) .contains("multipart/form-data")); return "OK".getBytes(); } }); for (Map.Entry<RequestMethod, Class<? extends WebRequest>> entry : allRequests.entrySet()) { if (entry.getKey().equals(RequestMethod.POST) || entry.getKey().equals(RequestMethod.PUT)) { EntityEnclosingWebRequest req = new HttpPostWebRequest(server.getBaseUrl() + "/postWithBody"); req.addPart("param1", body); req.addPart("param2", requestParam2); wb.getResponse(req); } } } @Test public void testCookies() throws Exception { final String cookieName1 = "PREF"; final String cookieValue1 = "ID=120db22e4e2810cb:FF=0:TM=1318488512:LM=1318488512:S=tTZoDOAsNIbsiH4R"; final String cookieParams1 = "expires=Sat, 12-Oct-2099 06:48:32 GMT; path=/; domain=localhost"; final String cookieName2 = "NID"; final String cookieValue2 = "52=fa8SxaS_YoBUQ7jLIy9bp14biO"; final String cookieParams2 = "expires=Fri, 13-Apr-2099 06:48:32 GMT; path=/; domain=localhost; HttpOnly"; final AtomicInteger requestCount = new AtomicInteger(0); server.addHandler("/cookies", new ByteArrayHandlerAdapter() { public byte[] getResponseAsByteArray(HttpRequestContext httpRequestContext) { requestCount.addAndGet(1); if (requestCount.get() == 1) { setResponseHeader("Set-Cookie", cookieName1 + "=" + cookieValue1 + "; " + cookieParams1, httpRequestContext); } else if (requestCount.get() == 2) { assertEquals(cookieName1 + "=" + cookieValue1, httpRequestContext.getRequestHeaders().get("Cookie").get(0)); setResponseHeader("Set-Cookie", cookieName2 + "=" + cookieValue2 + "; " + cookieParams2, httpRequestContext); } else { //Sends only one cookie somewhy //assertEquals(cookieName1 + "; " + cookieName2, httpRequestContext.getRequestHeaders().get("Cookie")); } return "OK".getBytes(); } }); WebRequest req = new HttpGetWebRequest(server.getBaseUrl() + "/cookies"); wb.getResponse(req); Cookie cookie1 = wb.getCookieByName(cookieName1); assertEquals("Invalid cookie 1", cookieName1, cookie1.getName()); assertEquals("Invalid cookie 1", cookieValue1, cookie1.getValue()); wb.getResponse(req); cookie1 = wb.getCookieByName(cookieName1); assertEquals("Invalid cookie 1", cookieName1, cookie1.getName()); assertEquals("Invalid cookie 1", cookieValue1, cookie1.getValue()); Cookie cookie2 = wb.getCookieByName(cookieName2); assertEquals("Invalid cookie 2", cookieName2, cookie2.getName()); assertEquals("Invalid cookie2", cookieValue2, cookie2.getValue()); wb.getResponse(req); } }