diff --git a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java index 3f094ff53..061a291f2 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java +++ b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java @@ -62,8 +62,11 @@ import java.net.URL; import java.util.Map; import java.util.Optional; +import java.util.UUID; public class AppiumCommandExecutor extends HttpCommandExecutor { + // https://github.com/appium/appium-base-driver/pull/400 + private static final String IDEMPOTENCY_KEY_HEADER = "X-Idempotency-Key"; private final Optional serviceOptional; @@ -150,18 +153,23 @@ protected void setResponseCodec(ResponseCodec codec) { } protected HttpClient getClient() { - //noinspection unchecked return getPrivateFieldValue("client", HttpClient.class); } + protected HttpClient withRequestsPatchedByIdempotencyKey(HttpClient httpClient) { + return (request) -> { + request.setHeader(IDEMPOTENCY_KEY_HEADER, UUID.randomUUID().toString().toLowerCase()); + return httpClient.execute(request); + }; + } + private Response createSession(Command command) throws IOException { if (getCommandCodec() != null) { throw new SessionNotCreatedException("Session already exists"); } ProtocolHandshake handshake = new ProtocolHandshake() { - @SuppressWarnings("unchecked") - public Result createSession(HttpClient client, Command command) - throws IOException { + @SuppressWarnings({"unchecked", "UnstableApiUsage"}) + public Result createSession(HttpClient client, Command command) throws IOException { Capabilities desiredCapabilities = (Capabilities) command.getParameters().get("desiredCapabilities"); Capabilities desired = desiredCapabilities == null ? new ImmutableCapabilities() : desiredCapabilities; @@ -182,8 +190,8 @@ public Result createSession(HttpClient client, Command command) .getDeclaredMethod("createSession", HttpClient.class, InputStream.class, long.class); createSessionMethod.setAccessible(true); - Optional result = (Optional) createSessionMethod - .invoke(this, client, contentStream, counter.getCount()); + Optional result = (Optional) createSessionMethod.invoke(this, + withRequestsPatchedByIdempotencyKey(client), contentStream, counter.getCount()); return result.map(result1 -> { Result toReturn = result.get();