Enable setting of a custom HTTP client for HTTPRequest.send

Issue #434 resolved
Paolo Selvini created an issue

The current com.nimbusds.oauth2.sdk.http.HTTPRequest does not allow to implement retry strategies to apply when sending requests. It would be nice and useful to allow setting a custom HTTPClient instance initialized with such behavior.

Comments (15)

  1. Yavor Vasilev

    Implemented here: cbbb0af5

    Released in:

    version 11.0 (2023-09-20)
        * Breaking change: HTTPRequest.getURL and getURI returns a modified URL if
          setQuery(String), appendQueryString(String),
          appendQueryParameters(Map<String, List<String>) or setFragment(String)
          is called.
        * Adds HTTPRequestSender interface for implementing custom HTTPRequest
          dispatching via a new HTTPRequest.send(HTTPRequestSender) method.
        * Adds ReadOnlyHTTPMessage, ReadOnlyHTTPRequest and ReadOnlyHTTPResponse
          interfaces for the new HTTPRequestSender.
        * Adds HTTPRequest.appendQueryString(String) and
          appendQueryParameters(Map<String, List<String>) methods.
        * Adds HTTPMessage.getBody() and setBody(String) methods.
        * Adds HTTPMessage.getBodyAsFormParameters(), getBodyAsJSONObject(),
          getBodyAsJSONArray() and getBodyAsJWT() helper methods.
        * Deprecates HTTPRequest.getQuery() and setQuery(String). Use
          HTTPRequest.getURL().getQuery() and appendQueryString(String) instead.
        * Deprecates HTTPResponse.getContent(), getContentAsJSONObject.(),
          getContentAsJSONArray(), getContentAsJWT() and setContent(String).
        * Adds URLUtils.setEncodedQuery(String) and setEncodedFragment(String)
          methods.
        * URLUtils.parseParameters(String) switches to LinkedHashMap.
        * The TokenIntrospectionRequest.parse must use only the form parameters
          found in the request body, URL query string parameters must be ignored
          (iss #432).
        * Switches LogoutRequest.toHTTPRequest() from HTTP GET to POST to prevent
          the optional id_token_hint parameter from getting exposed in access logs
          (iss #439).
    
  2. Paolo Selvini reporter

    Thanks a lot Yavor, much appreciated!

    There are just a couple of typos in the how-to:

    1. at the beginning, HTTPRequestSender myHttpClient =newApacheHttpClient(); should read HTTPRequestSender customClient =newApacheHttpClient();
    2. near the end of the sample code, httpResponse.setStatusMessage(statusLine.getReasonPhrase( should read httpResponse.setStatusMessage(statusLine.getReasonPhrase());

    Finally, checking for response.getEntity().getContentLength() > 0 may not always be a good idea, as that apparently relies on the Content-Length HTTP header, which could not be returned by the HTTP server, even if content is actually there.

  3. Vladimir Dzhuvinov

    Hi Paolo,

    Thanks for getting back with this feedback.

    What is the correct way to check whether an Entity Body is present with an ApacheHttpClient?

  4. Paolo Selvini reporter

    Hello Vladimir,

    I usually simply check if response.getEntity() is null or not. However, the entity could be non-null and yet empty. so the org.apache.http.util.EntityUtils.toString() method could come in handy. It takes a (non-null) entity and returns a string: if the resulting string is empty then the entity body is empty.

    I don’t know if this is the best or most correct method, but it generally works…

  5. Paolo Selvini reporter

    Hello again,

    about the TrustChainResolver, I see that there’s already the possibility to pass a custom EntityStatementRetriever, but I guess it’s not the same approach as the new HTTPRequestSender interface realized for this issue. Do you have any hint about how to use a custom HTTP Client for that as well?

  6. Yavor Vasilev

    The HTTP client example was fixed, thanks for your input.

    We’ll try to check out the trust chain resolver HTTP handling next week.

  7. Paolo Selvini reporter

    Good! But there would also be that other minor fix in the initial code fragment at the top of the same page where you first define “myHttpClient” and then use “customClient” right below it.

  8. Yavor Vasilev
  9. Log in to comment