/** * Returns the {@link HttpHeaderNames#METHOD METHOD} of this message. * * @return the method, or {@code null} if there's no such header */ @Nullable default HttpMethod method() { return headers().method(); }
/** * Returns the {@link HttpHeaderNames#AUTHORITY AUTHORITY} of this message, in the form of * {@code "hostname:port"}. * * @return the authority, or {@code null} if there's no such header */ @Nullable default String authority() { return headers().authority(); }
/** * Returns the {@link HttpHeaderNames#PATH PATH} of this message. * * @return the path, or {@code null} if there's no such header */ @Nullable default String path() { return headers().path(); }
/** * Returns the {@link HttpHeaderNames#SCHEME SCHEME} of this message. * * @return the scheme, or {@code null} if there's no such header */ @Nullable default String scheme() { return headers().scheme(); }
/** * Returns the {@link HttpHeaderNames#STATUS STATUS} of this message. * * @return the status, or {@code null} if there's no such header */ @Nullable default HttpStatus status() { return headers().status(); }
@Override protected HttpResponse doHead(ServiceRequestContext ctx, HttpRequest req) { return HttpResponse.of(newResponse(ctx).headers()); // Send without the content. }
/** * Converts the {@link AggregatedHttpMessage} into a new {@link HttpRequest} and closes the stream. */ static HttpRequest of(AggregatedHttpMessage message) { return of(message.headers(), message.content(), message.trailingHeaders()); }
@Nullable @Override public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { final MediaType mediaType = request.headers().contentType(); if (mediaType != null && mediaType.is(MediaType.PLAIN_TEXT_UTF_8)) { return new Request(request.content().toStringUtf8()); } return RequestConverterFunction.fallthrough(); } }
@Test public void shouldRespondAuthnRequest_HttpRedirect() throws Exception { final AggregatedHttpMessage resp = client.get("/redirect").aggregate().join(); assertThat(resp.status()).isEqualTo(HttpStatus.FOUND); // Check the order of the parameters in the quest string. final String location = resp.headers().get(HttpHeaderNames.LOCATION); final Pattern p = Pattern.compile( "http://idp\\.example\\.com/saml/sso/redirect\\?" + "SAMLRequest=([^&]+)&RelayState=([^&]+)&SigAlg=([^&]+)&Signature=(.+)$"); assertThat(p.matcher(location).matches()).isTrue(); final QueryStringDecoder decoder = new QueryStringDecoder(location, true); assertThat(decoder.parameters().get(SIGNATURE_ALGORITHM).get(0)).isEqualTo(signatureAlgorithm); }
@Test public void shouldRespondAuthnRequest_HttpPost() throws Exception { final AggregatedHttpMessage resp = client.get("/post").aggregate().join(); assertThat(resp.status()).isEqualTo(HttpStatus.OK); assertThat(resp.headers().contentType()).isEqualTo(MediaType.HTML_UTF_8); final Document doc = Jsoup.parse(resp.content().toStringUtf8()); assertThat(doc.body().attr("onLoad")).isEqualTo("document.forms[0].submit()"); // SAMLRequest will be posted to the IdP's SSO URL. final Element form = doc.body().child(0); assertThat(form.attr("method")).isEqualTo("post"); assertThat(form.attr("action")).isEqualTo("http://idp.example.com/saml/sso/post"); assertThat(form.child(0).attr("name")).isEqualTo(SAML_REQUEST); assertThat(form.child(1).attr("name")).isEqualTo(RELAY_STATE); }
@Test public void completable() { final HttpClient client = HttpClient.of(rule.uri("/completable")); AggregatedHttpMessage msg; msg = client.get("/done").aggregate().join(); assertThat(msg.headers().status()).isEqualTo(HttpStatus.OK); msg = client.get("/error").aggregate().join(); assertThat(msg.headers().status()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); }
@Test public void shouldConsumeLogoutRequest_HttpRedirect() throws Exception { final LogoutRequest logoutRequest = getLogoutRequest("http://" + spHostname + ':' + rule.httpPort() + "/saml/slo/redirect", "http://idp.example.com/redirect"); final AggregatedHttpMessage msg = sendViaHttpRedirectBindingProtocol("/saml/slo/redirect", SAML_REQUEST, logoutRequest); assertThat(msg.status()).isEqualTo(HttpStatus.FOUND); // Check the order of the parameters in the quest string. final String location = msg.headers().get(HttpHeaderNames.LOCATION); final Pattern p = Pattern.compile( "http://idp\\.example\\.com/saml/slo/redirect\\?" + "SAMLResponse=([^&]+)&SigAlg=([^&]+)&Signature=(.+)$"); assertThat(p.matcher(location).matches()).isTrue(); }
@Test public void shouldConsumeAssertion_HttpPost() throws Exception { final Response response = getAuthResponse("http://" + spHostname + ':' + rule.httpPort() + "/saml/acs/post"); final AggregatedHttpMessage msg = sendViaHttpPostBindingProtocol("/saml/acs/post", SAML_RESPONSE, response); assertThat(msg.status()).isEqualTo(HttpStatus.FOUND); assertThat(msg.headers().get(HttpHeaderNames.LOCATION)).isEqualTo("/"); }
@Test public void shouldConsumeAssertion_HttpRedirect() throws Exception { final Response response = getAuthResponse("http://" + spHostname + ':' + rule.httpPort() + "/saml/acs/redirect"); final AggregatedHttpMessage msg = sendViaHttpRedirectBindingProtocol("/saml/acs/redirect", SAML_RESPONSE, response); assertThat(msg.status()).isEqualTo(HttpStatus.FOUND); assertThat(msg.headers().get(HttpHeaderNames.LOCATION)).isEqualTo("/"); }
@Test public void single() { final HttpClient client = HttpClient.of(rule.uri("/single")); AggregatedHttpMessage msg; msg = client.get("/string").aggregate().join(); assertThat(msg.headers().contentType()).isEqualTo(MediaType.PLAIN_TEXT_UTF_8); assertThat(msg.content().toStringUtf8()).isEqualTo("a"); msg = client.get("/json").aggregate().join(); assertThat(msg.headers().contentType()).isEqualTo(MediaType.JSON_UTF_8); assertThatJson(msg.content().toStringUtf8()).isStringEqualTo("a"); msg = client.get("/error").aggregate().join(); assertThat(msg.headers().status()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); }
@Test public void maybe() { final HttpClient client = HttpClient.of(rule.uri("/maybe")); AggregatedHttpMessage msg; msg = client.get("/string").aggregate().join(); assertThat(msg.headers().contentType()).isEqualTo(MediaType.PLAIN_TEXT_UTF_8); assertThat(msg.content().toStringUtf8()).isEqualTo("a"); msg = client.get("/json").aggregate().join(); assertThat(msg.headers().contentType()).isEqualTo(MediaType.JSON_UTF_8); assertThatJson(msg.content().toStringUtf8()).isStringEqualTo("a"); msg = client.get("/empty").aggregate().join(); assertThat(msg.headers().status()).isEqualTo(HttpStatus.OK); assertThat(msg.content().isEmpty()).isTrue(); msg = client.get("/error").aggregate().join(); assertThat(msg.headers().status()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); }
@Test public void statusOk() throws Exception { unframedGrpcService = (UnframedGrpcService) new GrpcServiceBuilder().addService(testService) .setMaxInboundMessageSizeBytes(MAX_MESSAGE_BYTES) .setMaxOutboundMessageSizeBytes(MAX_MESSAGE_BYTES) .supportedSerializationFormats( GrpcSerializationFormats.values()) .enableUnframedRequests(true) .build(); final HttpResponse response = unframedGrpcService.serve(ctx, request); final AggregatedHttpMessage aggregatedHttpMessage = response.aggregate().get(); assertThat(aggregatedHttpMessage.headers().status()).isEqualTo(HttpStatus.OK); assertThat(aggregatedHttpMessage.content().toStringUtf8()).isEqualTo("{}"); }
@Test public void shouldReturnCompressedResponse() { final ArmeriaReactiveWebServerFactory factory = factory(); final Compression compression = new Compression(); compression.setEnabled(true); compression.setMinResponseSize(DataSize.ofBytes(1)); compression.setMimeTypes(new String[] { "text/plain" }); compression.setExcludedUserAgents(new String[] { "unknown-agent/[0-9]+\\.[0-9]+\\.[0-9]+$" }); factory.setCompression(compression); runEchoServer(factory, server -> { final AggregatedHttpMessage res = sendPostRequest(httpClient(server)); assertThat(res.status()).isEqualTo(com.linecorp.armeria.common.HttpStatus.OK); assertThat(res.headers().get(HttpHeaderNames.CONTENT_ENCODING)).isEqualTo("gzip"); assertThat(res.content().toStringUtf8()).isNotEqualTo("hello"); }); }
@Test public void shouldReturnNonCompressedResponse_dueToUserAgent() { final ArmeriaReactiveWebServerFactory factory = factory(); final Compression compression = new Compression(); compression.setEnabled(true); compression.setMinResponseSize(DataSize.ofBytes(1)); compression.setExcludedUserAgents(new String[] { "test-agent/[0-9]+\\.[0-9]+\\.[0-9]+$" }); factory.setCompression(compression); runEchoServer(factory, server -> { final AggregatedHttpMessage res = sendPostRequest(httpClient(server)); validateEchoResponse(res); assertThat(res.headers().get(HttpHeaderNames.CONTENT_ENCODING)).isNull(); }); }
@Test public void shouldReturnNonCompressedResponse_dueToContentType() { final ArmeriaReactiveWebServerFactory factory = factory(); final Compression compression = new Compression(); compression.setEnabled(true); compression.setMinResponseSize(DataSize.ofBytes(1)); compression.setMimeTypes(new String[] { "text/html" }); factory.setCompression(compression); runEchoServer(factory, server -> { final AggregatedHttpMessage res = sendPostRequest(httpClient(server)); validateEchoResponse(res); assertThat(res.headers().get(HttpHeaderNames.CONTENT_ENCODING)).isNull(); }); }