Standalone Play WS, an async HTTP client with fluent API

Overview

Build Status Maven Javadocs

Play WS Standalone

Play WS is a powerful HTTP Client library, originally developed by the Play team for use with Play Framework. It uses AsyncHttpClient for HTTP client functionality and has no Play dependencies.

We've provided some documentation here on how to use Play WS in your app (without Play). For more information on how to use Play WS in Play, please refer to the Play documentation.

Getting Started

To get started, you can add play-ahc-ws-standalone as a dependency in SBT:

libraryDependencies += "com.typesafe.play" %% "play-ahc-ws-standalone" % "LATEST_VERSION"

Where you replace LATEST_VERSION with the version shown in this image: Latest released version.

This adds the standalone version of Play WS, backed by AsyncHttpClient. This library contains both the Scala and Java APIs, under play.api.libs.ws and play.libs.ws.

To add XML and JSON support using Play-JSON or Scala XML, add the following:

libraryDependencies += "com.typesafe.play" %% "play-ws-standalone-xml" % playWsStandaloneVersion
libraryDependencies += "com.typesafe.play" %% "play-ws-standalone-json" % playWsStandaloneVersion

Shading

Play WS uses shaded versions of AsyncHttpClient and OAuth Signpost, repackaged under the play.shaded.ahc and play.shaded.oauth package names, respectively. Shading AsyncHttpClient means that the version of Netty used behind AsyncHttpClient is completely independent of the application and Play as a whole.

Specifically, shading AsyncHttpClient means that there are no version conflicts introduced between Netty 4.0 and Netty 4.1 using Play WS.

NOTE: If you are developing play-ws and publishing shaded-asynchttpclient and shaded-oauth using sbt publishLocal, you need to be aware that updating ~/.ivy2/local does not overwrite ~/.ivy2/cache and so you will not see your updated shaded code until you remove it from cache. See http://eed3si9n.com/field-test for more details. This bug has been filed as https://github.com/sbt/sbt/issues/2687.

Shaded AHC Defaults

Because Play WS shades AsyncHttpClient, the default settings are also shaded and so do not adhere to the AHC documentation. This means that the settings in ahc-default.properties and the AsyncHttpClient system properties are prepended with play.shaded.ahc, for example the usePooledMemory setting in the shaded version of AsyncHttpClient is defined like this:

play.shaded.ahc.org.asynchttpclient.usePooledMemory=true

Typed Bodies

The type system in Play-WS has changed so that the request body and the response body can use richer types.

You can define your own BodyWritable or BodyReadable, but if you want to use the default out of the box settings, you can import the type mappings with the DefaultBodyReadables / DefaultBodyWritables.

Scala

import play.api.libs.ws.DefaultBodyReadables._
import play.api.libs.ws.DefaultBodyWritables._

More likely you will want the XML and JSON support:

import play.api.libs.ws.XMLBodyReadables._
import play.api.libs.ws.XMLBodyWritables._

or

import play.api.libs.ws.JsonBodyReadables._
import play.api.libs.ws.JsonBodyWritables._

To use a BodyReadable in a response, you must type the response explicitly:

import scala.concurrent.{ ExecutionContext, Future }

import play.api.libs.ws.StandaloneWSClient
import play.api.libs.ws.XMLBodyReadables._ // required

def handleXml(ws: StandaloneWSClient)(
  implicit ec: ExecutionContext): Future[scala.xml.Elem] =
  ws.url("...").get().map { response =>
    response.body[scala.xml.Elem]
  }

or using Play-JSON:

import scala.concurrent.{ ExecutionContext, Future }

import play.api.libs.json.JsValue
import play.api.libs.ws.StandaloneWSClient

import play.api.libs.ws.JsonBodyReadables._ // required

def handleJsonResp(ws: StandaloneWSClient)(
  implicit ec: ExecutionContext): Future[JsValue] =
  ws.url("...").get().map { response =>
    response.body[JsValue]
  }

Note that there is a special case: when you are streaming the response, then you should get the body as a Source:

import scala.concurrent.ExecutionContext
import akka.util.ByteString
import akka.stream.scaladsl.Source
import play.api.libs.ws.StandaloneWSClient

def useWSStream(ws: StandaloneWSClient)(implicit ec: ExecutionContext) =
  ws.url("...").stream().map { response =>
     val source: Source[ByteString, _] = response.bodyAsSource
     val _ = source // do something with source
  }

To POST, you should pass in a type which has an implicit class mapping of BodyWritable:

import scala.concurrent.ExecutionContext
import play.api.libs.ws.DefaultBodyWritables._ // required

def postExampleString(ws: play.api.libs.ws.StandaloneWSClient)(
  implicit ec: ExecutionContext) = {
  val stringData = "Hello world"
  ws.url("...").post(stringData).map { response => /* do something */ }
}

You can also define your own custom BodyReadable:

import play.api.libs.ws.BodyReadable
import play.api.libs.ws.ahc.StandaloneAhcWSResponse

case class Foo(body: String)

implicit val fooBodyReadable = BodyReadable[Foo] { response =>
  import play.shaded.ahc.org.asynchttpclient.{ Response => AHCResponse }
  val ahcResponse = response.asInstanceOf[StandaloneAhcWSResponse].underlying[AHCResponse]
  Foo(ahcResponse.getResponseBody)
}

or custom BodyWritable:

import akka.util.ByteString
import play.api.libs.ws.{ BodyWritable, InMemoryBody }

implicit val writeableOf_Foo: BodyWritable[Foo] = {
  // https://tools.ietf.org/html/rfc6838#section-3.2
  BodyWritable(foo => InMemoryBody(ByteString.fromString(foo.toString)), "application/vnd.company.category+foo")
}

Java

To use the default type mappings in Java, you should use the following:

import play.libs.ws.DefaultBodyReadables;
import play.libs.ws.DefaultBodyWritables;

followed by:

public class MyClient implements DefaultBodyWritables, DefaultBodyReadables {    
    public CompletionStage<String> doStuff() {
      return client.url("http://example.com").post(body("hello world")).thenApply(response ->
        response.body(string())
      );
    }
}

Note that there is a special case: when you are using a stream, then you should get the body as a Source:

class MyClass {
    public CompletionStage<Source<ByteString, NotUsed>> readResponseAsStream() {
        return ws.url(url).stream().thenApply(response ->
            response.bodyAsSource()
        );
    }
}

You can also post a Source:

class MyClass {
    public CompletionStage<String> doStuff() {
        Source<ByteString, NotUsed> source = fromSource();
        return ws.url(url).post(body(source)).thenApply(response ->
            response.body()
        );
    }
}

You can define a custom BodyReadable:

import play.libs.ws.ahc.*;
import play.shaded.ahc.org.asynchttpclient.Response;

class FooReadable implements BodyReadable<StandaloneWSResponse, Foo> {
    public Foo apply(StandaloneWSResponse response) {
        Response ahcResponse = (Response) response.getUnderlying();
        return Foo.serialize(ahcResponse.getResponseBody(StandardCharsets.UTF_8));
    }
}

You can also define your own custom BodyWritable:

public class MyClient {
    private BodyWritable<String> someOtherMethod(String string) {
      akka.util.ByteString byteString = akka.util.ByteString.fromString(string);
      return new DefaultBodyWritables.InMemoryBodyWritable(byteString, "text/plain");
    }
}

Instantiating a standalone client

The standalone client needs Akka to handle streaming data internally:

Scala

In Scala, the way to call out to a web service and close down the client:

package playwsclient

import akka.actor.ActorSystem
import akka.stream._
import play.api.libs.ws._
import play.api.libs.ws.ahc._

import scala.concurrent.Future

object ScalaClient {
  import DefaultBodyReadables._
  import scala.concurrent.ExecutionContext.Implicits._

  def main(args: Array[String]): Unit = {
    // Create Akka system for thread and streaming management
    implicit val system = ActorSystem()
    system.registerOnTermination {
      System.exit(0)
    }

    implicit val materializer = SystemMaterializer(system).materializer

    // Create the standalone WS client
    // no argument defaults to a AhcWSClientConfig created from
    // "AhcWSClientConfigFactory.forConfig(ConfigFactory.load, this.getClass.getClassLoader)"
    val wsClient = StandaloneAhcWSClient()

    call(wsClient)
      .andThen { case _ => wsClient.close() }
      .andThen { case _ => system.terminate() }
  }

  def call(wsClient: StandaloneWSClient): Future[Unit] = {
    wsClient.url("http://www.google.com").get().map { response =>
      val statusText: String = response.statusText
      val body = response.body[String]
      println(s"Got a response $statusText: $body")
    }
  }
}

You can also create the standalone client directly from an AsyncHttpClient instance:

object ScalaClient {
  def main(args: Array[String]): Unit = {
    // Use 
    import play.shaded.ahc.org.asynchttpclient._
    val asyncHttpClientConfig = new DefaultAsyncHttpClientConfig.Builder()
      .setMaxRequestRetry(0)
      .setShutdownQuietPeriod(0)
      .setShutdownTimeout(0).build
    val asyncHttpClient = new DefaultAsyncHttpClient(asyncHttpClientConfig)
    val wsClient = new StandaloneAhcWSClient(asyncHttpClient)
    /// ...
  }
}

This is useful when there is an AsyncHttpClient configuration option that is not available in the WS config layer.

Java

In Java the API is much the same:

package playwsclient;

import akka.actor.ActorSystem;
import akka.stream.*;
import com.typesafe.config.ConfigFactory;

import play.libs.ws.*;
import play.libs.ws.ahc.*;

public class JavaClient implements DefaultBodyReadables {
    private final StandaloneAhcWSClient client;
    private final ActorSystem system;

    public static void main(String[] args) {
        // Set up Akka materializer to handle streaming
        final String name = "wsclient";
        ActorSystem system = ActorSystem.create(name);
        system.registerOnTermination(() -> System.exit(0));
        Materializer materializer = SystemMaterializer.get(system).materializer();

        // Create the WS client from the `application.conf` file, the current classloader and materializer.
        StandaloneAhcWSClient ws = StandaloneAhcWSClient.create(
                AhcWSClientConfigFactory.forConfig(ConfigFactory.load(), system.getClass().getClassLoader()),
                materializer
        );

        JavaClient javaClient = new JavaClient(system, ws);
        javaClient.run();
    }

    JavaClient(ActorSystem system, StandaloneAhcWSClient client) {
        this.system = system;
        this.client = client;
    }

    public void run() {
        client.url("http://www.google.com").get()
                .whenComplete((response, throwable) -> {
                    String statusText = response.getStatusText();
                    String body = response.getBody(string());
                    System.out.println("Got a response " + statusText);
                })
                .thenRun(() -> {
                    try {
                        client.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                })
                .thenRun(system::terminate);
    }
}

Likewise, you can provide the AsyncHttpClient client explicitly from configuration:

public class JavaClient implements DefaultBodyReadables {
     public static void main(String[] args) { 
        // ...
        // Set up AsyncHttpClient directly from config
        AsyncHttpClientConfig asyncHttpClientConfig =
            new DefaultAsyncHttpClientConfig.Builder()
                .setMaxRequestRetry(0)
                .setShutdownQuietPeriod(0)
                .setShutdownTimeout(0)
                .build();
        AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient(asyncHttpClientConfig);
    
        // Set up WSClient instance directly from asynchttpclient.
        WSClient client = new AhcWSClient(asyncHttpClient, materializer);
        // ...
    }
}

Caching

Play WS implements HTTP Caching through CachingAsyncHttpClient, AhcHTTPCache and CacheControl, a minimal HTTP cache management library in Scala.

To create a standalone AHC client that uses caching, pass in an instance of AhcHttpCache with a cache adapter to the underlying implementation. For example, to use Caffeine as the underlying cache, you could use the following:

import scala.concurrent.Future
import java.util.concurrent.TimeUnit
import com.github.benmanes.caffeine.cache.{ Caffeine, Ticker }

import play.api.libs.ws.ahc.StandaloneAhcWSClient
import play.api.libs.ws.ahc.cache.{
  AhcHttpCache, Cache, EffectiveURIKey, ResponseEntry
}

class CaffeineHttpCache extends Cache {
  val underlying = Caffeine.newBuilder()
    .ticker(Ticker.systemTicker())
    .expireAfterWrite(365, TimeUnit.DAYS)
    .build[EffectiveURIKey, ResponseEntry]()

  def remove(key: EffectiveURIKey) =
    Future.successful(Option(underlying.invalidate(key)))

  def put(key: EffectiveURIKey, entry: ResponseEntry) =
    Future.successful(underlying.put(key, entry))

  def get(key: EffectiveURIKey) =
    Future.successful(Option(underlying getIfPresent key ))

  def close(): Unit = underlying.cleanUp()
}

def withCache(implicit m: akka.stream.Materializer): StandaloneAhcWSClient = {
  implicit def ec = m.executionContext

  val cache = new CaffeineHttpCache()
  StandaloneAhcWSClient(httpCache = Some(new AhcHttpCache(cache)))
}

There are a number of guides that help with putting together Cache-Control headers:

License

Play WS is licensed under the Apache license, version 2. See the LICENSE file for more information.

Comments
  • [fix] don't use AHC cookie store

    [fix] don't use AHC cookie store

    The WSRequest withCookies method suggests all cookies will be discarded. This is not the case if the underlying http client has a cookie store. Play ws also does not know about those cookies so for example the AhcCurlRequestLogger does not log these cookies.

    opened by bomgar 16
  • Add withUrl(String)

    Add withUrl(String)

    Pull Request Checklist

    • [x] Have you read through the contributor guidelines?
    • [x] Have you signed the Typesafe CLA?
    • [x] Have you squashed your commits?
    • [x] Have you added copyright headers to new files?
    • [x] Have you checked that both Scala and Java APIs are updated? (see below)
    • [x] Have you updated the documentation for both Scala and Java sections?
    • [x] Have you added tests for any changed functionality?

    Fixes

    Fixes #264

    Purpose

    Adds support in the scala API for changing the url of the WSRequest.

    Background Context

    Like @gmethvin, I've encountered a couple use cases where I'd like to modify the URL of an existing WSRequest.

    1. Fixing URIs In my WSRequestFilters, I'd like to make use of WSRequest.uri, but it's unsafe (see #267). Today, I have a WSRequestFilter to sanitize the entire request prior to subsequent WSRequestFilters touching WSRequest.uri. In order to strip out query params and any other garbage from the URL, my WSRequestFilter has to rebuild the whole request from scratch. Additionally, it has to require a WSClient to do the job (wsClient.url()), which I hope is the same WSClient that originally used to build the request. Ugh!

    2. Changing hostnames We're cursed with https://github.com/mesosphere/marathon-lb, which sometimes fails to route requests. I'd love to be able to have a WSRequestFilter I can use to bypass that layer and rewrite https://pray-marathon-lb-works.example.com/foo to https://10.0.0.25/foo.

    opened by htmldoug 16
  • ssl-config-core 0.6.0 (was 0.4.3) + cachecontrol 2.1.0

    ssl-config-core 0.6.0 (was 0.4.3) + cachecontrol 2.1.0

    Updates com.typesafe:ssl-config-core from 0.4.3 to 0.5.0. GitHub Release Notes - Version Diff

    I'll automatically update this PR to resolve conflicts as long as you don't change it yourself.

    If you'd like to skip this version, you can just close this PR. If you have any feedback, just mention me in the comments below.

    Configure Scala Steward for your repository with a .scala-steward.conf file.

    Have a fantastic day writing Scala!

    Files still referring to the old version number

    The following files still refer to the old version number (0.4.3). You might want to review and update them manually.

    project/plugins.sbt
    
    Ignore future updates

    Add this to your .scala-steward.conf file to ignore future updates of this dependency:

    updates.ignore = [ { groupId = "com.typesafe", artifactId = "ssl-config-core" } ]
    

    labels: library-update, semver-minor, old-version-remains

    opened by scala-steward 15
  • add new AHC parameter: connectionPoolCleanerPeriod

    add new AHC parameter: connectionPoolCleanerPeriod

    Pull Request Checklist

    • [x] Have you read through the contributor guidelines?
    • [x] Have you signed the Typesafe CLA?
    • [x] Have you squashed your commits?
    • [x] Have you added copyright headers to new files?
    • [x] Have you checked that both Scala and Java APIs are updated?
    • [x] Have you updated the documentation for both Scala and Java sections?
    • [x] Have you added tests for any changed functionality?

    Purpose

    add new AHC parameter: connectionPoolCleanerPeriod

    Background Context

    Sometimes we need to populate idleConnectionInPoolTimeout together with connectionPoolCleanerPeriod

    References

    Are there any relevant issues / PRs / mailing lists discussions?

    opened by maxcellent 13
  • Make the client mockable with Java mocking frameworks

    Make the client mockable with Java mocking frameworks

    Play WS Version (2.5.x / etc)

    1.0.0-M8

    API (Scala / Java / Neither / Both)

    Scala

    Expected Behavior

    It should be able to mock the client with Java mocking libraries like mockito, EasyMock or JMock.

    Actual Behavior

    The following code doesn't compile:

    val wsRequest = mock[WSRequest]
    val wsResponse = mock[WSResponse]
    
    wsResponse.json throws new RuntimeException("Unexpected character ('<' (code 60))")
    wsResponse.body returns "<html></html>"
    wsRequest.withHeaders(any) returns wsRequest
    wsRequest.post[Map[String, Seq[String]]](any)(any) returns Future.successful(wsResponse)
    
    /home/travis/build/mohiva/play-silhouette/silhouette/test/com/mohiva/play/silhouette/impl/providers/OAuth2ProviderSpec.scala:274: type mismatch;
    [error]  found   : this.wsRequest.type (with underlying type play.api.libs.ws.WSRequest)
    [error]  required: this.wsRequest.Self
    [error]       wsRequest.withHeaders(any) returns wsRequest
    
    /home/travis/build/mohiva/play-silhouette/silhouette/test/com/mohiva/play/silhouette/impl/providers/OAuth2ProviderSpec.scala:275: type mismatch;
    [error]  found   : this.wsResponse.type (with underlying type play.api.libs.ws.WSResponse)
    [error]  required: this.wsRequest.Response
    [error]       wsRequest.post[Map[String, Seq[String]]](any)(any) returns Future.successful(wsResponse)
    

    Reproducible Test Case

    https://github.com/mohiva/play-silhouette/pull/509

    Links

    https://groups.google.com/forum/#!topic/play-framework/mYPRPbfa8Uk

    Notes

    Both Scala testing libraries support mocking with Java mocking frameworks. ScalaTest supports one Scala and three Java mocking frameworks. Specs2 provides syntactic sugar for mockito. This shows that using Java mocking frameworks in the Scala world is a preferred method.

    Switching to play-mockws as suggested by @wsargent , isn't a good solution for a play related library, because then the library is bound to the release cycle of that play related dependency.

    opened by akkie 13
  • MEGA ticket for Akka Http backend related tickets

    MEGA ticket for Akka Http backend related tickets

    Work-in-progress branch and PR can be found here: https://github.com/playframework/play-ws/pull/205

    List of topics that are currently missing:

    • [ ] #213 configuration
    • [ ] #214 proxy support when using HTTP https://github.com/akka/akka-http/issues/115
    • [ ] #215 follow redirects https://github.com/akka/akka-http/issues/195
    • [ ] #216 proper request timeout support. Now it is implemented using future timeouts. https://github.com/akka/akka-http/issues/42
    • [ ] #217 caching support
    • [ ] #218 signature calculator support
    • [ ] authentication
      • [x] BASIC
      • [ ] #219 DIGEST
      • [ ] #220 NTLM
      • [ ] #221 SPNEGO
      • [ ] #222 KERBEROS
    opened by 2m 12
  • WSRequest: Normalize URL

    WSRequest: Normalize URL

    Pull Request Checklist

    • [x] Have you read through the contributor guidelines?
    • [x] Have you signed the Typesafe CLA?
    • [x] Have you squashed your commits?
    • [x] Have you added copyright headers to new files?
    • [x] Have you checked that both Scala and Java APIs are updated?
    • [x] Have you updated the documentation for both Scala and Java sections?
    • [x] Have you added tests for any changed functionality?

    Fixes

    Fixes #267

    Purpose

    Ensure that StandaloneWSRequest.uri does not return invalid values or throw, by normalizing the url: String when a StandaloneWSRequest is constructed. Same approach is used by the java implementation.

    Background Context

    This approach follows the "tolerant" recommendation, https://github.com/playframework/play-ws/issues/267#issuecomment-419266583.

    Ensures:

    1. StandaloneWSRequest.url path is encoded.
    2. Any query params present in the URL are moved to StandaloneWSRequest.queryString.

    Implementation is based upon a WSRequestFilter-like decorator I've been using in production since June 2018. An advantage to fixing the request right away is that request.uri can be invoked safely sooner in the process.

    Caveats

    Normalization can still be bypassed by:

    • StandaloneAhcWSClient.copy(url = ">^..^<", ...)
    • new StandaloneAhcWSRequest(client, ">^..^<", ...)
    status:backlog 
    opened by htmldoug 11
  • Upgrade async-http-client to 2.4.4 to expose client connection stats

    Upgrade async-http-client to 2.4.4 to expose client connection stats

    Couldn't find a way to update branch name in the other PR, so had to create a new PR

    Pull Request Checklist

    • [Y] Have you read through the contributor guidelines?
    • [Y] Have you signed the Typesafe CLA?
    • [Y] Have you squashed your commits?
    • [N/A] Have you added copyright headers to new files?
    • [Y] Have you checked that both Scala and Java APIs are updated?
    • [Y] Have you updated the documentation for both Scala and Java sections?
    • [Y] Have you added tests for any changed functionality?

    Fixes

    Upgrade Async-Http-Client to 2.4.4

    Purpose

    Have access to connection stats through new class exposed from AsyncHttpClient

    Background Context

    One major change around Cookie specific codes from Async-Http-Client is moved to Netty and there are now 2 different decoders (STRICT and LAX) so that we had to make that configurable.

    References

    • https://discuss.lightbend.com/t/upgrade-async-http-client/752
    • CHANGES in the Async-Http-Client : https://github.com/AsyncHttpClient/async-http-client/blob/master/CHANGES.md

    Please refer to https://github.com/playframework/play-ws/pull/252 for previous comments

    opened by fatihi-sky 11
  • Exceptions when using together with AsyncHttpClient

    Exceptions when using together with AsyncHttpClient

    Sorry for cross-posting. I've written down the details of this issue at: https://github.com/playframework/playframework/issues/7056

    It looks like (at least in my Play 2.6.0-M1 app) that the shaded AsyncHttpClientDefaults class reads the ahc-default.properties that are pulled in from the non-shaded version on my classpath.

    The issue probably comes from https://github.com/AsyncHttpClient/async-http-client/blob/async-http-client-project-2.0.27/client/src/main/java/org/asynchttpclient/config/AsyncHttpClientConfigHelper.java#L47

    Where the current ThreadContext Classloader is used to lookup the properties instead a classloader based on the current class (which would then find the ahc-default.properties with the play.shaded prefix.

    opened by domdorn 11
  • Add Scala 3 support

    Add Scala 3 support

    would a volunteer like to attempt this? it would be helpful even just to have a failing draft PR that shows where the next roadblock is, and then we could chip away it from there

    I published ssl-config and cachecontrol today for Scala 3, so that helps

    #590 should be merged before any attempt is made at this

    opened by SethTisue 10
  • fix: make query param order deterministic when adding params

    fix: make query param order deterministic when adding params

    Pull Request Checklist

    • [x] Have you read through the contributor guidelines?
    • [x] Have you signed the Typesafe CLA?
    • [x] Have you squashed your commits?
    • [ ] Have you added copyright headers to new files?
    • [ ] Have you checked that both Scala and Java APIs are updated?
    • [ ] Have you updated the documentation for both Scala and Java sections?
    • [x] Have you added tests for any changed functionality?

    Fixes

    Fixes #48

    Purpose

    Ensure deterministic query param order when adding params through the WSRequest interface. This does not address order when adding to a query param that already contains a value. for example

    req.addQueryParam("p1", "v1")
    req.addQueryParam("p2", "v2")
    req.addQueryParam("p1, "v3")
    

    will yield p1=v1&p1=v3&p2=v2 which is still not perfect but is at least deterministic

    Background Context

    I wanted to make the minimal code change to achieve deterministic behaviour. When generating digital signatures of urls (for example of an Authorization header) it's important to have a deterministic order to be able to correctly compute the digest.

    References

    https://github.com/playframework/playframework/pull/6884 https://github.com/playframework/play-ws/pull/102

    opened by bpossolo 10
  • Got

    Got "Digest algorithm not supported: md5" on try use DIGEST

    As I understand it, when calling the ws.url().withAuth(username, password, WSAuthScheme.DIGEST) function, the MD5 encryption algorithm is selected by default, but it is not supported and I get an error. How can I force DIGEST to use SHA or allow configuration to use MD5?

    The project uses:

    scala - 2.13.8
    play  - 2.8.16
    jvm   - openjdk 11.0.16.1 2022-08-12 LTS
    

    **UPD error log

    [debug] p.s.a.o.a.n.r.NettyRequestSender - Digest algorithm not supported: md5
    java.lang.UnsupportedOperationException: Digest algorithm not supported: md5
    at play.shaded.ahc.org.asynchttpclient.Realm$Builder.ha1(Realm.java:504)
    at play.shaded.ahc.org.asynchttpclient.Realm$Builder.newResponse(Realm.java:542)
    at play.shaded.ahc.org.asynchttpclient.Realm$Builder.build(Realm.java:565)
    at play.shaded.ahc.org.asynchttpclient.netty.handler.intercept.Unauthorized401Interceptor.exitAfterHandling401(Unauthorized401Interceptor.java:117)
    at play.shaded.ahc.org.asynchttpclient.netty.handler.intercept.Interceptors.exitAfterIntercept(Interceptors.java:89)
    at play.shaded.ahc.org.asynchttpclient.netty.handler.HttpHandler.handleHttpResponse(HttpHandler.java:78)
    at play.shaded.ahc.org.asynchttpclient.netty.handler.HttpHandler.handleRead(HttpHandler.java:140)
    at play.shaded.ahc.org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelRead(AsyncHttpClientHandler.java:78)
    at play.shaded.ahc.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at play.shaded.ahc.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    [debug] p.s.a.o.a.n.c.ChannelManager - Closing Channel [**secure ip]
    [debug] p.s.a.o.a.n.h.HttpHandler - Unexpected I/O exception on channel [id: 0x27d4ea64, **secure ip ! **secure ip]
    
    opened by mprosvitlyk 0
  • [feature] Add support for `SameSite` attribute in `WSCookie`

    [feature] Add support for `SameSite` attribute in `WSCookie`

    The SameSite cookie attribute is widespread, see e.g. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite#browser_compatibility.

    It would be great if play-ws helped me consume SameSite attributes, e.g. by having a sameSite field on WSCookie.

    opened by jonaskoelker-jypo 0
  • Null pointer error in `play.api.libs.ws.ahc.CookieBuilder` if cookie has no value

    Null pointer error in `play.api.libs.ws.ahc.CookieBuilder` if cookie has no value

    In my app I construct a WSRequest and call .stream() on it (this is the Scala API). It's talking to an in-house service, which responds with a Set-Cookie header with a cookie name but no cookie value. In my repro setup I use a mock response with a line saying Set-Cookie: absent-value;. In both cases I get a null pointer exception.

    I tracked it down:

    • When I touch the cookies I hit this: https://github.com/playframework/play-ws/blob/d06f8b15b2564384c0754711b8cb2dbb384311f0/play-ahc-ws-standalone/src/main/scala/play/api/libs/ws/ahc/StreamedResponse.scala#L56
    • This in turns goes here: https://github.com/playframework/play-ws/blob/d06f8b15b2564384c0754711b8cb2dbb384311f0/play-ahc-ws-standalone/src/main/scala/play/api/libs/ws/ahc/CookieBuilder.scala#L21
    • Since the cookie value is absent, the underlying cookie builder returns null
    • Then Some(c) = Some(null) acts just like c = null (in the cookie builder)
    • Then asCookie(null) is called, which tries to access (null).name which throws the null pointer exception.

    I believe Some(c) = Option(<the same expression as before>) will make the null pointer exception not happen, but it's not obvious to me that this is the right design.

    It's just what I did as a workaround: I made a wrapper around WSRepsonse which forwards everything to the underlying response, except it diverts the code path leading to this buggy line onto a copy-pasted-and-the-fixed version which says Option instead of Some on this line—plus some incidental and (I believe) unrelated changes.

    I'm not sure what behavior to expect, given that value-free cookie headers do not conform to any HTTP standard I could find—not that I looked all day—but I definitely don't expect a null pointer exception.

    Here's sbt dependencyTree | grep ws | grep -v aws | cut -f2- -d'-' | sort -u, just in case it helps. My above links are to the most recent version of each of the linked files, as far as I can find out; they look like differently indented versions of the source my LSP/metals setup jumps to.

    com.typesafe.play:play-ahc-ws-standalone_2.13:2.1.7 [S]
    com.typesafe.play:play-ahc-ws_2.13:2.8.11 (evicted by: 2.8.13)
    com.typesafe.play:play-ahc-ws_2.13:2.8.13 [S]
    com.typesafe.play:play-ws-standalone-json_2.13:2.1.7 [S]
    com.typesafe.play:play-ws-standalone-xml_2.13:2.1.7 [S]
    com.typesafe.play:play-ws-standalone_2.13:2.1.7 [S]
    com.typesafe.play:play-ws_2.13:2.8.13 [S]
    

    API: Scala. We also have a bit of java stuff lying around but I don't think it interacts with this bug.

    OS/Java:

    $ uname -a
    Linux <hostname_withheld> 5.4.0-122-generic #138-Ubuntu SMP Wed Jun 22 15:00:31 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
    
    $ java -version
    openjdk version "11.0.16" 2022-07-19
    OpenJDK Runtime Environment (build 11.0.16+8-post-Ubuntu-0ubuntu120.04)
    OpenJDK 64-Bit Server VM (build 11.0.16+8-post-Ubuntu-0ubuntu120.04, mixed mode, sharing)
    
    opened by jonaskoelker-jypo 0
  • Source code for shaded jars are not properly published along with the shaded jars

    Source code for shaded jars are not properly published along with the shaded jars

    The problem is when attaching debugger with a running process using any shaded library. The non-shaded source code won't bind with the shaded classes that belong to the shaded packages such as

    package play.shaded.ahc.io.netty.channel.nio;
    ...
    public abstract class AbstractNioChannel extends AbstractChannel {
    

    The source code is still 266 bytes, see, https://repo1.maven.org/maven2/com/typesafe/play/shaded-asynchttpclient/2.1.3/

    So any plan to correctly publish shaded sources?

    A workaround in case someone needs it

    $ cd netty
    $ mkdir -p transport/src/main/java/play/shaded/ahc
    $ cp -a transport/src/main/java/io transport/src/main/java/play/shaded/ahc/.
    $ find transport/src/main/java/play/shaded/ahc -name "*.java" -exec sed -i 's#package io\.#package play.shaded.ahc.io.#' {} \; -exec sed -i 's#import io\.#import play.shaded.ahc.io.#' {} \; -exec sed -i 's#import static io\.#import static play.shaded.ahc.io.#' {} \;
    

    Originally posted by @jhooda in https://github.com/playframework/play-ws/issues/85#issuecomment-1130406025

    opened by jhooda 0
  • IOException Connection closed after many requests

    IOException Connection closed after many requests

    Hello! We are using play ws to execute requests on a highly loaded system. After running the system for about 30 - 40 minutes, we get an IOException Connection closed error and all further requests stop being executed until the system is restarted. Perhaps you know this problem and you tell me what we are doing wrong?

    We use - Scala version: 2.11.6 Play version: 2.4.11 Akka version: 2.4.0 SBT version: 0.13.8

    Error stack trace -

    java.io.IOException: Closed
    	at com.ning.http.client.providers.netty.request.NettyRequestSender.sendRequest(NettyRequestSender.java:98) ~[com.ning.async-http-client-1.9.40.jar:na]
    	at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.execute(NettyAsyncHttpProvider.java:87) ~[com.ning.async-http-client-1.9.40.jar:na]
    	at com.ning.http.client.AsyncHttpClient.executeRequest(AsyncHttpClient.java:506) ~[com.ning.async-http-client-1.9.40.jar:na]
    	at play.api.libs.ws.ning.NingWSClient.executeRequest(NingWS.scala:47) ~[com.typesafe.play.play-ws_2.11-2.4.11.jar:2.4.11]
    	at play.api.libs.ws.ning.NingWSRequest.execute(NingWS.scala:312) ~[com.typesafe.play.play-ws_2.11-2.4.11.jar:2.4.11]
    	at play.api.libs.ws.ning.NingWSRequest.execute(NingWS.scala:128) ~[com.typesafe.play.play-ws_2.11-2.4.11.jar:2.4.11]
    	at play.api.libs.ws.WSRequest$class.post(WS.scala:455) ~[com.typesafe.play.play-ws_2.11-2.4.11.jar:2.4.11]
    	at play.api.libs.ws.ning.NingWSRequest.post(NingWS.scala:81) ~[com.typesafe.play.play-ws_2.11-2.4.11.jar:2.4.11]
    	at ru.alfatell.webregistry.XmlExecutionContext$WebExecutor.callInternal(XmlExecutor.scala:338) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at ru.alfatell.webregistry.XmlExecutor$class.call(XmlExecutor.scala:199) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at ru.alfatell.webregistry.XmlExecutor$class.perform(XmlExecutor.scala:119) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at ru.alfatell.webregistry.XmlExecutionContext$WebExecutor.perform(XmlExecutor.scala:287) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at ru.alfatell.webregistry.ExternalApiGateway$$anonfun$execute$1$$anonfun$apply$12.apply(ExternalApiGateway.scala:111) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at ru.alfatell.webregistry.ExternalApiGateway$$anonfun$execute$1$$anonfun$apply$12.apply(ExternalApiGateway.scala:90) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at scala.util.Try$.apply(Try.scala:192) ~[org.scala-lang.scala-library-2.11.8.jar:na]
    	at ru.alfatell.webregistry.ExternalApiGateway$$anonfun$execute$1.apply(ExternalApiGateway.scala:90) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at ru.alfatell.webregistry.ExternalApiGateway$$anonfun$execute$1.apply(ExternalApiGateway.scala:89) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at scala.util.Success.flatMap(Try.scala:231) ~[org.scala-lang.scala-library-2.11.8.jar:na]
    	at ru.alfatell.webregistry.ExternalApiGateway$.execute(ExternalApiGateway.scala:89) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at controllers.tmp.ExtApiMain$$anonfun$xml$1$$anonfun$apply$1$$anonfun$4.apply(ExtApiMain.scala:24) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at controllers.tmp.ExtApiMain$$anonfun$xml$1$$anonfun$apply$1$$anonfun$4.apply(ExtApiMain.scala:24) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at controllers.tmp.ExtApiSecurity$class.callerAuthorize(ExtApiSecurity.scala:158) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at controllers.ExternalApi$.callerAuthorize(ExternalApi.scala:34) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at controllers.tmp.ExtApiMain$$anonfun$xml$1$$anonfun$apply$1.apply(ExtApiMain.scala:24) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at controllers.tmp.ExtApiMain$$anonfun$xml$1$$anonfun$apply$1.apply(ExtApiMain.scala:21) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at controllers.tmp.ExtApiSecurity$class.withCtx(ExtApiSecurity.scala:121) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at controllers.ExternalApi$.withCtx(ExternalApi.scala:34) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at controllers.tmp.ExtApiMain$$anonfun$xml$1.apply(ExtApiMain.scala:21) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at controllers.tmp.ExtApiMain$$anonfun$xml$1.apply(ExtApiMain.scala:20) ~[ru.alfatell.web-registry-portal-1.1.1-sans-externalized.jar:na]
    	at play.api.mvc.Action$.invokeBlock(Action.scala:533) ~[com.typesafe.play.play_2.11-2.4.11.jar:2.4.11]
    	at play.api.mvc.Action$.invokeBlock(Action.scala:530) ~[com.typesafe.play.play_2.11-2.4.11.jar:2.4.11]
    	at play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:493) ~[com.typesafe.play.play_2.11-2.4.11.jar:2.4.11]
    	at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:105) ~[com.typesafe.play.play_2.11-2.4.11.jar:2.4.11]
    	at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:105) ~[com.typesafe.play.play_2.11-2.4.11.jar:2.4.11]
    	at play.utils.Threads$.withContextClassLoader(Threads.scala:21) ~[com.typesafe.play.play_2.11-2.4.11.jar:2.4.11]
    	at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:104) ~[com.typesafe.play.play_2.11-2.4.11.jar:2.4.11]
    	at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:103) ~[com.typesafe.play.play_2.11-2.4.11.jar:2.4.11]
    	at scala.Option.map(Option.scala:146) ~[org.scala-lang.scala-library-2.11.8.jar:na]
    	at play.api.mvc.Action$$anonfun$apply$1.apply(Action.scala:103) ~[com.typesafe.play.play_2.11-2.4.11.jar:2.4.11]
    	at play.api.mvc.Action$$anonfun$apply$1.apply(Action.scala:96) ~[com.typesafe.play.play_2.11-2.4.11.jar:2.4.11]
    	at play.api.libs.iteratee.Iteratee$$anonfun$mapM$1.apply(Iteratee.scala:524) ~[com.typesafe.play.play-iteratees_2.11-2.4.11.jar:2.4.11]
    	at play.api.libs.iteratee.Iteratee$$anonfun$mapM$1.apply(Iteratee.scala:524) ~[com.typesafe.play.play-iteratees_2.11-2.4.11.jar:2.4.11]
    	at play.api.libs.iteratee.Iteratee$$anonfun$flatMapM$1.apply(Iteratee.scala:560) ~[com.typesafe.play.play-iteratees_2.11-2.4.11.jar:2.4.11]
    	at play.api.libs.iteratee.Iteratee$$anonfun$flatMapM$1.apply(Iteratee.scala:560) ~[com.typesafe.play.play-iteratees_2.11-2.4.11.jar:2.4.11]
    	at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$14.apply(Iteratee.scala:537) ~[com.typesafe.play.play-iteratees_2.11-2.4.11.jar:2.4.11]
    	at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$14.apply(Iteratee.scala:537) ~[com.typesafe.play.play-iteratees_2.11-2.4.11.jar:2.4.11]
    	at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) ~[org.scala-lang.scala-library-2.11.8.jar:na]
    	at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[org.scala-lang.scala-library-2.11.8.jar:na]
    	at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:39) [com.typesafe.akka.akka-actor_2.11-2.4.0.jar:na]
    	at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:399) [com.typesafe.akka.akka-actor_2.11-2.4.0.jar:na]
    	at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [org.scala-lang.scala-library-2.11.8.jar:na]
    	at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [org.scala-lang.scala-library-2.11.8.jar:na]
    	at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [org.scala-lang.scala-library-2.11.8.jar:na]
    	at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [org.scala-lang.scala-library-2.11.8.jar:na]
    
    opened by pavlovaleksei 0
Releases(2.2.0-M2)
  • 2.2.0-M2(Sep 26, 2022)

    Milestone release, do not use in production!

    Comes with Scala 3 support, see pull requests below.

    Changes

    • #704 scala-xml 2.1.0 also for Scala 2.12 by @mkurz
    • #703 slf4j-api 2.0.1 (was 1.7.36) by @scala-steward
    • #700 logback-core 1.4.1 (was 1.2.11) by @scala-steward
    • #702 scala3-library 3.2.0 (was 3.1.3) by @scala-steward
    • #701 akka-stream 2.6.20 (was 2.6.19) by @scala-steward
    • #699 🔄 Synced file(s) with playframework/.github by @ihostage
    • #698 Removed Lightbend CLA from PR template by @BillyAutrey
    • #697 scalafmt-core 3.5.9 (was 3.5.8) by @scala-steward
    • #696 sbt 1.7 by @mkurz
    • #694 scalafmt-core 3.5.8 (was 3.5.2) by @scala-steward
    • #695 specs2-core, specs2-junit, ... 4.16.1 (was 4.13.3) by @scala-steward
    • #689 sbt-mima-plugin 1.1.0 (was 1.0.1) by @scala-steward
    • #693 scala3-library 3.1.3 (was 3.1.1) by @scala-steward
    • #692 reactive-streams 1.0.4 (was 1.0.3) by @scala-steward
    • #690 sbt-header 5.7.0 (was 5.6.5) by @scala-steward
    • #691 assertj-core 3.23.1 (was 3.22.0) by @scala-steward
    • #688 Use scala-xml 2.x for Scala 2.13+ by @mkurz
    • #686 fix warnings by @xuwei-k
    • #685 remove scala-java8-compat dependency by @xuwei-k
    • #684 use jdk.CollectionConverters instead of deprecated JavaConverters by @xuwei-k
    • #679 GitHub actions last round + badges by @mkurz
    • #677 Use secrets inherit for publish workflow by @mkurz
    • #676 Switch to cmd.yml by @mkurz
    • #675 scalafmt-core 3.5.2 (was 3.5.1) by @scala-steward
    • #674 Remove obsolete comment by @mkurz
    • #673 Use new "Ready To Merge" approach for GHA by @mkurz
    • #672 Switch to v1 GHA + nicer validateCode alias by @mkurz
    • #669 scalafmt-core 3.5.1 (was 2.7.5) by @scala-steward
    • #670 Switch to reusable workflows by @mkurz
    • #667 awaitility 4.2.0 (was 4.1.1) by @scala-steward
    • #666 sbt-assembly 1.2.0 (was 1.1.1) by @scala-steward
    • #665 logback-core 1.2.11 (was 1.2.10) by @scala-steward
    • #664 No need to exclude scala-parser-combinators anymore by @mkurz
    • #663 Latest akka/ssl-config/play-json RC by @mkurz
    • #604 Scala 3 by @xuwei-k
    • #655 sbt-assembly 1.1.1 (was 1.1.0) by @scala-steward
    • #659 slf4j-api 1.7.36 (was 1.7.35) by @scala-steward
    • #656 sbt-header 5.6.5 (was 5.6.0) by @scala-steward
    • #657 sbt 1.6.2 (was 1.6.1) by @scala-steward
    • #660 specs2-core, specs2-junit, ... 4.13.3 (was 4.13.2) by @scala-steward
    • #652 Add release drafter with configs from .github repo by @mkurz
    • #650 Use official release drafter action by @mkurz
    • #646 assertj-core 3.22.0 (was 3.21.0) by @scala-steward
    • #648 slf4j-api 1.7.35 (was 1.7.32) by @scala-steward
    • #649 specs2-core, specs2-junit, ... 4.13.2 (was 4.13.1) by @scala-steward
    • #644 Drop Travis CI by @ihostage
    • #643 Configure branches for PR workflow explicitly by @ihostage
    • #639 Migrate check RRs for 2.1.x to GitHub Actions by @ihostage
    • #637 Migrate to GitHub Actions by @ihostage

    :heart: Thanks to our premium sponsors!

    If you find this OSS project useful for work, please consider asking your company to support it by becoming a sponsor. You can also individually sponsor the project by becoming a backer.

    :bow: Thanks to our contributors

    Finally, thanks to the community for their help with detailed bug reports, discussions about new features and pull request reviews. This project is only possible due to the help we had from amazing contributors. Special thanks to all code contributors who helped with this particular release (they are listed below)!

    Source code(tar.gz)
    Source code(zip)
  • 2.1.10(May 19, 2022)

    Problems occured during the release of 2.1.8 and 2.1.9, that's why these versions have not been published to the maven central repository.

    Changes

    • #682 Homepage needed for publishing by @mkurz
    • #681 Fix pom by @mkurz
    • #680 [2.1.x] sbt-ci-release + GHA by @mkurz
    • #662 [2.1.x] Keep dependencies like in v2.1.7 by @mkurz
    • #653 [2.1.x] Add release drafter with configs from .github repo by @mkurz
    • #651 [2.1.x] Rename master branch to main by @mkurz
    • #645 [2.1.x] Drop Travis CI by @ihostage
    • #642 [2.1.x] Migrate to GitHub Actions by @ihostage
    • #638 [2.1.x] ssl-config 0.6.0 (like akka 2.6.19) by @mkurz

    :heart: Thanks to our premium sponsors!

    If you find this OSS project useful for work, please consider asking your company to support it by becoming a sponsor. You can also individually sponsor the project by becoming a backer.

    :bow: Thanks to our contributors

    Finally, thanks to the community for their help with detailed bug reports, discussions about new features and pull request reviews. This project is only possible due to the help we had from amazing contributors. Special thanks to all code contributors who helped with this particular release (they are listed below)!

    Source code(tar.gz)
    Source code(zip)
  • 2.1.7(Jan 4, 2022)

    What's Changed

    • Set scala-java8-compat version depending on Scala version by @mkurz in https://github.com/playframework/play-ws/pull/630

    Full Changelog: https://github.com/playframework/play-ws/compare/2.1.6...2.1.7

    Source code(tar.gz)
    Source code(zip)
  • 2.2.0-M1(Jan 3, 2022)

    Milestone release, do not use in production!

    Changes

    • Bump versions, scala-xml conditional depending on Scala version, sbt-ci-release #631 by @scala-steward
    • re-format build.sbt #636 by @xuwei-k
    • Update scalafmt docstrings setting #635 by @xuwei-k
    • add explicit type annotations for implicits #634 by @xuwei-k
    • scala-library 2.13.7 (was 2.13.6) #625 by @scala-steward

    What's Changed

    • Configure mima previous version to 2.1.0 by @octonato in https://github.com/playframework/play-ws/pull/422
    • Correctly shade javax.activation by @octonato in https://github.com/playframework/play-ws/pull/420
    • Update sbt-header to 5.3.1 by @scala-steward in https://github.com/playframework/play-ws/pull/423
    • Update sbt to 1.3.4 by @scala-steward in https://github.com/playframework/play-ws/pull/424
    • Update sbt-sonatype to 3.8.1 by @scala-steward in https://github.com/playframework/play-ws/pull/425
    • Update akka-http to 10.1.11 by @scala-steward in https://github.com/playframework/play-ws/pull/428
    • Fix code examples in markdown documentation & Scaladoc by @cchantep in https://github.com/playframework/play-ws/pull/429
    • Update akka-stream to 2.6.1 by @scala-steward in https://github.com/playframework/play-ws/pull/430
    • add new AHC parameter: connectionPoolCleanerPeriod by @maxcellent in https://github.com/playframework/play-ws/pull/416
    • Update play-json to 2.8.1 by @scala-steward in https://github.com/playframework/play-ws/pull/432
    • Update sbt to 1.3.5 by @scala-steward in https://github.com/playframework/play-ws/pull/434
    • [2.1.x]: Configure mima to check against version 2.1.2 by @marcospereira in https://github.com/playframework/play-ws/pull/435
    • Add git depth settings for Travis by @octonato in https://github.com/playframework/play-ws/pull/437
    • Update sbt-pgp to 2.0.1 by @scala-steward in https://github.com/playframework/play-ws/pull/438
    • Update slf4j-api to 1.7.30 by @scala-steward in https://github.com/playframework/play-ws/pull/436
    • auto merge scala-steward by @octonato in https://github.com/playframework/play-ws/pull/441
    • Adds dynver settings by @octonato in https://github.com/playframework/play-ws/pull/440
    • Update sbt to 1.3.6 by @scala-steward in https://github.com/playframework/play-ws/pull/442
    • Remove copyright year (2.1.x) by @octonato in https://github.com/playframework/play-ws/pull/444
    • Remove year from Copyright header by @octonato in https://github.com/playframework/play-ws/pull/443
    • Update sbt 1.3.6 and fix coursier cache by @octonato in https://github.com/playframework/play-ws/pull/446
    • branch-merge-2.1.x (b4ca2fe) by @octonato in https://github.com/playframework/play-ws/pull/439
    • Update sbt-mima-plugin to 0.6.4 by @scala-steward in https://github.com/playframework/play-ws/pull/457
    • Update async-http-client to 2.10.5 by @scala-steward in https://github.com/playframework/play-ws/pull/456
    • Update specs2-core, specs2-junit, ... to 4.8.3 by @scala-steward in https://github.com/playframework/play-ws/pull/455
    • Update sbt to 1.3.8 by @scala-steward in https://github.com/playframework/play-ws/pull/454
    • Update akka-stream to 2.6.3 by @scala-steward in https://github.com/playframework/play-ws/pull/451
    • Update sbt-release to 1.0.13 by @scala-steward in https://github.com/playframework/play-ws/pull/449
    • Update assertj-core to 3.15.0 by @scala-steward in https://github.com/playframework/play-ws/pull/453
    • Update sbt-header to 5.4.0 by @scala-steward in https://github.com/playframework/play-ws/pull/452
    • Move to scalafmt by @wsargent in https://github.com/playframework/play-ws/pull/459
    • Change travis to use latest JDK point version by @wsargent in https://github.com/playframework/play-ws/pull/460
    • Doc update java client by @wsargent in https://github.com/playframework/play-ws/pull/463
    • Remove unnecessary repository by @marcospereira in https://github.com/playframework/play-ws/pull/464
    • Remove probot settings by @octonato in https://github.com/playframework/play-ws/pull/465
    • Update sbt-scalafmt to 2.0.7 by @scala-steward in https://github.com/playframework/play-ws/pull/461
    • Update sbt-scalafmt to 2.3.1 by @scala-steward in https://github.com/playframework/play-ws/pull/466
    • Update scalafmt-core to 2.4.1 by @scala-steward in https://github.com/playframework/play-ws/pull/468
    • Update ssl-config-core to 0.4.2 by @scala-steward in https://github.com/playframework/play-ws/pull/470
    • [doc] Add note to show using AHC client directly by @wsargent in https://github.com/playframework/play-ws/pull/472
    • Update scalafmt-core to 2.4.2 by @scala-steward in https://github.com/playframework/play-ws/pull/471
    • Update sbt-mima-plugin to 0.7.0 by @scala-steward in https://github.com/playframework/play-ws/pull/475
    • Update scala-java8-compat to 0.9.1 by @scala-steward in https://github.com/playframework/play-ws/pull/469
    • Update specs2-core, specs2-junit, ... to 4.9.1 by @scala-steward in https://github.com/playframework/play-ws/pull/477
    • Update awaitility to 4.0.2 by @scala-steward in https://github.com/playframework/play-ws/pull/445
    • Update sbt-scalafmt to 2.3.2 by @scala-steward in https://github.com/playframework/play-ws/pull/480
    • JPMS Automatic-Module-Name for all jars published by @nhojpatrick in https://github.com/playframework/play-ws/pull/474
    • Update sbt-sonatype to 3.9.2 by @scala-steward in https://github.com/playframework/play-ws/pull/485
    • Update specs2-core, specs2-junit, ... to 4.9.3 by @scala-steward in https://github.com/playframework/play-ws/pull/490
    • Update sbt-scalafmt to 2.3.4 by @scala-steward in https://github.com/playframework/play-ws/pull/493
    • Update sbt to 1.3.10 by @scala-steward in https://github.com/playframework/play-ws/pull/494
    • Update sbt-header to 5.5.0 by @scala-steward in https://github.com/playframework/play-ws/pull/491
    • Update sbt-header to 5.6.0 by @scala-steward in https://github.com/playframework/play-ws/pull/495
    • Update specs2-core, specs2-junit, ... to 4.9.4 by @scala-steward in https://github.com/playframework/play-ws/pull/496
    • Fix typo in README by @basicobject in https://github.com/playframework/play-ws/pull/497
    • Don't automatically merge Scala Stewards PRs by @ignasi35 in https://github.com/playframework/play-ws/pull/499
    • Update akka-stream to 2.6.5 by @scala-steward in https://github.com/playframework/play-ws/pull/500
    • Update scala-xml to 1.3.0 by @scala-steward in https://github.com/playframework/play-ws/pull/483
    • Update async-http-client to 2.12.1 by @scala-steward in https://github.com/playframework/play-ws/pull/489
    • Update akka-http to 10.1.12 by @scala-steward in https://github.com/playframework/play-ws/pull/505
    • Enable Release Drafter as Github action by @ennru in https://github.com/playframework/play-ws/pull/508
    • Update scalafmt-core to 2.5.3 by @scala-steward in https://github.com/playframework/play-ws/pull/510
    • Update play-json to 2.9.0 by @scala-steward in https://github.com/playframework/play-ws/pull/511
    • Update awaitility to 4.0.3 by @scala-steward in https://github.com/playframework/play-ws/pull/509
    • Update assertj-core to 3.16.1 by @scala-steward in https://github.com/playframework/play-ws/pull/503
    • Update sbt to 1.3.12 by @scala-steward in https://github.com/playframework/play-ws/pull/513
    • Update akka-stream to 2.6.6 by @scala-steward in https://github.com/playframework/play-ws/pull/515
    • Build: Mima, Dynver and publish settings; release to Bintray from Travis by @ennru in https://github.com/playframework/play-ws/pull/514
    • Update sbt-scalafmt to 2.4.0 by @scala-steward in https://github.com/playframework/play-ws/pull/507
    • Mergify: merge-when-green by @octonato in https://github.com/playframework/play-ws/pull/516
    • sbt-dynver 4.1.1 (was 4.0.0) by @scala-steward in https://github.com/playframework/play-ws/pull/517
    • sbt 1.3.13 (was 1.3.12) by @scala-steward in https://github.com/playframework/play-ws/pull/519
    • scalafmt-core 2.6.2 (was 2.5.3) by @scala-steward in https://github.com/playframework/play-ws/pull/520
    • fix ssl-config url by @xuwei-k in https://github.com/playframework/play-ws/pull/522
    • specs2-core, specs2-junit, ... 4.10.3 (was 4.9.4) by @scala-steward in https://github.com/playframework/play-ws/pull/530
    • sbt-scalafmt 2.4.2 (was 2.4.0) by @scala-steward in https://github.com/playframework/play-ws/pull/525
    • scalafmt-core 2.6.4 (was 2.6.2) by @scala-steward in https://github.com/playframework/play-ws/pull/526
    • sbt-jmh 0.4.0 (was 0.3.7) by @scala-steward in https://github.com/playframework/play-ws/pull/531
    • async-http-client 2.12.2 (was 2.12.1) by @scala-steward in https://github.com/playframework/play-ws/pull/550
    • play-json 2.9.2 (was 2.9.0) by @scala-steward in https://github.com/playframework/play-ws/pull/549
    • assertj-core 3.18.1 (was 3.16.1) by @scala-steward in https://github.com/playframework/play-ws/pull/547
    • akka-http 10.1.13 (was 10.1.12) by @scala-steward in https://github.com/playframework/play-ws/pull/546
    • specs2-core, specs2-junit, ... 4.10.5 (was 4.10.3) by @scala-steward in https://github.com/playframework/play-ws/pull/544
    • sbt-bintray 0.6.1 (was 0.5.6) by @scala-steward in https://github.com/playframework/play-ws/pull/541
    • sbt-mima-plugin 0.8.1 (was 0.7.0) by @scala-steward in https://github.com/playframework/play-ws/pull/538
    • sbt-assembly 0.15.0 (was 0.14.10) by @scala-steward in https://github.com/playframework/play-ws/pull/518
    • scalafmt-core 2.7.5 (was 2.6.4) by @scala-steward in https://github.com/playframework/play-ws/pull/543
    • signpost-core 2.1.1 (was 1.2.1.2) by @scala-steward in https://github.com/playframework/play-ws/pull/524
    • akka-stream 2.6.10 (was 2.6.6) by @scala-steward in https://github.com/playframework/play-ws/pull/539
    • specs2-core, specs2-junit, ... 4.10.6 (was 4.10.5) by @scala-steward in https://github.com/playframework/play-ws/pull/557
    • Make play.ws.ahc.disableUrlEncoding actually do something useful by @mkurz in https://github.com/playframework/play-ws/pull/552
    • akka-http 10.1.14 (was 10.1.13) by @scala-steward in https://github.com/playframework/play-ws/pull/558
    • scala-library 2.12.13 (was 2.12.10) by @scala-steward in https://github.com/playframework/play-ws/pull/560
    • akka-stream 2.6.13 (was 2.6.10) by @scala-steward in https://github.com/playframework/play-ws/pull/559
    • scala-library 2.13.5 (was 2.13.1) by @scala-steward in https://github.com/playframework/play-ws/pull/561
    • async-http-client 2.12.3 (was 2.12.2) by @scala-steward in https://github.com/playframework/play-ws/pull/564
    • ssl-config-core 0.4.3 (was 0.4.2) by @scala-steward in https://github.com/playframework/play-ws/pull/563
    • add parentheses for lambda param by @xuwei-k in https://github.com/playframework/play-ws/pull/569
    • specs2-core, specs2-junit, ... 4.11.0 (was 4.10.6) by @scala-steward in https://github.com/playframework/play-ws/pull/568
    • specs2-core, specs2-junit, ... 4.12.2 (was 4.11.0) by @scala-steward in https://github.com/playframework/play-ws/pull/584
    • slf4j-api 1.7.31 (was 1.7.30) by @scala-steward in https://github.com/playframework/play-ws/pull/583
    • assertj-core 3.20.2 (was 3.19.0) by @scala-steward in https://github.com/playframework/play-ws/pull/581
    • akka-stream 2.6.15 (was 2.6.14) by @scala-steward in https://github.com/playframework/play-ws/pull/580
    • sbt-assembly 1.0.0 (was 0.15.0) by @scala-steward in https://github.com/playframework/play-ws/pull/579
    • sbt-jmh 0.4.3 (was 0.4.0) by @scala-steward in https://github.com/playframework/play-ws/pull/577
    • scala-xml 2.0.0 (was 1.3.0) by @scala-steward in https://github.com/playframework/play-ws/pull/574
    • scala-java8-compat 1.0.0 (was 0.9.1) by @scala-steward in https://github.com/playframework/play-ws/pull/573
    • awaitility 4.1.0 (was 4.0.3) by @scala-steward in https://github.com/playframework/play-ws/pull/572
    • sbt-mima-plugin 0.9.2 (was 0.8.1) by @scala-steward in https://github.com/playframework/play-ws/pull/571
    • add explicit type annotations for implicit val by @xuwei-k in https://github.com/playframework/play-ws/pull/586
    • use slash syntax instead of deprecated in by @xuwei-k in https://github.com/playframework/play-ws/pull/585
    • fix warnings in build.sbt by @xuwei-k in https://github.com/playframework/play-ws/pull/588
    • specs2-core, specs2-junit, ... 4.12.4-js-ec (was 4.12.2) by @scala-steward in https://github.com/playframework/play-ws/pull/595
    • scala-xml 2.0.1 (was 2.0.0) by @scala-steward in https://github.com/playframework/play-ws/pull/591
    • logback-core 1.2.5 (was 1.2.3) by @scala-steward in https://github.com/playframework/play-ws/pull/589
    • slf4j-api 1.7.32 (was 1.7.31) by @scala-steward in https://github.com/playframework/play-ws/pull/594
    • sbt-scalafmt 2.4.3 (was 2.4.2) by @scala-steward in https://github.com/playframework/play-ws/pull/593
    • rename master branch to main by @SethTisue in https://github.com/playframework/play-ws/pull/597
    • remove old Bintray-based publishing by @SethTisue in https://github.com/playframework/play-ws/pull/599
    • sbt 1.5.5 (was 1.3.13) by @scala-steward in https://github.com/playframework/play-ws/pull/592
    • ssl-config-core 0.6.0 (was 0.4.3) + cachecontrol 2.1.0 by @scala-steward in https://github.com/playframework/play-ws/pull/590
    • Upgrade to latest akka 2.6.16 by @mkurz in https://github.com/playframework/play-ws/pull/603
    • sbt-mima-plugin 1.0.0 (was 0.9.2) by @scala-steward in https://github.com/playframework/play-ws/pull/606
    • sbt-assembly 1.1.0 (was 1.0.0) by @scala-steward in https://github.com/playframework/play-ws/pull/605
    • logback-core 1.2.6 (was 1.2.5) by @scala-steward in https://github.com/playframework/play-ws/pull/609
    • assertj-core 3.21.0 (was 3.20.2) by @scala-steward in https://github.com/playframework/play-ws/pull/610
    • junit-interface 0.13.2 (was 0.11) by @scala-steward in https://github.com/playframework/play-ws/pull/613
    • sbt-mima-plugin 1.0.1 (was 1.0.0) by @scala-steward in https://github.com/playframework/play-ws/pull/614
    • akka-stream 2.6.17 (was 2.6.16) by @scala-steward in https://github.com/playframework/play-ws/pull/615
    • awaitility 4.1.1 (was 4.1.0) by @scala-steward in https://github.com/playframework/play-ws/pull/616
    • scala-java8-compat 1.0.2 (was 1.0.0) by @scala-steward in https://github.com/playframework/play-ws/pull/617
    • scala-library 2.13.7 (was 2.13.6) by @scala-steward in https://github.com/playframework/play-ws/pull/625
    • add explicit type annotations for implicits by @xuwei-k in https://github.com/playframework/play-ws/pull/634
    • Update scalafmt docstrings setting by @xuwei-k in https://github.com/playframework/play-ws/pull/635
    • re-format build.sbt by @xuwei-k in https://github.com/playframework/play-ws/pull/636
    • Bump versions, scala-xml conditional depending on Scala version, sbt-ci-release by @scala-steward in https://github.com/playframework/play-ws/pull/631

    New Contributors

    • @maxcellent made their first contribution in https://github.com/playframework/play-ws/pull/416
    • @nhojpatrick made their first contribution in https://github.com/playframework/play-ws/pull/474
    • @basicobject made their first contribution in https://github.com/playframework/play-ws/pull/497
    • @ennru made their first contribution in https://github.com/playframework/play-ws/pull/508
    • @SethTisue made their first contribution in https://github.com/playframework/play-ws/pull/597

    Full Changelog: https://github.com/playframework/play-ws/compare/2.1.0...2.2.0-M1

    Source code(tar.gz)
    Source code(zip)
  • 2.1.6(Dec 1, 2021)

  • 2.1.5(Nov 30, 2021)

    What's Changed

    • update play-json to 2.8.2 by @octonato in https://github.com/playframework/play-ws/pull/622

    Full Changelog: https://github.com/playframework/play-ws/compare/2.1.4...2.1.5

    Source code(tar.gz)
    Source code(zip)
  • 2.1.4(Nov 29, 2021)

    Changes

    Source code(tar.gz)
    Source code(zip)
  • 2.1.3(Mar 19, 2021)

  • 2.1.2(May 19, 2020)

  • v2.0.4(May 15, 2019)

    This release contains an important bug fix on streamed calls. In case of an error, after a connection is established, the error is now properly propagated. See https://github.com/playframework/play-ws/pull/340

    For the complete changes since the previous release see change log

    Source code(tar.gz)
    Source code(zip)
  • v1.1.13(May 15, 2019)

    This release contains an important bug fix on streamed calls. In case of an error, after a connection is established, the error is now properly propagated. See https://github.com/playframework/play-ws/pull/340

    For the complete changes since the previous release see change log

    Source code(tar.gz)
    Source code(zip)
tasks, async await, actors and channels for java

AsyncUtils tasks, async, await, actors and channels for java This project tries to explore several approaches to simplify async/concurrent programming

Michael Hoffer 6 Dec 1, 2022
Square’s meticulous HTTP client for the JVM, Android, and GraalVM.

OkHttp See the project website for documentation and APIs. HTTP is the way modern applications network. It’s how we exchange data & media. Doing HTTP

Square 43.4k Jan 9, 2023
Asynchronous Http and WebSocket Client library for Java

Async Http Client Follow @AsyncHttpClient on Twitter. The AsyncHttpClient (AHC) library allows Java applications to easily execute HTTP requests and a

AsyncHttpClient 6k Dec 31, 2022
Telegram API Client and Telegram BOT API Library and Framework in Pure java.

Javagram Telegram API Client and Telegram Bot API library and framework in pure Java. Hello Telegram You can use Javagram for both Telegram API Client

Java For Everything 3 Oct 17, 2021
The Java gRPC implementation. HTTP/2 based RPC

gRPC-Java - An RPC library and framework gRPC-Java works with JDK 7. gRPC-Java clients are supported on Android API levels 16 and up (Jelly Bean and l

grpc 10.2k Jan 1, 2023
Magician is an asynchronous non-blocking network protocol analysis package, supports TCP, UDP protocol, built-in Http, WebSocket decoder

An asynchronous non-blocking network protocol analysis package Project Description Magician is an asynchronous non-blocking network protocol analysis

贝克街的天才 103 Nov 30, 2022
A Java event based WebSocket and HTTP server

Webbit - A Java event based WebSocket and HTTP server Getting it Prebuilt JARs are available from the central Maven repository or the Sonatype Maven r

null 808 Dec 23, 2022
HTTP Server Model made in java

SimplyJServer HTTP Server Model made in java Features Fast : SimplyJServer is 40%-60% faster than Apache, due to it's simplicity. Simple to implement

Praudyogikee for Advanced Technology 2 Sep 25, 2021
TCP/UDP client/server library for Java, based on Kryo

KryoNet can be downloaded on the releases page. Please use the KryoNet discussion group for support. Overview KryoNet is a Java library that provides

Esoteric Software 1.7k Jan 2, 2023
Proteus Java Client

Netifi Proteus Java This project has been moved to https://github.com/netifi/netifi-java Build from Source Run the following Gradle command to build t

netifi-proteus 42 Nov 20, 2020
Socket.IO Client Implementation in Java

Socket.IO-Client for Java socket.io-java-client is an easy to use implementation of socket.io for Java. It uses Weberknecht as transport backend, but

Enno Boland 946 Dec 21, 2022
Full-featured Socket.IO Client Library for Java, which is compatible with Socket.IO v1.0 and later.

Socket.IO-client Java This is the Socket.IO Client Library for Java, which is simply ported from the JavaScript client. See also: Android chat demo en

Socket.IO 5k Jan 4, 2023
BAIN Social is a Fully Decentralized Server/client system that utilizes Concepts pioneered by I2P, ToR, and PGP to create a system which bypasses singular hosts for data while keeping that data secure.

SYNOPSIS ---------------------------------------------------------------------------------------------------- Welcome to B.A.I.N - Barren's A.I. Natio

Barren A.I. Wolfsbane 14 Jan 11, 2022
IoT Platform, Device management, data collection, processing and visualization, multi protocol, rule engine, netty mqtt client

GIoT GIoT: GIoT是一个开源的IoT平台,支持设备管理、物模型,产品、设备管理、规则引擎、多种存储、多sink、多协议(http、mqtt、tcp,自定义协议)、多租户管理等等,提供插件化开发 Documentation Quick Start Module -> giot-starte

gerry 34 Sep 13, 2022
Book Finder application is a client-server application (gRPC) for educational purposes.

Book-Finder Book Finder application is a client-server application (gRPC) for educational purposes. Instalation These projects (Client/Server) are Mav

Mihai-Lucian Rîtan 21 Oct 27, 2022
A barebones WebSocket client and server implementation written in 100% Java.

Java WebSockets This repository contains a barebones WebSocket server and client implementation written in 100% Java. The underlying classes are imple

Nathan Rajlich 9.5k Dec 30, 2022
Realtime Client Server Framework for the JVM, supporting WebSockets with Cross-Browser Fallbacks

Welcome to Atmosphere: The Event Driven Framework supporting WebSocket and HTTP The Atmosphere Framework contains client and server side components fo

Atmosphere Framework 3.6k Jan 3, 2023
A small java project consisting of Client and Server, that communicate via TCP/UDP protocols.

Ninja Battle A small java project consisting of Client and Server, that communicate via TCP/UDP protocols. Client The client is equipped with a menu i

Steliyan Dobrev 2 Jan 14, 2022