Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpRequestInterceptor;
import org.apache.hc.core5.http.Method;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.message.MessageSupport;
import org.apache.hc.core5.http.protocol.HttpContext;
Expand Down Expand Up @@ -76,6 +77,13 @@ public H2RequestConformance() {
public void process(final HttpRequest request, final EntityDetails entity, final HttpContext localContext)
throws HttpException, IOException {
Args.notNull(request, "HTTP request");

if (Method.QUERY.isSame(request.getMethod())) {
if (!request.containsHeader(HttpHeaders.CONTENT_TYPE)) {
throw new ProtocolException("QUERY request must have Content-Type header");
}
}

for (int i = 0; i < illegalHeaderNames.length; i++) {
final String headerName = illegalHeaderNames[i];
if (request.containsHeader(headerName)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@

class TestH2RequestConformance {

@Test
void testQueryMissingContentType() {
final HttpRequest request = new BasicHttpRequest("QUERY", "/");
Assertions.assertThrows(ProtocolException.class,
() -> H2RequestConformance.INSTANCE.process(request, null, HttpCoreContext.create()));
}

@Test
void testQueryWithContentType() throws Exception {
final HttpRequest request = new BasicHttpRequest("QUERY", "/");
request.setHeader(HttpHeaders.CONTENT_TYPE, "application/sql");
H2RequestConformance.INSTANCE.process(request, null, HttpCoreContext.create());
}

@Test
void testTEAbsent() throws Exception {
final HttpRequest request = new BasicHttpRequest("GET", "/");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ private HttpHeaders() {

public static final String ACCEPT_RANGES = "Accept-Ranges";

/**
* The RFC 10008 {@code Accept-Query} response header field name.
*
* @since 5.5
*/
public static final String ACCEPT_QUERY = "Accept-Query";

/**
* The CORS {@code Access-Control-Allow-Credentials} response header field name.
*/
Expand Down
3 changes: 0 additions & 3 deletions httpcore5/src/main/java/org/apache/hc/core5/http/Method.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@

import java.util.Locale;

import org.apache.hc.core5.annotation.Experimental;
import org.apache.hc.core5.util.Args;

/**
Expand Down Expand Up @@ -104,8 +103,6 @@ public enum Method {
*
* @since 5.4
*/
@Experimental
//("QUERY method is still in DRAFT status")
QUERY(true, true);

private final boolean safe;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import java.util.Arrays;
import java.util.List;

import org.apache.hc.core5.annotation.Experimental;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.Header;
Expand Down Expand Up @@ -129,7 +128,6 @@ public static ClassicRequestBuilder head(final String uri) {
*
* @since 5.4
*/
@Experimental
public static ClassicRequestBuilder query() {
return new ClassicRequestBuilder(Method.QUERY);
}
Expand All @@ -142,7 +140,6 @@ public static ClassicRequestBuilder query() {
*
* @since 5.4
*/
@Experimental
public static ClassicRequestBuilder query(final URI uri) {
return new ClassicRequestBuilder(Method.QUERY, uri);
}
Expand All @@ -155,7 +152,6 @@ public static ClassicRequestBuilder query(final URI uri) {
*
* @since 5.4
*/
@Experimental
public static ClassicRequestBuilder query(final String uri) {
return new ClassicRequestBuilder(Method.QUERY, uri);
}
Expand Down Expand Up @@ -408,7 +404,7 @@ public ClassicHttpRequest build() {
final String method = getMethod();
final List<NameValuePair> parameters = getParameters();
if (parameters != null && !parameters.isEmpty()) {
if (entityCopy == null && (Method.POST.isSame(method) || Method.PUT.isSame(method))) {
if (entityCopy == null && (Method.POST.isSame(method) || Method.PUT.isSame(method) || Method.QUERY.isSame(method))) {
entityCopy = HttpEntities.createUrlEncoded(parameters, getCharset());
} else {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import java.util.Arrays;
import java.util.List;

import org.apache.hc.core5.annotation.Experimental;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpHost;
Expand Down Expand Up @@ -128,7 +127,6 @@ public static AsyncRequestBuilder head(final String uri) {
*
* @since 5.4
*/
@Experimental
public static AsyncRequestBuilder query() {
return new AsyncRequestBuilder(Method.QUERY);
}
Expand All @@ -141,7 +139,6 @@ public static AsyncRequestBuilder query() {
*
* @since 5.4
*/
@Experimental
public static AsyncRequestBuilder query(final URI uri) {
return new AsyncRequestBuilder(Method.QUERY, uri);
}
Expand All @@ -154,7 +151,6 @@ public static AsyncRequestBuilder query(final URI uri) {
*
* @since 5.4
*/
@Experimental
public static AsyncRequestBuilder query(final String uri) {
return new AsyncRequestBuilder(Method.QUERY, uri);
}
Expand Down Expand Up @@ -383,7 +379,7 @@ public AsyncRequestProducer build() {
final List<NameValuePair> parameters = getParameters();
if (parameters != null && !parameters.isEmpty()) {
final Charset charset = getCharset();
if (entityProducerCopy == null && (Method.POST.isSame(method) || Method.PUT.isSame(method))) {
if (entityProducerCopy == null && (Method.POST.isSame(method) || Method.PUT.isSame(method) || Method.QUERY.isSame(method))) {
final String content = WWWFormCodec.format(
parameters,
charset != null ? charset : ContentType.APPLICATION_FORM_URLENCODED.getCharset());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpRequestInterceptor;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.Method;
import org.apache.hc.core5.http.MisdirectedRequestException;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.URIScheme;
Expand Down Expand Up @@ -66,6 +68,12 @@ public void process(final HttpRequest request, final EntityDetails entity, final
throws HttpException, IOException {
Args.notNull(request, "HTTP request");

if (Method.QUERY.isSame(request.getMethod())) {
if (!request.containsHeader(HttpHeaders.CONTENT_TYPE)) {
throw new ProtocolException("QUERY request must have Content-Type header");
}
}

if (TextUtils.isBlank(request.getScheme())) {
throw new ProtocolException("Request scheme is not set");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import java.util.Arrays;
import java.util.List;

import org.apache.hc.core5.annotation.Experimental;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
Expand Down Expand Up @@ -112,7 +111,6 @@ public static BasicRequestBuilder head(final String uri) {
*
* @since 5.4
*/
@Experimental
public static BasicRequestBuilder query() {
return new BasicRequestBuilder(Method.QUERY);
}
Expand All @@ -125,7 +123,6 @@ public static BasicRequestBuilder query() {
*
* @since 5.4
*/
@Experimental
public static BasicRequestBuilder query(final URI uri) {
return new BasicRequestBuilder(Method.QUERY, uri);
}
Expand All @@ -138,7 +135,6 @@ public static BasicRequestBuilder query(final URI uri) {
*
* @since 5.4
*/
@Experimental
public static BasicRequestBuilder query(final String uri) {
return new BasicRequestBuilder(Method.QUERY, uri);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
Expand All @@ -42,6 +43,7 @@
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.Method;
import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.http.message.BasicNameValuePair;
Expand Down Expand Up @@ -249,4 +251,23 @@ void builderTraceThrowsIllegalStateException() {
.build());
}

@Test
void builderQuery() throws IOException {
final ClassicHttpRequest classicHttpRequest = ClassicRequestBuilder.query()
.setHttpHost(new HttpHost("httpbin.org"))
.setPath("/theUri")
.addParameter("param1", "value1")
.addParameter("param2", "value2")
.build();

assertAll("QUERY builder tests",
() -> assertEquals(Method.QUERY.name(), classicHttpRequest.getMethod()),
() -> assertEquals("httpbin.org", classicHttpRequest.getAuthority().getHostName()),
() -> assertEquals("/theUri", classicHttpRequest.getPath()),
() -> assertNotNull(classicHttpRequest.getEntity()),
() -> assertEquals(ContentType.APPLICATION_FORM_URLENCODED.getMimeType(), ContentType.parse(classicHttpRequest.getEntity().getContentType()).getMimeType()),
() -> assertEquals("param1=value1&param2=value2", EntityUtils.toString(classicHttpRequest.getEntity()))
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,30 @@ void testRequestConformance() {
Assertions.assertDoesNotThrow(() -> interceptor.process(request, request.getEntity(), context));
}

@Test
void testRequestConformanceQueryMissingContentType() {
final HttpCoreContext context = HttpCoreContext.create();
final BasicClassicHttpRequest request = new BasicClassicHttpRequest(Method.QUERY, "/");
request.setScheme("http");
request.setAuthority(new URIAuthority("somehost", 8888));
request.setPath("/path");
final RequestConformance interceptor = new RequestConformance();
Assertions.assertThrows(ProtocolException.class, () ->
interceptor.process(request, request.getEntity(), context));
}

@Test
void testRequestConformanceQueryWithContentType() {
final HttpCoreContext context = HttpCoreContext.create();
final BasicClassicHttpRequest request = new BasicClassicHttpRequest(Method.QUERY, "/");
request.setScheme("http");
request.setAuthority(new URIAuthority("somehost", 8888));
request.setPath("/path");
request.setHeader(HttpHeaders.CONTENT_TYPE, "application/jsonpath");
final RequestConformance interceptor = new RequestConformance();
Assertions.assertDoesNotThrow(() -> interceptor.process(request, request.getEntity(), context));
}

@Test
void testRequestConformanceSchemeMissing() {
final HttpCoreContext context = HttpCoreContext.create();
Expand Down