package org.webpieces.httpfrontend2.api.http1; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.junit.Assert; import org.junit.Test; import org.webpieces.data.api.DataWrapper; import org.webpieces.frontend2.impl.translation.Http2Translations; import org.webpieces.httpfrontend2.api.Responses; import org.webpieces.httpfrontend2.api.mock2.MockHttp2RequestListener.PassedIn; import org.webpieces.httpparser.api.common.Header; import org.webpieces.httpparser.api.common.KnownHeaderName; import org.webpieces.httpparser.api.dto.HttpChunk; import org.webpieces.httpparser.api.dto.HttpLastChunk; import org.webpieces.httpparser.api.dto.HttpPayload; import org.webpieces.httpparser.api.dto.HttpRequest; import org.webpieces.httpparser.api.dto.HttpResponse; import org.webpieces.httpparser.api.dto.KnownHttpMethod; import com.webpieces.hpack.api.dto.Http2Headers; import com.webpieces.http2engine.api.StreamWriter; import com.webpieces.http2parser.api.dto.DataFrame; public class TestHttp11Basic extends AbstractHttp1Test { @Test public void testConnectionKeepAliveOffAndFrontEndCloses() { } @Test public void testConnectionKeepAliveOn() { } @Test public void testFileUploadWithMultipartFormData() { } @Test public void testFileDownloadWithChunking() throws InterruptedException, ExecutionException, TimeoutException { HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/xxxx"); mockChannel.write(req); PassedIn in1 = mockListener.getSingleRequest(); HttpRequest req1 = Http2Translations.translateRequest(in1.request); Assert.assertEquals(req, req1); HttpResponse resp = Requests.createResponse(); resp.addHeader(new Header(KnownHeaderName.TRANSFER_ENCODING, "chunked")); Http2Headers headers = (Http2Headers) Http2Translations.responseToHeaders(resp, false); CompletableFuture<StreamWriter> future = in1.stream.sendResponse(headers); HttpResponse respToClient = (HttpResponse) mockChannel.getFrameAndClear(); Assert.assertEquals(resp, respToClient); StreamWriter writer = future.get(2, TimeUnit.SECONDS); DataFrame dataFrame = new DataFrame(); dataFrame.setEndOfStream(true); String bodyStr = "hi here and there"; DataWrapper data = dataGen.wrapByteArray(bodyStr.getBytes(StandardCharsets.UTF_8)); dataFrame.setData(data); writer.send(dataFrame); List<HttpPayload> frames = mockChannel.getFramesAndClear(); Assert.assertEquals(2, frames.size()); HttpChunk chunk = (HttpChunk) frames.get(0); DataWrapper body = chunk.getBodyNonNull(); String result = body.createStringFromUtf8(0, body.getReadableSize()); Assert.assertEquals(bodyStr, result); HttpLastChunk last = (HttpLastChunk) frames.get(1); Assert.assertEquals(0, last.getBodyNonNull().getReadableSize()); } @Test public void testPostWithChunking() { HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/xxxx"); req.addHeader(new Header(KnownHeaderName.TRANSFER_ENCODING, "chunked")); mockChannel.write(req); PassedIn in1 = mockListener.getSingleRequest(); HttpRequest req1 = Http2Translations.translateRequest(in1.request); Assert.assertEquals(req, req1); HttpChunk chunk = new HttpChunk(); String bodyStr = "hi here and there"; DataWrapper data = dataGen.wrapByteArray(bodyStr.getBytes(StandardCharsets.UTF_8)); chunk.setBody(data); mockChannel.write(chunk); DataFrame singleFrame = (DataFrame) mockStreamWriter.getSingleFrame(); Assert.assertTrue(!singleFrame.isEndOfStream()); DataWrapper data2 = singleFrame.getData(); String result = data2.createStringFromUtf8(0, data2.getReadableSize()); Assert.assertEquals(bodyStr, result); HttpLastChunk last = new HttpLastChunk(); mockChannel.write(last); DataFrame lastEmpty = (DataFrame) mockStreamWriter.getSingleFrame(); Assert.assertTrue(lastEmpty.isEndOfStream()); Assert.assertEquals(0, lastEmpty.getData().getReadableSize()); } @Test public void testUploadWithBody() { String bodyStr = "hi there, how are you"; DataWrapper dataWrapper = dataGen.wrapByteArray(bodyStr.getBytes(StandardCharsets.UTF_8)); HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/xxxx"); req.setBody(dataWrapper); req.addHeader(new Header(KnownHeaderName.CONTENT_LENGTH, ""+dataWrapper.getReadableSize())); mockChannel.write(req); PassedIn in1 = mockListener.getSingleRequest(); HttpRequest req1 = Http2Translations.translateRequest(in1.request); Assert.assertEquals(req, req1); DataFrame frame = (DataFrame) mockStreamWriter.getSingleFrame(); DataWrapper data = frame.getData(); Assert.assertEquals(bodyStr, data.createStringFromUtf8(0, data.getReadableSize())); Assert.assertTrue(frame.isEndOfStream()); HttpResponse resp = Requests.createResponse(); Http2Headers http2Resp = (Http2Headers) Http2Translations.responseToHeaders(resp, false); in1.stream.sendResponse(http2Resp); HttpResponse respToClient = (HttpResponse) mockChannel.getFrameAndClear(); Assert.assertEquals(resp, respToClient); } @Test public void testSendTwoRequestsAndMisorderedResponses() throws InterruptedException, ExecutionException { HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/xxxx"); HttpRequest req2 = Requests.createRequest(KnownHttpMethod.GET, "/xxxx"); mockChannel.write(req); mockListener.getSingleRequest(); mockChannel.write(req2); PassedIn in2 = mockListener.getSingleRequest(); //send back request2's response first!!!! BUT verify it does not go to client per http11 pipelining rules try { in2.stream.sendResponse(Responses.createResponse(2)); Assert.fail("should have thrown exception and did not"); } catch(IllegalStateException e) { } //assert NOT received Assert.assertEquals(0, mockChannel.getFramesAndClear().size()); } }