Skip to content

Commit 6ba3150

Browse files
authored
Upgrade Apache HttpClient 4.5.13 -> 5.1.3 (#35)
1 parent 2b76687 commit 6ba3150

21 files changed

+200
-227
lines changed

labkey-client-api/CHANGELOG.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
# The LabKey Remote API Library for Java - Change Log
22

3-
## version 2.?.?
4-
*Released*: TBD
3+
## version 3.0.0
4+
*Released*: 14 September 2022
5+
* Migrate internal HTTP handling to use Apache HttpClient 5.1.x
6+
* Switch `StopImpersonatingCommand` to disable redirects (mimicking previous behavior)
7+
* Add `Connection.stopImpersonating()` and deprecate `stopImpersonate()`
8+
* Remove deprecated methods:
9+
* ApiVersionException() (use constructor that takes contentType)
10+
* CommandException() (use constructor that takes contentType)
11+
* Connection.getBaseUrl() (use Connection.getBaseURI())
12+
* CredentialsProvider.configureRequest() (use variant that takes a URI)
13+
* Filter.NON_BLANK (use Filter.NONBLANK)
14+
* Filter.getCaption() (use Filter.getDisplayValue())
15+
* Filter.getName() (use Filter.getUrlKey())
16+
* Filter.isDataValueRequired() (use Filter.isValueRequired())
517
* Remove SAS macros and wrapper classes
6-
* Add `CreateFolderCommand` and `CreateProjectCommand`
18+
* Add `CreateFolderCommand`
19+
* Add `CreateProjectCommand` (earliest compatible LabKey Server version: 22.3.0)
720
* Update `LogoutCommand` to use POST
821

922
## version 2.0.0

labkey-client-api/build.gradle

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,19 @@ repositories {
5757

5858
group "org.labkey.api"
5959

60-
version "2.1.0-SNAPSHOT"
60+
version "3.1.0-SNAPSHOT"
6161

6262
dependencies {
63-
implementation "org.apache.httpcomponents:httpmime:${httpmimeVersion}"
6463
api ("com.googlecode.json-simple:json-simple:${jsonSimpleVersion}")
6564
{
6665
// exclude this because it gets in the way of our own JSON object implementations from server/api
6766
exclude group: "org.json", module:"json"
6867
}
68+
api "org.apache.httpcomponents.client5:httpclient5:${httpclient5Version}"
69+
api "org.apache.httpcomponents.core5:httpcore5:${httpcore5Version}"
6970
implementation "net.sf.opencsv:opencsv:${opencsvVersion}"
7071
implementation "commons-logging:commons-logging:${commonsLoggingVersion}"
71-
api "org.apache.httpcomponents:httpclient:${httpclientVersion}"
7272
implementation "commons-codec:commons-codec:${commonsCodecVersion}"
73-
api "org.apache.httpcomponents:httpcore:${httpcoreVersion}"
7473
}
7574

7675
configurations.all

labkey-client-api/gradle.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ commonsCodecVersion=1.15
1414
commonsLoggingVersion=1.2
1515

1616
hamcrestVersion=1.3
17-
httpclientVersion=4.5.13
18-
httpcoreVersion=4.4.14
19-
httpmimeVersion=4.5.13
17+
18+
httpclient5Version=5.1.3
19+
httpcore5Version=5.1.4
2020

2121
jsonSimpleVersion=1.1.1
2222

labkey-client-api/src/org/labkey/remoteapi/ApiKeyCredentialsProvider.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
*/
1616
package org.labkey.remoteapi;
1717

18-
import org.apache.http.auth.AuthenticationException;
19-
import org.apache.http.client.methods.HttpUriRequest;
20-
import org.apache.http.client.protocol.HttpClientContext;
18+
import org.apache.hc.client5.http.auth.AuthenticationException;
19+
import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
20+
import org.apache.hc.client5.http.protocol.HttpClientContext;
2121

2222
import java.net.URI;
2323

labkey-client-api/src/org/labkey/remoteapi/ApiVersionException.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,6 @@
2424
*/
2525
public class ApiVersionException extends CommandException
2626
{
27-
/**
28-
* @deprecated Use {@link #ApiVersionException(String, int, Map, String, String)}
29-
*/
30-
ApiVersionException(String message, int statusCode, Map<String, Object> properties, String responseText)
31-
{
32-
this(message, statusCode, properties, responseText, null);
33-
}
34-
3527
ApiVersionException(String message, int statusCode, Map<String, Object> properties, String responseText, String contentType)
3628
{
3729
super(message, statusCode, properties, responseText, contentType);

labkey-client-api/src/org/labkey/remoteapi/BasicAuthCredentialsProvider.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@
1515
*/
1616
package org.labkey.remoteapi;
1717

18-
import org.apache.http.auth.AuthScope;
19-
import org.apache.http.auth.AuthenticationException;
20-
import org.apache.http.auth.Credentials;
21-
import org.apache.http.auth.UsernamePasswordCredentials;
22-
import org.apache.http.client.methods.HttpUriRequest;
23-
import org.apache.http.client.protocol.HttpClientContext;
24-
import org.apache.http.impl.auth.BasicScheme;
25-
import org.apache.http.impl.client.BasicCredentialsProvider;
18+
import org.apache.hc.client5.http.auth.AuthScope;
19+
import org.apache.hc.client5.http.auth.AuthenticationException;
20+
import org.apache.hc.client5.http.auth.Credentials;
21+
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
22+
import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
23+
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
24+
import org.apache.hc.client5.http.impl.auth.BasicScheme;
25+
import org.apache.hc.client5.http.protocol.HttpClientContext;
2626

2727
import java.net.URI;
2828

@@ -43,12 +43,10 @@ public BasicAuthCredentialsProvider(String email, String password)
4343
@Override
4444
public void configureRequest(URI baseURI, HttpUriRequest request, HttpClientContext httpClientContext) throws AuthenticationException
4545
{
46-
AuthScope scope = new AuthScope(baseURI.getHost(), AuthScope.ANY_PORT, AuthScope.ANY_REALM);
4746
BasicCredentialsProvider provider = new BasicCredentialsProvider();
48-
Credentials credentials = new UsernamePasswordCredentials(_email, _password);
47+
AuthScope scope = new AuthScope(baseURI.getHost(), -1);
48+
Credentials credentials = new UsernamePasswordCredentials(_email, _password.toCharArray());
4949
provider.setCredentials(scope, credentials);
50-
5150
httpClientContext.setCredentialsProvider(provider);
52-
request.addHeader(new BasicScheme().authenticate(credentials, request, httpClientContext));
5351
}
5452
}

labkey-client-api/src/org/labkey/remoteapi/Command.java

Lines changed: 40 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@
1515
*/
1616
package org.labkey.remoteapi;
1717

18-
import org.apache.commons.codec.EncoderException;
19-
import org.apache.commons.codec.net.URLCodec;
2018
import org.apache.commons.logging.LogFactory;
21-
import org.apache.http.Header;
22-
import org.apache.http.auth.AuthenticationException;
23-
import org.apache.http.client.methods.CloseableHttpResponse;
24-
import org.apache.http.client.methods.HttpGet;
25-
import org.apache.http.client.methods.HttpUriRequest;
26-
import org.apache.http.client.utils.URIBuilder;
19+
import org.apache.hc.client5.http.auth.AuthenticationException;
20+
import org.apache.hc.client5.http.classic.methods.HttpGet;
21+
import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
22+
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
23+
import org.apache.hc.core5.http.Header;
24+
import org.apache.hc.core5.net.URIBuilder;
2725
import org.json.simple.JSONObject;
2826
import org.json.simple.JSONValue;
2927

@@ -256,12 +254,12 @@ private Response(CloseableHttpResponse httpResponse, String contentType, Long co
256254

257255
public String getStatusText()
258256
{
259-
return _httpResponse.getStatusLine().getReasonPhrase();
257+
return _httpResponse.getReasonPhrase();
260258
}
261259

262260
public int getStatusCode()
263261
{
264-
return _httpResponse.getStatusLine().getStatusCode();
262+
return _httpResponse.getCode();
265263
}
266264

267265
public String getContentType()
@@ -328,7 +326,7 @@ protected Response _execute(Connection connection, String folderPath) throws Com
328326
{
329327
//construct and initialize the HttpUriRequest
330328
request = getHttpRequest(connection, folderPath);
331-
LogFactory.getLog(Command.class).info("Requesting URL: " + request.getURI().toString());
329+
LogFactory.getLog(Command.class).info("Requesting URL: " + request.getRequestUri());
332330

333331
//execute the request
334332
httpResponse = connection.executeRequest(request, getTimeout());
@@ -448,19 +446,13 @@ protected HttpUriRequest getHttpRequest(Connection connection, String folderPath
448446
// TODO (Dave 11/11/14 -- as far as I can tell the default of the AuthSchemes is to automatically handle challenges
449447
// method.setDoAuthentication(true);
450448

449+
// NOTE: Fairly sure that the "unescaped" comment below is obsolete
450+
// TODO: Combine getActionUrl() and addParameters() into a single method
451451
//construct a URI from the results of the getActionUrl method
452452
//note that this method returns an unescaped URL, so pass
453453
//false for the second parameter to escape it
454454
URI uri = getActionUrl(connection, folderPath);
455-
456-
//the query string values will need to be escaped as they are
457-
//put into the query string, and we don't want to re-escape the
458-
//entire thing, as the %, & and = characters will be escaped again
459-
//so add this separately as a raw value
460-
//(indicating that it has already been escaped)
461-
String queryString = getQueryString();
462-
if (null != queryString)
463-
uri = new URIBuilder(uri).setQuery(queryString).build();
455+
uri = addParameters(uri);
464456

465457
return createRequest(uri);
466458
}
@@ -487,7 +479,7 @@ protected HttpUriRequest createRequest(URI uri)
487479
* @return The URL
488480
* @throws URISyntaxException if the uri constructed from the parameters is malformed
489481
*/
490-
protected URI getActionUrl(Connection connection, String folderPath) throws URISyntaxException
482+
private URI getActionUrl(Connection connection, String folderPath) throws URISyntaxException
491483
{
492484
URI uri = connection.getBaseURI();
493485

@@ -520,60 +512,55 @@ protected URI getActionUrl(Connection connection, String folderPath) throws URIS
520512
}
521513

522514
/**
523-
* Returns the query string portion of the URL for this command.
515+
* Adds all parameters to the passed URI
524516
* <p>
525-
* The parameters in the query string should be encoded to avoid parsing errors on the server.
526-
* @return The query string
527-
* @throws CommandException Thrown if there is a problem encoding the query string parameter names or values
517+
* @return The URI with parameters added
518+
* @throws CommandException Thrown if there is a problem building the URI
528519
*/
529-
protected String getQueryString() throws CommandException
520+
protected URI addParameters(URI uri) throws CommandException, URISyntaxException
530521
{
531522
Map<String, Object> params = getParameters();
532523

533524
//add the required version if it's > 0
534525
if (getRequiredVersion() > 0)
535526
params.put(CommonParameters.apiVersion.name(), getRequiredVersion());
536527

537-
StringBuilder qstring = new StringBuilder();
538-
URLCodec urlCodec = new URLCodec();
539-
try
528+
if (params.isEmpty())
529+
return uri;
530+
531+
URIBuilder builder = new URIBuilder(uri);
532+
533+
for (String name : params.keySet())
540534
{
541-
for (String name : params.keySet())
535+
Object value = params.get(name);
536+
if (value instanceof Collection<?> col)
542537
{
543-
Object value = params.get(name);
544-
if (value instanceof Collection)
538+
for (Object o : col)
545539
{
546-
for (Object o : ((Collection) value))
547-
{
548-
appendParameter(qstring, urlCodec, name, o);
549-
}
550-
}
551-
else
552-
{
553-
appendParameter(qstring, urlCodec, name, value);
540+
addParameter(builder, name, o);
554541
}
555542
}
543+
else
544+
{
545+
addParameter(builder, name, value);
546+
}
547+
}
548+
549+
try
550+
{
551+
return builder.build();
556552
}
557-
catch(EncoderException e)
553+
catch (URISyntaxException e)
558554
{
559555
throw new CommandException(e.getMessage());
560556
}
561-
562-
return qstring.length() > 0 ? qstring.toString() : null;
563557
}
564558

565-
private void appendParameter(StringBuilder qstring, URLCodec urlCodec, String name, Object value)
566-
throws EncoderException
559+
private void addParameter(URIBuilder builder, String name, Object value)
567560
{
568561
String strValue = null == value ? null : getParamValueAsString(value, name);
569-
if(null != strValue)
570-
{
571-
if (qstring.length() > 0)
572-
qstring.append('&');
573-
qstring.append(urlCodec.encode(name));
574-
qstring.append('=');
575-
qstring.append(urlCodec.encode(strValue));
576-
}
562+
if (null != strValue)
563+
builder.addParameter(name, strValue);
577564
}
578565

579566
/**

labkey-client-api/src/org/labkey/remoteapi/CommandException.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package org.labkey.remoteapi;
1717

18-
import org.apache.http.impl.EnglishReasonPhraseCatalog;
18+
import org.apache.hc.core5.http.impl.EnglishReasonPhraseCatalog;
1919

2020
import java.util.Locale;
2121
import java.util.Map;
@@ -51,18 +51,6 @@ public CommandException(String message)
5151
this(message, 0, null, null, null);
5252
}
5353

54-
/**
55-
* @param message The message text (should not be null).
56-
* @param statusCode The HTTP status code.
57-
* @param properties The exception property map (may be null)
58-
* @param responseText The full response text (may be null)
59-
* @deprecated Use {@link #CommandException(String, int, Map, String, String)}
60-
*/
61-
public CommandException(String message, int statusCode, Map<String, Object> properties, String responseText)
62-
{
63-
this(message, statusCode, properties, responseText, null);
64-
}
65-
6654
/**
6755
* Constructs a new CommandException given a message, HTTP status code,
6856
* exception property map, responseText, and contentType.

0 commit comments

Comments
 (0)