Skip to content

Commit

Permalink
Ensure protocol converter sets content length correctly.
Browse files Browse the repository at this point in the history
  • Loading branch information
shs96c committed Sep 4, 2019
1 parent 6074ee6 commit e21ca05
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 27 deletions.
65 changes: 38 additions & 27 deletions java/server/src/org/openqa/selenium/grid/web/ProtocolConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.MediaType;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.Command;
import org.openqa.selenium.remote.CommandCodec;
Expand All @@ -39,31 +40,33 @@
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.UncheckedIOException;
import java.net.HttpURLConnection;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;

import static java.net.HttpURLConnection.HTTP_OK;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.openqa.selenium.json.Json.MAP_TYPE;
import static org.openqa.selenium.remote.Dialect.W3C;
import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.bytes;
import static org.openqa.selenium.remote.http.Contents.string;

public class ProtocolConverter implements HttpHandler {

private final static Json JSON = new Json();
private final static ImmutableSet<String> IGNORED_REQ_HEADERS = ImmutableSet.<String>builder()
.add("connection")
.add("keep-alive")
.add("proxy-authorization")
.add("proxy-authenticate")
.add("proxy-connection")
.add("te")
.add("trailer")
.add("transfer-encoding")
.add("upgrade")
.build();
.add("connection")
.add("content-length")
.add("content-type")
.add("keep-alive")
.add("proxy-authorization")
.add("proxy-authenticate")
.add("proxy-connection")
.add("te")
.add("trailer")
.add("transfer-encoding")
.add("upgrade")
.build();

private final HttpClient client;
private final CommandCodec<HttpRequest> downstream;
Expand All @@ -74,9 +77,9 @@ public class ProtocolConverter implements HttpHandler {
private final Function<HttpResponse, HttpResponse> newSessionConverter;

public ProtocolConverter(
HttpClient client,
Dialect downstream,
Dialect upstream) {
HttpClient client,
Dialect downstream,
Dialect upstream) {
this.client = Objects.requireNonNull(client);

Objects.requireNonNull(downstream);
Expand All @@ -99,9 +102,9 @@ public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
@SuppressWarnings("unchecked")
Map<String, ?> parameters = (Map<String, ?>) converter.apply(command.getParameters());
command = new Command(
command.getSessionId(),
command.getName(),
parameters);
command.getSessionId(),
command.getName(),
parameters);

HttpRequest request = upstream.encode(command);

Expand Down Expand Up @@ -161,11 +164,10 @@ private HttpResponse createW3CNewSessionResponse(HttpResponse response) {
Preconditions.checkState(value.get("sessionId") != null);
Preconditions.checkState(value.get("value") instanceof Map);

return new HttpResponse()
.setContent(asJson(ImmutableMap.of(
"value", ImmutableMap.of(
"sessionId", value.get("sessionId"),
"capabilities", value.get("value")))));
return createResponse(ImmutableMap.of(
"value", ImmutableMap.of(
"sessionId", value.get("sessionId"),
"capabilities", value.get("value"))));
}

private HttpResponse createJwpNewSessionResponse(HttpResponse response) {
Expand All @@ -175,11 +177,20 @@ private HttpResponse createJwpNewSessionResponse(HttpResponse response) {
Preconditions.checkState(value.get("sessionId") != null);
Preconditions.checkState(value.get("capabilities") instanceof Map);

return createResponse(ImmutableMap.of(
"status", 0,
"sessionId", value.get("sessionId"),
"value", value.get("capabilities")));
}


private HttpResponse createResponse(ImmutableMap<String, Object> toSend) {
byte[] bytes = JSON.toJson(toSend).getBytes(UTF_8);

return new HttpResponse()
.setContent(asJson(ImmutableMap.of(
"status", 0,
"sessionId", value.get("sessionId"),
"value", value.get("capabilities"))));
.setHeader("Content-Type", MediaType.JSON_UTF_8.toString())
.setHeader("Content-Length", String.valueOf(bytes.length))
.setContent(bytes(bytes));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import java.util.Map;

import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
Expand All @@ -53,6 +54,7 @@
import static org.openqa.selenium.remote.Dialect.W3C;
import static org.openqa.selenium.remote.ErrorCodes.UNHANDLED_ERROR;
import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.bytes;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.Contents.utf8String;
import static org.openqa.selenium.remote.http.HttpMethod.POST;
Expand Down Expand Up @@ -282,4 +284,26 @@ public void newJwpSessionResponseShouldBeConvertedToW3CCorrectly() {
assertThat(convertedResponse.get("sessionId")).isEqualTo("i like cheese very much");
assertThat(convertedResponse.get("value")).isEqualTo(ImmutableMap.of("cheese", "brie"));
}

@Test
public void contentLengthShouldBeSetCorrectlyOnSuccessfulNewSessionRequest() {
Map<String, Object> w3cResponse = ImmutableMap.of(
"value", ImmutableMap.of(
"capabilities", ImmutableMap.of("cheese", "brie"),
"sessionId", "i like cheese very much"));
byte[] bytes = json.toJson(w3cResponse).getBytes(UTF_8);

HttpClient client = mock(HttpClient.class);
Mockito.when(client.execute(any()))
.thenReturn(
new HttpResponse().setHeader("Content-Length", String.valueOf(bytes.length)).setContent(bytes(bytes)));

ProtocolConverter converter = new ProtocolConverter(client, OSS, W3C);

HttpResponse response = converter.execute(
new HttpRequest(POST, "/session")
.setContent(asJson(ImmutableMap.of("desiredCapabilities", ImmutableMap.of()))));

assertThat(response.getHeader("Content-Length")).isNotEqualTo(String.valueOf(bytes.length));
}
}

0 comments on commit e21ca05

Please sign in to comment.