/** * Returns an {@link HttpData} which holds a SSO form. */ static HttpData getSsoForm(String remoteEndpointUrl, String paramName, String paramValue, @Nullable String relayState) { requireNonNull(remoteEndpointUrl, "remoteEndpointUrl"); requireNonNull(paramName, "paramName"); requireNonNull(paramValue, "paramValue"); final StringBuilder html = new StringBuilder(); html.append(XHTML.get(0)) .append(XHTML.get(1)).append(HTML_ESCAPER.escape(remoteEndpointUrl)).append(XHTML.get(2)) .append(XHTML.get(3)).append(HTML_ESCAPER.escape(paramName)) .append(XHTML.get(4)).append(HTML_ESCAPER.escape(paramValue)).append(XHTML.get(5)); if (relayState != null) { html.append(XHTML.get(3)).append(RELAY_STATE) .append(XHTML.get(4)).append(HTML_ESCAPER.escape(relayState)).append(XHTML.get(5)); } html.append(XHTML.get(6)); return HttpData.ofUtf8(html.toString()); }
/** * Sends an HTTP POST request with the specified content. */ default HttpResponse post(String path, String content) { return execute(HttpHeaders.of(HttpMethod.POST, path), HttpData.ofUtf8(content)); }
/** * Sends an HTTP request with the specified headers and content. */ default HttpResponse execute(HttpHeaders headers, String content) { return execute(AggregatedHttpMessage.of(headers, HttpData.ofUtf8(content))); }
/** * Sends an HTTP PUT request with the specified content. */ default HttpResponse put(String path, String content) { return execute(HttpHeaders.of(HttpMethod.PUT, path), HttpData.ofUtf8(content)); }
/** * Sends an HTTP PATCH request with the specified content. */ default HttpResponse patch(String path, String content) { return execute(HttpHeaders.of(HttpMethod.PATCH, path), HttpData.ofUtf8(content)); }
@Override public HttpResponse convertResponse(ServiceRequestContext ctx, HttpHeaders headers, @Nullable Object result, HttpHeaders trailingHeaders) throws Exception { if (result instanceof Response) { final Response response = (Response) result; final HttpData body = HttpData.ofUtf8(response.result() + ':' + response.from()); return HttpResponse.of(headers, body, trailingHeaders); } return ResponseConverterFunction.fallthrough(); } }
private void fail(int id, HttpResponseStatus status) { discarding = true; req = null; final HttpData data = HttpData.ofUtf8(status.toString()); final com.linecorp.armeria.common.HttpHeaders headers = com.linecorp.armeria.common.HttpHeaders.of(status.code()); headers.set(HttpHeaderNames.CONNECTION, "close"); headers.setObject(HttpHeaderNames.CONTENT_TYPE, MediaType.PLAIN_TEXT_UTF_8); headers.setInt(HttpHeaderNames.CONTENT_LENGTH, data.length()); writer.writeHeaders(id, 1, headers, false); writer.writeData(id, 1, data, true).addListener(ChannelFutureListener.CLOSE); }
@Test public void completeNormally() throws Exception { when(armeriaCall.tryFinish()).thenReturn(true); final ManualMockCallback callback = new ManualMockCallback(); final BlockingCallSubscriber subscriber = new BlockingCallSubscriber( armeriaCall, callback, new Request.Builder().url("http://foo.com").build()); subscriber.onSubscribe(subscription); subscriber.onNext(HttpHeaders.of(200)); subscriber.onNext(HttpData.ofUtf8("{\"name\":\"foo\"}")); subscriber.onComplete(); verify(subscription).request(Long.MAX_VALUE); assertThat(callback.callbackCallingCount).isEqualTo(1); assertThat(callback.response.body().string()).isEqualTo("{\"name\":\"foo\"}"); }
@Test public void cancel() throws Exception { when(armeriaCall.tryFinish()).thenReturn(false); when(armeriaCall.isCanceled()).thenReturn(false, false, true); final ManualMockCallback callback = new ManualMockCallback(); final BlockingCallSubscriber subscriber = new BlockingCallSubscriber( armeriaCall, callback, new Request.Builder().url("http://foo.com").build()); subscriber.onSubscribe(subscription); subscriber.onNext(HttpHeaders.of(200)); subscriber.onNext(HttpData.ofUtf8("{\"name\":\"foo\"}")); subscriber.onComplete(); verify(subscription).request(Long.MAX_VALUE); assertThat(callback.callbackCallingCount).isEqualTo(1); assertThat(callback.exception.getMessage()).isEqualTo("cancelled"); } }
@Test public void cancel_duringReadingData() throws Exception { when(armeriaCall.tryFinish()).thenReturn(false); when(armeriaCall.isCanceled()).thenReturn(false, false, false, true); final ManualMockCallback callback = new ManualMockCallback(); final StreamingCallSubscriber subscriber = new StreamingCallSubscriber( armeriaCall, callback, new Request.Builder().url("http://foo.com").build(), MoreExecutors.directExecutor()); subscriber.onSubscribe(subscription); subscriber.onNext(HttpHeaders.of(200)); subscriber.onNext(HttpData.ofUtf8("{\"name\":")); subscriber.onNext(HttpData.ofUtf8("\"foo\"}")); subscriber.onComplete(); verify(subscription, times(2)).request(1L); await().untilAsserted(() -> assertThat(callback.callbackCallingCount).isEqualTo(1)); await().untilAsserted(() -> assertThat(callback.exception).isNull()); await().untilAsserted( () -> assertThatThrownBy(() -> callback.response.body().string()).hasMessage("closed")); }
@Test public void completeNormally() throws Exception { when(armeriaCall.tryFinish()).thenReturn(true); final ManualMockCallback callback = new ManualMockCallback(); final StreamingCallSubscriber subscriber = new StreamingCallSubscriber( armeriaCall, callback, new Request.Builder().url("http://foo.com").build(), MoreExecutors.directExecutor()); subscriber.onSubscribe(subscription); subscriber.onNext(HttpHeaders.of(200)); subscriber.onNext(HttpData.ofUtf8("{\"name\":\"foo\"}")); subscriber.onComplete(); verify(subscription, times(2)).request(1L); await().untilAsserted(() -> assertThat(callback.callbackCallingCount).isEqualTo(1)); await().untilAsserted( () -> assertThat(callback.response.body().string()).isEqualTo("{\"name\":\"foo\"}")); }
@Test public void cancel() throws Exception { when(armeriaCall.tryFinish()).thenReturn(false); when(armeriaCall.isCanceled()).thenReturn(false, false, true); final ManualMockCallback callback = new ManualMockCallback(); final StreamingCallSubscriber subscriber = new StreamingCallSubscriber( armeriaCall, callback, new Request.Builder().url("http://foo.com").build(), MoreExecutors.directExecutor()); subscriber.onSubscribe(subscription); subscriber.onNext(HttpHeaders.of(200)); subscriber.onNext(HttpData.ofUtf8("{\"name\":\"foo\"}")); subscriber.onComplete(); verify(subscription, times(2)).request(1L); await().untilAsserted(() -> assertThat(callback.callbackCallingCount).isEqualTo(1)); await().untilAsserted(() -> assertThat(callback.exception.getMessage()).isEqualTo("cancelled")); }
@Test public void exception_afterReceivingHttpData() throws Exception { when(armeriaCall.tryFinish()).thenReturn(true); when(armeriaCall.isCanceled()).thenReturn(false); final ManualMockCallback callback = new ManualMockCallback(); final StreamingCallSubscriber subscriber = new StreamingCallSubscriber( armeriaCall, callback, new Request.Builder().url("http://foo.com").build(), MoreExecutors.directExecutor()); subscriber.onSubscribe(subscription); subscriber.onNext(HttpHeaders.of(200)); subscriber.onNext(HttpData.ofUtf8("{\"name\":")); subscriber.onError(new IOException("foo")); verify(subscription, times(2)).request(1L); await().untilAsserted(() -> assertThat(callback.callbackCallingCount).isEqualTo(1)); await().untilAsserted(() -> assertThat(callback.exception).isNull()); assertThatThrownBy(() -> callback.response.body().string()).hasMessageEndingWith("foo"); } }
@Test public void splitHeaders() throws Exception { when(armeriaCall.tryFinish()).thenReturn(true); final ManualMockCallback callback = new ManualMockCallback(); final BlockingCallSubscriber subscriber = new BlockingCallSubscriber( armeriaCall, callback, new Request.Builder().url("http://bar.com").build()); subscriber.onSubscribe(subscription); subscriber.onNext(HttpHeaders.of(100)); subscriber.onNext(HttpHeaders.of(200)); subscriber.onNext(HttpHeaders.of(HttpHeaderNames.CONTENT_TYPE, MediaType.PLAIN_TEXT_UTF_8.toString())); subscriber.onNext(HttpData.ofUtf8("bar")); subscriber.onComplete(); verify(subscription).request(Long.MAX_VALUE); assertThat(callback.callbackCallingCount).isEqualTo(1); assertThat(callback.response.header("content-type")).isEqualToIgnoringCase("text/plain; charset=utf-8"); assertThat(callback.response.body().string()).isEqualTo("bar"); }
@Test public void usingDefaultDataBufferFactory_HttpData() { final DataBufferFactoryWrapper<?> wrapper = new DataBufferFactoryWrapper<>(new DefaultDataBufferFactory()); final HttpData httpData1 = HttpData.ofUtf8("abc"); final DataBuffer buffer = wrapper.toDataBuffer(httpData1); assertThat(buffer).isInstanceOf(DefaultDataBuffer.class); assertThat(buffer.asByteBuffer()).isEqualTo(ByteBuffer.wrap("abc".getBytes())); final HttpData httpData2 = wrapper.toHttpData(buffer); assertThat(httpData2).isInstanceOf(ByteBufHttpData.class); assertThat(((ByteBufHttpData) httpData2).refCnt()).isOne(); assertThat(ByteBufUtil.getBytes(((ByteBufHttpData) httpData2).content())).isEqualTo("abc".getBytes()); } }
@Test public void splitHeaders() throws Exception { when(armeriaCall.tryFinish()).thenReturn(true); final ManualMockCallback callback = new ManualMockCallback(); final StreamingCallSubscriber subscriber = new StreamingCallSubscriber( armeriaCall, callback, new Request.Builder().url("http://bar.com").build(), MoreExecutors.directExecutor()); subscriber.onSubscribe(subscription); subscriber.onNext(HttpHeaders.of(100)); subscriber.onNext(HttpHeaders.of(200)); subscriber.onNext(HttpHeaders.of(HttpHeaderNames.CONTENT_TYPE, MediaType.PLAIN_TEXT_UTF_8.toString())); subscriber.onNext(HttpData.ofUtf8("bar")); subscriber.onComplete(); verify(subscription, times(4)).request(1L); await().untilAsserted(() -> assertThat(callback.callbackCallingCount).isEqualTo(1)); await().untilAsserted(() -> assertThat(callback.response.header("content-type")) .isEqualToIgnoringCase("text/plain; charset=utf-8")); await().untilAsserted(() -> assertThat(callback.response.body().string()).isEqualTo("bar")); }
@Test public void missingContentType() throws Exception { final HttpRequest req = HttpRequest.of(HttpMethod.POST, "/grpc.testing.TestService.UnaryCall"); final ServiceRequestContext ctx = ServiceRequestContext.of(req); final HttpResponse response = grpcService.doPost(ctx, req); assertThat(response.aggregate().get()).isEqualTo(AggregatedHttpMessage.of( HttpHeaders.of(HttpStatus.UNSUPPORTED_MEDIA_TYPE) .contentType(MediaType.PLAIN_TEXT_UTF_8) .setInt(HttpHeaderNames.CONTENT_LENGTH, 39), HttpData.ofUtf8("Missing or invalid Content-Type header."))); }
@Test public void usingNettyDataBufferFactory_HttpData() { final DataBufferFactoryWrapper<?> wrapper = new DataBufferFactoryWrapper<>(new NettyDataBufferFactory(UnpooledByteBufAllocator.DEFAULT)); final HttpData httpData1 = HttpData.ofUtf8("abc"); final DataBuffer buffer = wrapper.toDataBuffer(httpData1); assertThat(buffer).isInstanceOf(NettyDataBuffer.class); assertThat(((NettyDataBuffer) buffer).getNativeBuffer().refCnt()).isOne(); final HttpData httpData2 = wrapper.toHttpData(buffer); assertThat(httpData2).isInstanceOf(ByteBufHttpData.class); assertThat(((ByteBufHttpData) httpData2).content()) .isEqualTo(((NettyDataBuffer) buffer).getNativeBuffer()); assertThat(((ByteBufHttpData) httpData2).refCnt()).isOne(); }
@Test public void badContentType() throws Exception { final HttpRequest req = HttpRequest.of( HttpHeaders.of(HttpMethod.POST, "/grpc.testing.TestService.UnaryCall") .contentType(MediaType.JSON_UTF_8)); final ServiceRequestContext ctx = ServiceRequestContext.of(req); final HttpResponse response = grpcService.doPost(ctx, req); assertThat(response.aggregate().get()).isEqualTo(AggregatedHttpMessage.of( HttpHeaders.of(HttpStatus.UNSUPPORTED_MEDIA_TYPE) .contentType(MediaType.PLAIN_TEXT_UTF_8) .setInt(HttpHeaderNames.CONTENT_LENGTH, 39), HttpData.ofUtf8("Missing or invalid Content-Type header."))); }
@Test public void pathMissingSlash() throws Exception { final HttpRequest req = HttpRequest.of( HttpHeaders.of(HttpMethod.POST, "/grpc.testing.TestService.UnaryCall") .set(HttpHeaderNames.CONTENT_TYPE, "application/grpc+proto")); final PathMappingResult pathMappingResult = PathMappingResult.of("grpc.testing.TestService.UnaryCall"); final ServiceRequestContext ctx = ServiceRequestContextBuilder.of(req) .pathMappingResult(pathMappingResult) .build(); final HttpResponse response = grpcService.doPost(ctx, req); assertThat(response.aggregate().get()).isEqualTo(AggregatedHttpMessage.of( HttpHeaders.of(HttpStatus.BAD_REQUEST) .contentType(MediaType.PLAIN_TEXT_UTF_8) .setInt(HttpHeaderNames.CONTENT_LENGTH, 13), HttpData.ofUtf8("Invalid path."))); }