Replace Commons HttpClient with HttpComponents 5 in TCK client layer Co-authored-by: mkarg <1701815+mkarg@users.noreply.github.com>
diff --git a/jaxrs-tck/pom.xml b/jaxrs-tck/pom.xml index a66e44e..cf26b4c 100644 --- a/jaxrs-tck/pom.xml +++ b/jaxrs-tck/pom.xml
@@ -39,7 +39,7 @@ <json.bind.api.version>3.0.1</json.bind.api.version> <xml.bind.api.version>4.0.4</xml.bind.api.version> <servlet.api.version>6.1.0</servlet.api.version> - <common.httpclient.version>3.1</common.httpclient.version> + <httpcomponents.client5.version>5.4.2</httpcomponents.client5.version> <arquillian.version>1.10.0.Final</arquillian.version> </properties> @@ -68,9 +68,9 @@ </dependency> <dependency> - <groupId>commons-httpclient</groupId> - <artifactId>commons-httpclient</artifactId> - <version>${common.httpclient.version}</version> + <groupId>org.apache.httpcomponents.client5</groupId> + <artifactId>httpclient5</artifactId> + <version>${httpcomponents.client5.version}</version> </dependency> <dependency>
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/JAXRSCommonClient.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/JAXRSCommonClient.java index d5c06b1..40b3e4a 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/JAXRSCommonClient.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/JAXRSCommonClient.java
@@ -33,8 +33,8 @@ import ee.jakarta.tck.ws.rs.common.webclient.http.HttpResponse; import ee.jakarta.tck.ws.rs.common.webclient.validation.CheckOneOfStatusesTokenizedValidator; import ee.jakarta.tck.ws.rs.lib.util.TestUtil; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HttpState; +import org.apache.hc.client5.http.protocol.HttpClientContext; +import org.apache.hc.core5.http.Header; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -169,7 +169,7 @@ /** * HttpState that may be used for multiple invocations requiring state. */ - protected HttpState _state = null; + protected HttpClientContext _state = null; /** * Test case.
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/client/ApacheResponseAdapter.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/client/ApacheResponseAdapter.java index d7e3b1b..af79e90 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/client/ApacheResponseAdapter.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/client/ApacheResponseAdapter.java
@@ -17,18 +17,24 @@ package ee.jakarta.tck.ws.rs.common.client; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.LinkedList; import java.util.List; import ee.jakarta.tck.ws.rs.common.webclient.http.HttpResponse; -import org.apache.commons.httpclient.Header; +import org.apache.hc.client5.http.protocol.HttpClientContext; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HttpVersion; +import org.apache.hc.core5.http.message.BasicHeader; import jakarta.ws.rs.core.MultivaluedMap; public class ApacheResponseAdapter extends HttpResponse { public ApacheResponseAdapter(jakarta.ws.rs.core.Response response, String host, int port) { - super(host, port, port == 443, null, null); + super(host, port, port == 443, null, HttpVersion.HTTP_1_1, response.getStatus(), + response.getStatusInfo().getReasonPhrase(), new Header[0], new byte[0], + HttpClientContext.create()); this.response = response; this.caser = TextCaser.NONE; } @@ -78,7 +84,7 @@ String[] sHeaders = JaxrsCommonClient.getMetadata(mHeaders); for (String header : sHeaders) { String[] split = header.split(":", 2); - headers.add(new Header(split[0], split[1])); + headers.add(new BasicHeader(split[0], split[1])); } return headers.toArray(new Header[headers.size()]); } @@ -105,4 +111,9 @@ } return encoding; } + + @Override + public byte[] getResponseBodyAsRawBytes() throws IOException { + return getResponseBodyAsString().getBytes(StandardCharsets.ISO_8859_1); + } }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/WebTestCase.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/WebTestCase.java index 22b3505..9570633 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/WebTestCase.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/WebTestCase.java
@@ -30,8 +30,9 @@ import ee.jakarta.tck.ws.rs.common.webclient.http.HttpResponse; import ee.jakarta.tck.ws.rs.common.webclient.validation.ValidationFactory; import ee.jakarta.tck.ws.rs.common.webclient.validation.ValidationStrategy; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HttpState; +import org.apache.hc.client5.http.protocol.HttpClientContext; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.message.BasicHeader; import ee.jakarta.tck.ws.rs.lib.util.TestUtil; @@ -476,7 +477,7 @@ * test state */ public void setState(Object state) { - _request.setState((HttpState) state); + _request.setState((HttpClientContext) state); } /** @@ -553,7 +554,7 @@ if (header != null) { map.put(name, createNewHeader(value, header)); } else { - map.put(name, new Header(name, value)); + map.put(name, new BasicHeader(name, value)); } } } @@ -569,7 +570,7 @@ */ private Header createNewHeader(String newValue, Header header) { String oldValue = header.getValue(); - return new Header(header.getName(), oldValue + ", " + newValue); + return new BasicHeader(header.getName(), oldValue + ", " + newValue); } /**
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/ALLOWHandler.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/ALLOWHandler.java index d2d79b2..4f72846 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/ALLOWHandler.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/ALLOWHandler.java
@@ -21,7 +21,7 @@ import java.util.StringTokenizer; -import org.apache.commons.httpclient.Header; +import org.apache.hc.core5.http.Header; import ee.jakarta.tck.ws.rs.lib.util.TestUtil;
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/ContentTypeHandler.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/ContentTypeHandler.java index 797d58e..b18e7d2 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/ContentTypeHandler.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/ContentTypeHandler.java
@@ -60,7 +60,7 @@ package ee.jakarta.tck.ws.rs.common.webclient.handler; -import org.apache.commons.httpclient.Header; +import org.apache.hc.core5.http.Header; import ee.jakarta.tck.ws.rs.lib.util.TestUtil;
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/DefaultHandler.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/DefaultHandler.java index 34e7d9e..f9d487f 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/DefaultHandler.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/DefaultHandler.java
@@ -60,8 +60,10 @@ package ee.jakarta.tck.ws.rs.common.webclient.handler; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HeaderElement; +import java.util.HashSet; +import java.util.Set; + +import org.apache.hc.core5.http.Header; import ee.jakarta.tck.ws.rs.lib.util.TestUtil; @@ -120,26 +122,23 @@ */ protected boolean areHeadersEqual(Header h1, Header h2) { - HeaderElement[] h1Values = h1.getElements(); - HeaderElement[] h2Values = h2.getElements(); + String[] h1Values = h1.getValue().split(","); + String[] h2Values = h2.getValue().split(","); if (h1Values.length == h2Values.length) { - for (HeaderElement h1Value : h1Values) { - String h1Val = h1Value.getName(); - boolean found = false; - for (HeaderElement h2Value : h2Values) { - if (h1Val.equals(h2Value.getName())) { - found = true; - break; - } - } - if (!found) { - return false; - } - } - return true; + Set<String> h1Names = normalizeHeaderElements(h1Values); + Set<String> h2Names = normalizeHeaderElements(h2Values); + return h1Names.equals(h2Names); } else { return false; } } + + private Set<String> normalizeHeaderElements(String[] values) { + Set<String> normalized = new HashSet<String>(); + for (String value : values) { + normalized.add(value.trim().split(";")[0].trim()); + } + return normalized; + } }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/Handler.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/Handler.java index d70e5c7..fa17aab 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/Handler.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/Handler.java
@@ -58,7 +58,7 @@ */ package ee.jakarta.tck.ws.rs.common.webclient.handler; -import org.apache.commons.httpclient.Header; +import org.apache.hc.core5.http.Header; /** * Handler interface.
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/LocationHandler.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/LocationHandler.java index 530e2b4..2af2fc5 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/LocationHandler.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/LocationHandler.java
@@ -63,7 +63,7 @@ import java.net.MalformedURLException; import java.net.URL; -import org.apache.commons.httpclient.Header; +import org.apache.hc.core5.http.Header; import ee.jakarta.tck.ws.rs.lib.util.TestUtil;
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/SetCookieHandler.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/SetCookieHandler.java index ae1e6c9..69937cc 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/SetCookieHandler.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/SetCookieHandler.java
@@ -22,7 +22,7 @@ import java.util.StringTokenizer; -import org.apache.commons.httpclient.Header; +import org.apache.hc.core5.http.Header; import ee.jakarta.tck.ws.rs.lib.util.TestUtil;
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/WWWAuthenticateHandler.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/WWWAuthenticateHandler.java index ffdc4ad..2027cfb 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/WWWAuthenticateHandler.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/handler/WWWAuthenticateHandler.java
@@ -60,7 +60,7 @@ package ee.jakarta.tck.ws.rs.common.webclient.handler; -import org.apache.commons.httpclient.Header; +import org.apache.hc.core5.http.Header; import ee.jakarta.tck.ws.rs.lib.util.TestUtil;
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/HttpRequest.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/HttpRequest.java index 3e7c60f..cecc156 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/HttpRequest.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/HttpRequest.java
@@ -21,27 +21,30 @@ package ee.jakarta.tck.ws.rs.common.webclient.http; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; import java.util.StringTokenizer; -import org.apache.commons.httpclient.Cookie; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpConnection; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.HttpState; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; -import org.apache.commons.httpclient.cookie.CookiePolicy; -import org.apache.commons.httpclient.methods.EntityEnclosingMethod; -import org.apache.commons.httpclient.methods.StringRequestEntity; -import org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory; -import org.apache.commons.httpclient.protocol.Protocol; -import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; -import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory; +import org.apache.hc.client5.http.auth.AuthScope; +import org.apache.hc.client5.http.auth.Credentials; +import org.apache.hc.client5.http.auth.UsernamePasswordCredentials; +import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.cookie.BasicCookieStore; +import org.apache.hc.client5.http.cookie.Cookie; +import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.cookie.BasicClientCookie; +import org.apache.hc.client5.http.protocol.HttpClientContext; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.io.entity.StringEntity; -import ee.jakarta.tck.ws.rs.lib.util.TestUtil; import ee.jakarta.tck.ws.rs.common.webclient.Util; +import ee.jakarta.tck.ws.rs.lib.util.TestUtil; /** * Represents an HTTP client Request @@ -49,15 +52,6 @@ public class HttpRequest { - static { - // if (TestUtil.traceflag) { - // System.setProperty("org.apache.commons.logging.Log", - // "ee.jakarta.tck.ws.rs.common.webclient.log.WebLog"); - // System.setProperty( - // "org.apache.commons.logging.simplelog.log.httpclient.wire", "debug"); - // } - } - /** * Default HTTP port. */ @@ -86,7 +80,7 @@ /** * Method representation of request. */ - private HttpMethod _method = null; + private HttpUriRequestBase _method = null; /** * Target web container host @@ -106,7 +100,7 @@ /** * HTTP state */ - private HttpState _state = null; + private HttpClientContext _state = null; /** * Original request line for this request. @@ -135,21 +129,17 @@ Header[] _headers = null; - protected HttpClient client = null; - /** * Creates new HttpRequest based of the passed request line. The request line * provied must be in the form of:<br> - * + * * <pre> * METHOD PATH HTTP-VERSION * Ex. GET /index.html HTTP/1.0 * </pre> */ public HttpRequest(String requestLine, String host, int port) { - client = new HttpClient(); - _method = MethodFactory.getInstance(requestLine); - _method.setFollowRedirects(false); + _method = createMethod(requestLine); _host = host; _port = port; @@ -157,11 +147,13 @@ _isSecure = true; } - // If we got this far, the request line is in the proper - // format _requestLine = requestLine; } + protected HttpUriRequestBase createMethod(String requestLine) { + return MethodFactory.getInstance(requestLine); + } + /* * public methods * ======================================================================== @@ -184,7 +176,7 @@ * @return String request type */ public String getRequestMethod() { - return _method.getName(); + return _method.getMethod(); } /** @@ -216,9 +208,8 @@ * request content */ public void setContent(String content) { - if (_method instanceof EntityEnclosingMethod) { - ((EntityEnclosingMethod) _method) - .setRequestEntity(new StringRequestEntity(content)); + if (isEntityEnclosingMethod()) { + _method.setEntity(new StringEntity(content, StandardCharsets.ISO_8859_1)); } _contentLength = content.length(); } @@ -254,9 +245,10 @@ } UsernamePasswordCredentials cred = new UsernamePasswordCredentials(username, - password); - AuthScope scope = new AuthScope(_host, _port, realm); - getState().setCredentials(scope, cred); + password.toCharArray()); + AuthScope scope = new AuthScope(_host, null, _port, realm, null); + ((BasicCredentialsProvider) getState().getCredentialsProvider()) + .setCredentials(scope, cred); TestUtil.logTrace("[HttpRequest] Added credentials for '" + username + "' with password '" + password + "' in realm '" + realm + "'"); @@ -276,9 +268,9 @@ * request header value */ public void addRequestHeader(String headerName, String headerValue) { - _method.addRequestHeader(headerName, headerValue); + _method.addHeader(headerName, headerValue); TestUtil.logTrace("[HttpRequest] Added request header: " - + _method.getRequestHeader(headerName).toExternalForm()); + + formatHeader(_method.getFirstHeader(headerName))); } public void addRequestHeader(String header) { @@ -306,9 +298,9 @@ * request header value */ public void setRequestHeader(String headerName, String headerValue) { - _method.setRequestHeader(headerName, headerValue); + _method.setHeader(headerName, headerValue); TestUtil.logTrace("[HttpRequest] Set request header: " - + _method.getRequestHeader(headerName).toExternalForm()); + + formatHeader(_method.getFirstHeader(headerName))); } @@ -317,7 +309,7 @@ * followed. By default, redirects are not followed. */ public void setFollowRedirects(boolean followRedirects) { - _method.setFollowRedirects(followRedirects); + _redirect = followRedirects; } /** @@ -325,14 +317,14 @@ * followed. */ public boolean getFollowRedirects() { - return _method.getFollowRedirects(); + return _redirect; } /** * <code>setState</code> will set the HTTP state for the current request (i.e. * session tracking). This has the side affect */ - public void setState(HttpState state) { + public void setState(HttpClientContext state) { _state = state; _useCookies = true; } @@ -345,79 +337,33 @@ * @throws IOException * if an I/O error occurs during dispatch. */ - public HttpResponse execute() throws IOException, HttpException { - String method; - int defaultPort; - ProtocolSocketFactory factory; + public HttpResponse execute() throws IOException { + String method = _isSecure ? "https" : "http"; + HttpHost target = new HttpHost(method, _host, _port); - if (_method.getFollowRedirects()) { - client = new HttpClient(); + TestUtil.logMsg("[HttpRequest] Dispatching request: '" + _requestLine + + "' to target server at '" + _host + ":" + _port + "'"); - if (_isSecure) { - method = "https"; - defaultPort = DEFAULT_SSL_PORT; - factory = new SSLProtocolSocketFactory(); - } else { - method = "http"; - defaultPort = DEFAULT_HTTP_PORT; - factory = new DefaultProtocolSocketFactory(); - } + addSupportHeaders(); + _headers = _method.getHeaders(); - Protocol protocol = new Protocol(method, factory, defaultPort); - HttpConnection conn = new HttpConnection(_host, _port, protocol); + TestUtil.logTrace( + "########## The real value set: " + getFollowRedirects()); - if (conn.isOpen()) { - throw new IllegalStateException("Connection incorrectly opened"); - } + RequestConfig config = RequestConfig.custom() + .setRedirectsEnabled(getFollowRedirects()).build(); - conn.open(); + try (CloseableHttpClient client = HttpClients.custom() + .setDefaultRequestConfig(config).build(); + CloseableHttpResponse response = client.execute(target, _method, + getState())) { - TestUtil.logMsg("[HttpRequest] Dispatching request: '" + _requestLine - + "' to target server at '" + _host + ":" + _port + "'"); + byte[] responseBody = response.getEntity() == null ? new byte[0] + : EntityUtils.toByteArray(response.getEntity()); - addSupportHeaders(); - _headers = _method.getRequestHeaders(); - - TestUtil.logTrace( - "########## The real value set: " + _method.getFollowRedirects()); - - client.getHostConfiguration().setHost(_host, _port, protocol); - - client.executeMethod(_method); - - return new HttpResponse(_host, _port, _isSecure, _method, getState()); - } else { - if (_isSecure) { - method = "https"; - defaultPort = DEFAULT_SSL_PORT; - factory = new SSLProtocolSocketFactory(); - } else { - method = "http"; - defaultPort = DEFAULT_HTTP_PORT; - factory = new DefaultProtocolSocketFactory(); - } - - Protocol protocol = new Protocol(method, factory, defaultPort); - HttpConnection conn = new HttpConnection(_host, _port, protocol); - - if (conn.isOpen()) { - throw new IllegalStateException("Connection incorrectly opened"); - } - - conn.open(); - - TestUtil.logMsg("[HttpRequest] Dispatching request: '" + _requestLine - + "' to target server at '" + _host + ":" + _port + "'"); - - addSupportHeaders(); - _headers = _method.getRequestHeaders(); - - TestUtil.logTrace( - "########## The real value set: " + _method.getFollowRedirects()); - - _method.execute(getState(), conn); - - return new HttpResponse(_host, _port, _isSecure, _method, getState()); + return new HttpResponse(_host, _port, _isSecure, _method.getPath(), + response.getVersion(), response.getCode(), response.getReasonPhrase(), + response.getHeaders(), responseBody, getState()); } } @@ -426,9 +372,11 @@ * * @return HttpState current state */ - public HttpState getState() { + public HttpClientContext getState() { if (_state == null) { - _state = new HttpState(); + _state = HttpClientContext.create(); + _state.setCredentialsProvider(new BasicCredentialsProvider()); + _state.setCookieStore(new BasicCookieStore()); } return _state; } @@ -441,7 +389,7 @@ for (Header _header : _headers) { sb.append(" [REQUEST HEADER] -> "); - sb.append(_header.toExternalForm()).append('\n'); + sb.append(formatHeader(_header)).append('\n'); } } @@ -463,33 +411,26 @@ String cookieLine = cookieHeader.substring(cookieHeader.indexOf(':') + 1) .trim(); StringTokenizer st = new StringTokenizer(cookieLine, " ;"); - Cookie cookie = new Cookie(); - cookie.setVersion(1); - - getState(); - - if (cookieLine.indexOf("$Version") == -1) { - cookie.setVersion(0); - _method.getParams().setCookiePolicy(CookiePolicy.NETSCAPE); - } - + BasicClientCookie cookie = null; while (st.hasMoreTokens()) { String token = st.nextToken(); if (token.charAt(0) != '$' && !token.startsWith("Domain") && !token.startsWith("Path")) { - cookie.setName(token.substring(0, token.indexOf('='))); - cookie.setValue(token.substring(token.indexOf('=') + 1)); - } else if (token.indexOf("Domain") > -1) { - cookie.setDomainAttributeSpecified(true); + String name = token.substring(0, token.indexOf('=')); + String value = token.substring(token.indexOf('=') + 1); + cookie = new BasicClientCookie(name, value); + } else if (cookie != null && token.indexOf("Domain") > -1) { cookie.setDomain(token.substring(token.indexOf('=') + 1)); - } else if (token.indexOf("Path") > -1) { - cookie.setPathAttributeSpecified(true); + } else if (cookie != null && token.indexOf("Path") > -1) { cookie.setPath(token.substring(token.indexOf('=') + 1)); } } - _state.addCookie(cookie); + if (cookie != null) { + getState().getCookieStore().addCookie(cookie); + _useCookies = true; + } } /** @@ -528,16 +469,16 @@ * to use basic authentication */ private void setBasicAuthorizationHeader() { - UsernamePasswordCredentials cred = (UsernamePasswordCredentials) getState() - .getCredentials(new AuthScope(_host, _port, null)); - String authString = null; - if (cred != null) { - authString = "Basic " + Util.getBase64EncodedString( - cred.getUserName() + ":" + cred.getPassword()); + Credentials cred = getState().getCredentialsProvider() + .getCredentials(new AuthScope(_host, _port), null); + if (cred instanceof UsernamePasswordCredentials) { + UsernamePasswordCredentials upCred = (UsernamePasswordCredentials) cred; + String authString = "Basic " + Util.getBase64EncodedString( + upCred.getUserName() + ":" + String.valueOf(upCred.getUserPassword())); + _method.setHeader("Authorization", authString); } else { TestUtil.logTrace("[HttpRequest] NULL CREDENTIALS"); } - _method.setRequestHeader("Authorization", authString); } /** @@ -545,8 +486,7 @@ */ private void setContentLengthHeader() { if (_contentLength > 0) { - _method.setRequestHeader("Content-Length", - Integer.toString(_contentLength)); + _method.setHeader("Content-Length", Integer.toString(_contentLength)); } } @@ -562,9 +502,9 @@ */ private void setHostHeader() { if (_port == DEFAULT_HTTP_PORT || _port == DEFAULT_SSL_PORT) { - _method.setRequestHeader("Host", _host); + _method.setHeader("Host", _host); } else { - _method.setRequestHeader("Host", _host + ":" + _port); + _method.setHeader("Host", _host + ":" + _port); } } @@ -573,14 +513,30 @@ */ private void setCookieHeader() { if (_useCookies) { - Cookie[] cookies = _state.getCookies(); - if (cookies != null && cookies.length > 0) { - Header cHeader = CookiePolicy.getCookieSpec(CookiePolicy.RFC_2109) - .formatCookieHeader(_state.getCookies()); - if (cHeader != null) { - _method.setRequestHeader(cHeader); + List<Cookie> cookies = getState().getCookieStore().getCookies(); + if (cookies != null && !cookies.isEmpty()) { + StringBuilder cookieHeader = new StringBuilder(); + for (Cookie cookie : cookies) { + if (cookieHeader.length() > 0) { + cookieHeader.append("; "); + } + cookieHeader.append(cookie.getName()).append('=') + .append(cookie.getValue()); + } + if (cookieHeader.length() > 0) { + _method.setHeader("Cookie", cookieHeader.toString()); } } } } + + private boolean isEntityEnclosingMethod() { + String requestMethod = _method.getMethod(); + return "POST".equals(requestMethod) || "PUT".equals(requestMethod) + || "PATCH".equals(requestMethod); + } + + private String formatHeader(Header header) { + return header == null ? "null" : header.getName() + ": " + header.getValue(); + } }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/HttpResponse.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/HttpResponse.java index 006a092..14d8d79 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/HttpResponse.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/HttpResponse.java
@@ -23,12 +23,11 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.HttpMethodBase; -import org.apache.commons.httpclient.HttpState; -import org.apache.commons.httpclient.HttpVersion; +import org.apache.hc.client5.http.protocol.HttpClientContext; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.ProtocolVersion; import ee.jakarta.tck.ws.rs.common.webclient.Util; @@ -49,14 +48,9 @@ private static final String CONTENT_TYPE = "Content-Type"; /** - * Wrapped HttpMethod used to pull response info from. - */ - private HttpMethod _method = null; - - /** * HttpState obtained after execution of request */ - private HttpState _state = null; + private HttpClientContext _state = null; /** * Charset encoding returned in the response @@ -84,14 +78,32 @@ */ private boolean _isSecure; + private String _path; + + private ProtocolVersion _version; + + private int _statusCode; + + private String _reasonPhrase; + + private Header[] _headers; + + private byte[] _rawResponseBody; + /** Creates new HttpResponse */ - public HttpResponse(String host, int port, boolean isSecure, - HttpMethod method, HttpState state) { + public HttpResponse(String host, int port, boolean isSecure, String path, + ProtocolVersion version, int statusCode, String reasonPhrase, + Header[] headers, byte[] rawResponseBody, HttpClientContext state) { _host = host; _port = port; _isSecure = isSecure; - _method = method; + _path = path; + _version = version; + _statusCode = statusCode; + _reasonPhrase = reasonPhrase; + _headers = headers; + _rawResponseBody = rawResponseBody == null ? new byte[0] : rawResponseBody; _state = state; } @@ -106,7 +118,7 @@ * @return HTTP status code */ public String getStatusCode() { - return Integer.toString(_method.getStatusCode()); + return Integer.toString(_statusCode); } /** @@ -115,7 +127,7 @@ * @return HTTP reason-phrase */ public String getReasonPhrase() { - return _method.getStatusText(); + return _reasonPhrase; } /** @@ -124,7 +136,7 @@ * @return response headers */ public Header[] getResponseHeaders() { - return _method.getResponseHeaders(); + return _headers; } /** @@ -133,7 +145,21 @@ * @return response headers */ public Header[] getResponseHeaders(String headerName) { - return _method.getResponseHeaders(headerName); + int count = 0; + for (Header header : _headers) { + if (header.getName().equalsIgnoreCase(headerName)) { + count++; + } + } + + Header[] filtered = new Header[count]; + int idx = 0; + for (Header header : _headers) { + if (header.getName().equalsIgnoreCase(headerName)) { + filtered[idx++] = header; + } + } + return filtered; } /** @@ -143,7 +169,12 @@ * exist. */ public Header getResponseHeader(String headerName) { - return _method.getResponseHeader(headerName); + for (Header header : _headers) { + if (header.getName().equalsIgnoreCase(headerName)) { + return header; + } + } + return null; } /** @@ -158,13 +189,13 @@ /** * Returns the response as bytes (no encoding is performed by client. - * + * * @return the raw response bytes * @throws IOException * if an error occurs reading from server */ public byte[] getResponseBodyAsRawBytes() throws IOException { - return _method.getResponseBody(); + return _rawResponseBody; } /** @@ -180,13 +211,13 @@ /** * Returns the response body of the server without being encoding by the * client. - * + * * @return an unecoded String representation of the response * @throws IOException * if an error occurs reading from the server */ public String getResponseBodyAsRawString() throws IOException { - return _method.getResponseBodyAsString(); + return new String(_rawResponseBody, StandardCharsets.ISO_8859_1); } /** @@ -202,13 +233,13 @@ /** * Returns the response body as an InputStream without any encoding applied by * the client. - * + * * @return an InputStream to read the response * @throws IOException * if an error occurs reading from the server */ public InputStream getResponseBodyAsRawStream() throws IOException { - return _method.getResponseBodyAsStream(); + return new ByteArrayInputStream(_rawResponseBody); } /** @@ -217,10 +248,10 @@ * @return charset encoding */ public String getResponseEncoding() { - Header content = _method.getResponseHeader(CONTENT_TYPE); + Header content = getResponseHeader(CONTENT_TYPE); if (content != null) { String headerVal = content.getValue(); - int idx = headerVal.indexOf(";charset="); + int idx = headerVal.toLowerCase().indexOf(";charset="); if (idx > -1) { // content encoding included in response _encoding = headerVal.substring(idx + 9); @@ -234,7 +265,7 @@ * * @return an HttpState object */ - public HttpState getState() { + public HttpClientContext getState() { return _state; } @@ -247,21 +278,20 @@ StringBuffer sb = new StringBuffer(255); sb.append("[RESPONSE STATUS LINE] -> "); - sb.append(((HttpMethodBase) _method).getParams().getVersion() - .equals(HttpVersion.HTTP_1_1) ? "HTTP/1.1 " : "HTTP/1.0 "); - sb.append(_method.getStatusCode()).append(' '); - sb.append(_method.getStatusText()).append('\n'); - Header[] headers = _method.getResponseHeaders(); - if (headers != null && headers.length != 0) { - for (int i = 0; i < headers.length; i++) { + sb.append(_version == null ? "HTTP/1.1" : _version).append(' '); + sb.append(_statusCode).append(' '); + sb.append(_reasonPhrase).append('\n'); + if (_headers != null && _headers.length != 0) { + for (Header header : _headers) { sb.append(" [RESPONSE HEADER] -> "); - sb.append(headers[i].toExternalForm()).append('\n'); + sb.append(header.getName()).append(": ").append(header.getValue()) + .append('\n'); } } String resBody; try { - resBody = _method.getResponseBodyAsString(); + resBody = getResponseBodyAsRawString(); } catch (IOException ioe) { resBody = "UNEXECTED EXCEPTION: " + ioe.toString(); } @@ -290,7 +320,7 @@ } public String getPath() { - return _method.getPath(); + return _path; } /* @@ -306,7 +336,7 @@ private String getEncodedResponse() throws IOException { if (_responseBody == null) { _responseBody = Util.getEncodedStringFromStream( - _method.getResponseBodyAsStream(), getResponseEncoding()); + new ByteArrayInputStream(_rawResponseBody), getResponseEncoding()); } return _responseBody; }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/MethodFactory.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/MethodFactory.java index 1bf1a39..8160b70 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/MethodFactory.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/http/MethodFactory.java
@@ -20,18 +20,20 @@ package ee.jakarta.tck.ws.rs.common.webclient.http; +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; import java.util.NoSuchElementException; import java.util.StringTokenizer; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.HttpMethodBase; -import org.apache.commons.httpclient.HttpVersion; -import org.apache.commons.httpclient.methods.DeleteMethod; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.httpclient.methods.HeadMethod; -import org.apache.commons.httpclient.methods.OptionsMethod; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.hc.client5.http.classic.methods.HttpDelete; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpHead; +import org.apache.hc.client5.http.classic.methods.HttpOptions; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.classic.methods.HttpPut; +import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; +import org.apache.hc.core5.http.HttpVersion; import ee.jakarta.tck.ws.rs.lib.porting.TSURL; @@ -76,6 +78,17 @@ */ private static final String OPTIONS_METHOD = "OPTIONS"; + private static final Map<String, Class<? extends HttpUriRequestBase>> METHOD_MAP = new HashMap<String, Class<? extends HttpUriRequestBase>>(); + + static { + METHOD_MAP.put(GET_METHOD, HttpGet.class); + METHOD_MAP.put(POST_METHOD, HttpPost.class); + METHOD_MAP.put(PUT_METHOD, HttpPut.class); + METHOD_MAP.put(DELETE_METHOD, HttpDelete.class); + METHOD_MAP.put(HEAD_METHOD, HttpHead.class); + METHOD_MAP.put(OPTIONS_METHOD, HttpOptions.class); + } + /** * TSURL implementation */ @@ -88,6 +101,10 @@ private MethodFactory() { } + public static Map<String, Class<? extends HttpUriRequestBase>> getMethodMap() { + return METHOD_MAP; + } + /* * public methods * ======================================================================== @@ -100,10 +117,9 @@ * * @return HttpMethod based in request. */ - public static HttpMethod getInstance(String request) { + public static HttpUriRequestBase getInstance(String request) { StringTokenizer st = new StringTokenizer(request); String method; - String query = null; String uri; String version; try { @@ -115,38 +131,21 @@ "Request provided: " + request + " is malformed."); } - // check to see if there is a query string appended - // to the URI - int queryStart = uri.indexOf('?'); - if (queryStart != -1) { - query = uri.substring(queryStart + 1); - uri = uri.substring(0, queryStart); - } - - HttpMethodBase req; - - if (method.equals(GET_METHOD)) { - req = new GetMethod(uri); - } else if (method.equals(POST_METHOD)) { - req = new PostMethod(uri); - } else if (method.equals(PUT_METHOD)) { - req = new PutMethod(uri); - } else if (method.equals(DELETE_METHOD)) { - req = new DeleteMethod(uri); - } else if (method.equals(HEAD_METHOD)) { - req = new HeadMethod(uri); - } else if (method.equals(OPTIONS_METHOD)) { - req = new OptionsMethod(uri); - } else { + HttpUriRequestBase req; + Class<? extends HttpUriRequestBase> methodClass = METHOD_MAP.get(method); + if (methodClass == null) { throw new IllegalArgumentException("Invalid method: " + method); } - setHttpVersion(version, req); - - if (query != null) { - req.setQueryString(query); + try { + Constructor<? extends HttpUriRequestBase> constructor = methodClass + .getDeclaredConstructor(String.class); + req = constructor.newInstance(uri); + } catch (Exception e) { + throw new IllegalStateException(e); } + setHttpVersion(version, req); return req; } @@ -163,9 +162,9 @@ * @param method * method to adjust HTTP version */ - private static void setHttpVersion(String version, HttpMethodBase method) { + private static void setHttpVersion(String version, HttpUriRequestBase method) { final String oneOne = "HTTP/1.1"; - method.getParams().setVersion( + method.setVersion( (version.equals(oneOne) ? HttpVersion.HTTP_1_1 : HttpVersion.HTTP_1_0)); } }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/validation/WebValidatorBase.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/validation/WebValidatorBase.java index a3582c2..c2620ae 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/validation/WebValidatorBase.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/common/webclient/validation/WebValidatorBase.java
@@ -24,7 +24,7 @@ import java.util.Iterator; import java.util.List; -import org.apache.commons.httpclient.Header; +import org.apache.hc.core5.http.Header; import ee.jakarta.tck.ws.rs.lib.util.TestUtil; import ee.jakarta.tck.ws.rs.common.webclient.WebTestCase; @@ -575,14 +575,14 @@ StringBuffer sb = new StringBuffer(255); sb.append("[WebValidatorBase] Unable to find the following header"); sb.append(" in the server's response: "); - sb.append(currentHeader.toExternalForm()).append("\n"); + sb.append(formatHeader(currentHeader)).append("\n"); sb.append("[WebValidatorBase] Response headers recieved from"); sb.append(" server:"); Header[] resHeaders = _res.getResponseHeaders(); for (int i = 0; i < resHeaders.length; i++) { sb.append("\n\tResponseHeader -> "); - sb.append(resHeaders[i].toExternalForm()); + sb.append(formatHeader(resHeaders[i])); } sb.append("\n"); TestUtil.logErr(sb.toString()); @@ -590,7 +590,7 @@ return false; } else { TestUtil.logTrace("[WebValidatorBase] Found expected header: " - + currentHeader.toExternalForm()); + + formatHeader(currentHeader)); return true; } } @@ -635,14 +635,14 @@ StringBuffer sb = new StringBuffer(255); sb.append("[WebValidatorBase] Unexpected header found in the "); sb.append("server's response: "); - sb.append(currentHeader.toExternalForm()).append("\n"); + sb.append(formatHeader(currentHeader)).append("\n"); sb.append("[WebValidatorBase] Response headers recieved from"); sb.append("server:"); Header[] resHeaders = _res.getResponseHeaders(); for (int j = 0; j < resHeaders.length; j++) { sb.append("\n\tResponseHeader -> "); - sb.append(resHeaders[j].toExternalForm()); + sb.append(formatHeader(resHeaders[j])); } sb.append("\n"); TestUtil.logErr(sb.toString()); @@ -666,4 +666,8 @@ return false; } } + + private String formatHeader(Header header) { + return header.getName() + ": " + header.getValue(); + } }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/ee/rs/core/request/JAXRSClientIT.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/ee/rs/core/request/JAXRSClientIT.java index bdda2fe..463bec6 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/ee/rs/core/request/JAXRSClientIT.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/ee/rs/core/request/JAXRSClientIT.java
@@ -16,7 +16,7 @@ package ee.jakarta.tck.ws.rs.ee.rs.core.request; -import org.apache.commons.httpclient.Header; +import org.apache.hc.core5.http.Header; import java.io.InputStream; import java.io.IOException;
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/ee/rs/core/securitycontext/JAXRSClient.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/ee/rs/core/securitycontext/JAXRSClient.java index 38a85e4..a7ed5f3 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/ee/rs/core/securitycontext/JAXRSClient.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/ee/rs/core/securitycontext/JAXRSClient.java
@@ -16,7 +16,7 @@ package ee.jakarta.tck.ws.rs.ee.rs.core.securitycontext; -import org.apache.commons.httpclient.Header; +import org.apache.hc.core5.http.Header; import ee.jakarta.tck.ws.rs.common.webclient.http.HttpResponse; import ee.jakarta.tck.ws.rs.common.JAXRSCommonClient;
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/AdaptiveHttpRequest.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/AdaptiveHttpRequest.java index fab1801..70999f1 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/AdaptiveHttpRequest.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/AdaptiveHttpRequest.java
@@ -20,528 +20,18 @@ package ee.jakarta.tck.ws.rs.jaxrs21.ee.patch.server; -import java.io.IOException; -import java.util.StringTokenizer; +import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; -import org.apache.commons.httpclient.Cookie; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpConnection; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.HttpState; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; -import org.apache.commons.httpclient.cookie.CookiePolicy; -import org.apache.commons.httpclient.methods.EntityEnclosingMethod; -import org.apache.commons.httpclient.methods.StringRequestEntity; -import org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory; -import org.apache.commons.httpclient.protocol.Protocol; -import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; -import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory; - -import ee.jakarta.tck.ws.rs.lib.util.TestUtil; -import ee.jakarta.tck.ws.rs.common.webclient.Util; import ee.jakarta.tck.ws.rs.common.webclient.http.HttpRequest; -import ee.jakarta.tck.ws.rs.common.webclient.http.HttpResponse; - -/** - * Represents an HTTP client Request - */ public class AdaptiveHttpRequest extends HttpRequest { - /** - * Method representation of request. - */ - private HttpMethod _method = null; - /** - * Target web container host - */ - private String _host = null; - - /** - * Target web container port - */ - private int _port = DEFAULT_HTTP_PORT; - - /** - * Is the request going over SSL - */ - private boolean _isSecure = false; - - /** - * HTTP state - */ - private HttpState _state = null; - - /** - * Original request line for this request. - */ - private String _requestLine = null; - - /** - * Authentication type for current request - */ - private int _authType = NO_AUTHENTICATION; - - /** - * Flag to determine if session tracking will be used or not. - */ - private boolean _useCookies = false; - - /** - * Content length of request body. - */ - private int _contentLength = 0; - - Header[] _headers = null; - - /** - * Creates new HttpRequest based of the passed request line. The request line - * provied must be in the form of:<br> - * - * <pre> - * METHOD PATH HTTP-VERSION - * Ex. GET /index.html HTTP/1.0 - * </pre> - */ public AdaptiveHttpRequest(String requestLine, String host, int port) { - super("GET /fake.jsp HTTP/1.1", host, port); - _method = AdaptiveMethodFactory.getInstance(requestLine); - _method.setFollowRedirects(false); - _host = host; - _port = port; - - if (port == DEFAULT_SSL_PORT) { - _isSecure = true; - } - - // If we got this far, the request line is in the proper - // format - _requestLine = requestLine; + super(requestLine, host, port); } - /* - * public methods - * ======================================================================== - */ - - /** - * <code>getRequestPath</code> returns the request path for this particular - * request. - * - * @return String request path - */ - public String getRequestPath() { - return _method.getPath(); - } - - /** - * <code>getRequestMethod</code> returns the request type, i.e., GET, POST, - * etc. - * - * @return String request type - */ - public String getRequestMethod() { - return _method.getName(); - } - - /** - * <code>isSecureConnection()</code> indicates if the Request is secure or - * not. - * - * @return boolean whether Request is using SSL or not. - */ - public boolean isSecureRequest() { - return _isSecure; - } - - /** - * <code>setSecureRequest</code> configures this request to use SSL. - * - * @param secure - * - whether the Request uses SSL or not. - */ - public void setSecureRequest(boolean secure) { - _isSecure = secure; - } - - /** - * <code>setContent</code> will set the body for this request. Note, this is - * only valid for POST and PUT operations, however, if called and the request - * represents some other HTTP method, it will be no-op'd. - * - * @param content - * request content - */ - @SuppressWarnings("deprecation") - public void setContent(String content) { - if (_method instanceof EntityEnclosingMethod) { - ((EntityEnclosingMethod) _method) - .setRequestEntity(new StringRequestEntity(content)); - } - _contentLength = content.length(); - } - - /** - * <code>setAuthenticationCredentials configures the request to - * perform authentication. - * - * <p><code>username</code> and <code>password</code> cannot be null. - * </p> - * - * <p> - * It is legal for <code>realm</code> to be null. - * </p> - * - * @param username - * the user - * @param password - * the user's password - * @param authType - * authentication type - * @param realm - * authentication realm - */ - public void setAuthenticationCredentials(String username, String password, - int authType, String realm) { - if (username == null) { - throw new IllegalArgumentException("Username cannot be null"); - } - - if (password == null) { - throw new IllegalArgumentException("Password cannot be null"); - } - - UsernamePasswordCredentials cred = new UsernamePasswordCredentials(username, - password); - AuthScope scope = new AuthScope(_host, _port, realm); - getState().setCredentials(scope, cred); - TestUtil.logTrace("[HttpRequest] Added credentials for '" + username - + "' with password '" + password + "' in realm '" + realm + "'"); - - _authType = authType; - } - - /** - * <code>addRequestHeader</code> adds a request header to this request. If a - * request header of the same name already exists, the new value, will be - * added to the set of already existing values. - * - * <strong>NOTE:</strong> that header names are not case-sensitive. - * - * @param headerName - * request header name - * @param headerValue - * request header value - */ - public void addRequestHeader(String headerName, String headerValue) { - _method.addRequestHeader(headerName, headerValue); - TestUtil.logTrace("[HttpRequest] Added request header: " - + _method.getRequestHeader(headerName).toExternalForm()); - } - - public void addRequestHeader(String header) { - StringTokenizer st = new StringTokenizer(header, "|"); - while (st.hasMoreTokens()) { - String h = st.nextToken(); - if (h.toLowerCase().startsWith("cookie")) { - createCookie(h); - continue; - } - int col = h.indexOf(':'); - addRequestHeader(h.substring(0, col).trim(), h.substring(col + 1).trim()); - } - } - - /** - * <code>setRequestHeader</code> sets a request header for this request - * overwritting any previously existing header/values with the same name. - * - * <strong>NOTE:</strong> Header names are not case-sensitive. - * - * @param headerName - * request header name - * @param headerValue - * request header value - */ - public void setRequestHeader(String headerName, String headerValue) { - _method.setRequestHeader(headerName, headerValue); - TestUtil.logTrace("[HttpRequest] Set request header: " - + _method.getRequestHeader(headerName).toExternalForm()); - - } - - /** - * <code>setFollowRedirects</code> indicates whether HTTP redirects are - * followed. By default, redirects are not followed. - */ - public void setFollowRedirects(boolean followRedirects) { - _method.setFollowRedirects(followRedirects); - } - - /** - * <code>getFollowRedirects</code> indicates whether HTTP redirects are - * followed. - */ - public boolean getFollowRedirects() { - return _method.getFollowRedirects(); - } - - /** - * <code>setState</code> will set the HTTP state for the current request (i.e. - * session tracking). This has the side affect - */ - public void setState(HttpState state) { - _state = state; - _useCookies = true; - } - - /** - * <code>execute</code> will dispatch the current request to the target - * server. - * - * @return HttpResponse the server's response. - * @throws IOException - * if an I/O error occurs during dispatch. - */ - public HttpResponse execute() throws IOException, HttpException { - String method; - int defaultPort; - ProtocolSocketFactory factory; - - if (_method.getFollowRedirects()) { - client = new HttpClient(); - - if (_isSecure) { - method = "https"; - defaultPort = DEFAULT_SSL_PORT; - factory = new SSLProtocolSocketFactory(); - } else { - method = "http"; - defaultPort = DEFAULT_HTTP_PORT; - factory = new DefaultProtocolSocketFactory(); - } - - Protocol protocol = new Protocol(method, factory, defaultPort); - HttpConnection conn = new HttpConnection(_host, _port, protocol); - - if (conn.isOpen()) { - throw new IllegalStateException("Connection incorrectly opened"); - } - - conn.open(); - - TestUtil.logMsg("[HttpRequest] Dispatching request: '" + _requestLine - + "' to target server at '" + _host + ":" + _port + "'"); - - addSupportHeaders(); - _headers = _method.getRequestHeaders(); - - TestUtil.logTrace( - "########## The real value set: " + _method.getFollowRedirects()); - - client.getHostConfiguration().setHost(_host, _port, protocol); - - client.executeMethod(_method); - - return new HttpResponse(_host, _port, _isSecure, _method, getState()); - } else { - if (_isSecure) { - method = "https"; - defaultPort = DEFAULT_SSL_PORT; - factory = new SSLProtocolSocketFactory(); - } else { - method = "http"; - defaultPort = DEFAULT_HTTP_PORT; - factory = new DefaultProtocolSocketFactory(); - } - - Protocol protocol = new Protocol(method, factory, defaultPort); - HttpConnection conn = new HttpConnection(_host, _port, protocol); - - if (conn.isOpen()) { - throw new IllegalStateException("Connection incorrectly opened"); - } - - conn.open(); - - TestUtil.logMsg("[HttpRequest] Dispatching request: '" + _requestLine - + "' to target server at '" + _host + ":" + _port + "'"); - - addSupportHeaders(); - _headers = _method.getRequestHeaders(); - - TestUtil.logTrace( - "########## The real value set: " + _method.getFollowRedirects()); - - _method.execute(getState(), conn); - - return new HttpResponse(_host, _port, _isSecure, _method, getState()); - } - } - - /** - * Returns the current state for this request. - * - * @return HttpState current state - */ - public HttpState getState() { - if (_state == null) { - _state = new HttpState(); - } - return _state; - } - - public String toString() { - StringBuffer sb = new StringBuffer(255); - sb.append("[REQUEST LINE] -> ").append(_requestLine).append('\n'); - - if (_headers != null && _headers.length != 0) { - - for (Header _header : _headers) { - sb.append(" [REQUEST HEADER] -> "); - sb.append(_header.toExternalForm()).append('\n'); - } - } - - if (_contentLength != 0) { - sb.append(" [REQUEST BODY LENGTH] -> ").append(_contentLength); - sb.append('\n'); - } - - return sb.toString(); - - } - - /* - * private methods - * ======================================================================== - */ - - private void createCookie(String cookieHeader) { - String cookieLine = cookieHeader.substring(cookieHeader.indexOf(':') + 1) - .trim(); - StringTokenizer st = new StringTokenizer(cookieLine, " ;"); - Cookie cookie = new Cookie(); - cookie.setVersion(1); - - getState(); - - if (cookieLine.indexOf("$Version") == -1) { - cookie.setVersion(0); - _method.getParams().setCookiePolicy(CookiePolicy.NETSCAPE); - } - - while (st.hasMoreTokens()) { - String token = st.nextToken(); - - if (token.charAt(0) != '$' && !token.startsWith("Domain") - && !token.startsWith("Path")) { - cookie.setName(token.substring(0, token.indexOf('='))); - cookie.setValue(token.substring(token.indexOf('=') + 1)); - } else if (token.indexOf("Domain") > -1) { - cookie.setDomainAttributeSpecified(true); - cookie.setDomain(token.substring(token.indexOf('=') + 1)); - } else if (token.indexOf("Path") > -1) { - cookie.setPathAttributeSpecified(true); - cookie.setPath(token.substring(token.indexOf('=') + 1)); - } - } - _state.addCookie(cookie); - - } - - /** - * Adds any support request headers necessary for this request. These headers - * will be added based on the state of the request. - */ - private void addSupportHeaders() { - - // Authentication headers - // NOTE: Possibly move logic to generic method - switch (_authType) { - case NO_AUTHENTICATION: - break; - case BASIC_AUTHENTICATION: - setBasicAuthorizationHeader(); - break; - case DIGEST_AUTHENTICATION: - throw new UnsupportedOperationException( - "Digest Authentication is not currently " + "supported"); - } - - // A Host header will be added to each request to handle - // cases where virtual hosts are used, or there is no DNS - // available on the system where the container is running. - setHostHeader(); - - // Content length header - setContentLengthHeader(); - - // Cookies - setCookieHeader(); - } - - /** - * Sets a basic authentication header in the request is Request is configured - * to use basic authentication - */ - private void setBasicAuthorizationHeader() { - UsernamePasswordCredentials cred = (UsernamePasswordCredentials) getState() - .getCredentials(new AuthScope(_host, _port, null)); - String authString = null; - if (cred != null) { - authString = "Basic " + Util.getBase64EncodedString( - cred.getUserName() + ":" + cred.getPassword()); - } else { - TestUtil.logTrace("[HttpRequest] NULL CREDENTIALS"); - } - _method.setRequestHeader("Authorization", authString); - } - - /** - * Sets a Content-Length header in the request if content is present - */ - private void setContentLengthHeader() { - if (_contentLength > 0) { - _method.setRequestHeader("Content-Length", - Integer.toString(_contentLength)); - } - } - - /** - * Sets a host header in the request. If the configured host value is an IP - * address, the Host header will be sent, but without any value. - * - * If we adhered to the HTTP/1.1 spec, the Host header must be empty of the - * target server is identified via IP address. However, no user agents I've - * tested follow this. And if a custom client library does this, it may not - * work properly with the target server. For now, the Host request-header will - * always have a value. - */ - private void setHostHeader() { - if (_port == DEFAULT_HTTP_PORT || _port == DEFAULT_SSL_PORT) { - _method.setRequestHeader("Host", _host); - } else { - _method.setRequestHeader("Host", _host + ":" + _port); - } - } - - /** - * Sets a Cookie header if this request is using cookies. - */ - private void setCookieHeader() { - if (_useCookies) { - Cookie[] cookies = _state.getCookies(); - if (cookies != null && cookies.length > 0) { - Header cHeader = CookiePolicy.getCookieSpec(CookiePolicy.RFC_2109) - .formatCookieHeader(_state.getCookies()); - if (cHeader != null) { - _method.setRequestHeader(cHeader); - } - } - } + @Override + protected HttpUriRequestBase createMethod(String requestLine) { + return AdaptiveMethodFactory.getInstance(requestLine); } }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/AdaptiveMethodFactory.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/AdaptiveMethodFactory.java index dd77372..43490a0 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/AdaptiveMethodFactory.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/AdaptiveMethodFactory.java
@@ -20,165 +20,22 @@ package ee.jakarta.tck.ws.rs.jaxrs21.ee.patch.server; -import java.lang.reflect.Constructor; -import java.util.HashMap; import java.util.Map; -import java.util.NoSuchElementException; -import java.util.StringTokenizer; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.HttpMethodBase; -import org.apache.commons.httpclient.HttpVersion; -import org.apache.commons.httpclient.methods.DeleteMethod; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.httpclient.methods.HeadMethod; -import org.apache.commons.httpclient.methods.OptionsMethod; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; -import ee.jakarta.tck.ws.rs.lib.porting.TSURL; - -/** - * Simple factory class which returns HttpMethod implementations based on a - * request line. - * <p> - * For example, a request line of <tt>GET /index.jsp HTTP/1.0</tt> would return - * an HttpMethod implementation that handles GET requests using HTTP/1.0. - * </p> - */ +import ee.jakarta.tck.ws.rs.common.webclient.http.MethodFactory; public class AdaptiveMethodFactory { - /** - * HTTP GET - */ - private static final String GET_METHOD = "GET"; - - /** - * HTTP POST - */ - private static final String POST_METHOD = "POST"; - - /** - * HTTP HEAD - */ - private static final String HEAD_METHOD = "HEAD"; - - /** - * HTTP PUT - */ - private static final String PUT_METHOD = "PUT"; - - /** - * HTTP DELETE - */ - private static final String DELETE_METHOD = "DELETE"; - - /** - * HTTP OPTIONS - */ - private static final String OPTIONS_METHOD = "OPTIONS"; - - private static final Map<String, Class<? extends HttpMethodBase>> METHOD_MAP = new HashMap<>(); - static { - METHOD_MAP.put(GET_METHOD, GetMethod.class); - METHOD_MAP.put(POST_METHOD, PostMethod.class); - METHOD_MAP.put(PUT_METHOD, PutMethod.class); - METHOD_MAP.put(DELETE_METHOD, DeleteMethod.class); - METHOD_MAP.put(HEAD_METHOD, HeadMethod.class); - METHOD_MAP.put(OPTIONS_METHOD, OptionsMethod.class); - } - - /** - * TSURL implementation - */ - private static final TSURL TS_URL = new TSURL(); - - /** - * Private constructor as all interaction with this class is through the - * getInstance() method. - */ private AdaptiveMethodFactory() { } - /* - * public methods - * ======================================================================== - */ - - public static final Map<String, Class<? extends HttpMethodBase>> getMethodMap() { - return METHOD_MAP; + public static Map<String, Class<? extends HttpUriRequestBase>> getMethodMap() { + return MethodFactory.getMethodMap(); } - /** - * Returns the approriate request method based on the provided request string. - * The request must be in the format of METHOD URI_PATH HTTP_VERSION, i.e. GET - * /index.jsp HTTP/1.1. - * - * @return HttpMethod based in request. - */ - public static HttpMethod getInstance(String request) { - StringTokenizer st = new StringTokenizer(request); - String method; - String query = null; - String uri; - String version; - try { - method = st.nextToken(); - uri = TS_URL.getRequest(st.nextToken()); - version = st.nextToken(); - } catch (NoSuchElementException nsee) { - throw new IllegalArgumentException( - "Request provided: " + request + " is malformed."); - } - - // check to see if there is a query string appended - // to the URI - int queryStart = uri.indexOf('?'); - if (queryStart != -1) { - query = uri.substring(queryStart + 1); - uri = uri.substring(0, queryStart); - } - - HttpMethodBase req; - Class<? extends HttpMethodBase> methodClass = METHOD_MAP.get(method); - if (methodClass == null) { - throw new IllegalArgumentException("Invalid method: " + method); - } - - Constructor<? extends HttpMethodBase> constructor; - try { - constructor = methodClass.getDeclaredConstructor(String.class); - req = constructor.newInstance(uri); - } catch (Exception e) { - throw new IllegalStateException(e); - } - - setHttpVersion(version, req); - - if (query != null) { - req.setQueryString(query); - } - - return req; - } - - /* - * private methods - * ======================================================================== - */ - - /** - * Sets the HTTP version for the method in question. - * - * @param version - * HTTP version to use for this request - * @param method - * method to adjust HTTP version - */ - private static void setHttpVersion(String version, HttpMethodBase method) { - final String oneOne = "HTTP/1.1"; - method.getParams().setVersion( - (version.equals(oneOne) ? HttpVersion.HTTP_1_1 : HttpVersion.HTTP_1_0)); + public static HttpUriRequestBase getInstance(String request) { + return MethodFactory.getInstance(request); } }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/PatchMethod.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/PatchMethod.java index be50bc3..7ac9f77 100644 --- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/PatchMethod.java +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/patch/server/PatchMethod.java
@@ -16,19 +16,17 @@ package ee.jakarta.tck.ws.rs.jaxrs21.ee.patch.server; -import org.apache.commons.httpclient.methods.EntityEnclosingMethod; +import java.net.URI; -public class PatchMethod extends EntityEnclosingMethod { +import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; + +public class PatchMethod extends HttpUriRequestBase { + public PatchMethod() { - super(); + this("/"); } public PatchMethod(String uri) { - super(uri); - } - - @Override - public String getName() { - return "PATCH"; + super("PATCH", URI.create(uri)); } }
diff --git a/jersey-tck/pom.xml b/jersey-tck/pom.xml index 68898c8..dbf942c 100644 --- a/jersey-tck/pom.xml +++ b/jersey-tck/pom.xml
@@ -131,12 +131,6 @@ </dependency> <dependency> - <groupId>commons-httpclient</groupId> - <artifactId>commons-httpclient</artifactId> - <version>3.1</version> - </dependency> - - <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-server</artifactId> <version>${jersey.version}</version>