Skip to content

Instantly share code, notes, and snippets.

@freynaud
Created February 20, 2012 17:23
Show Gist options
  • Save freynaud/1870188 to your computer and use it in GitHub Desktop.
Save freynaud/1870188 to your computer and use it in GitHub Desktop.
### Eclipse Workspace Patch 1.0
#P selenium
Index: java/server/src/org/openqa/grid/web/servlet/handler/WebDriverRequestHandler.java
===================================================================
--- java/server/src/org/openqa/grid/web/servlet/handler/WebDriverRequestHandler.java (revision 15924)
+++ java/server/src/org/openqa/grid/web/servlet/handler/WebDriverRequestHandler.java (working copy)
@@ -1,139 +0,0 @@
-/*
-Copyright 2011 WebDriver committers
-Copyright 2011 Software Freedom Conservancy
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package org.openqa.grid.web.servlet.handler;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.openqa.grid.internal.ExternalSessionKey;
-import org.openqa.grid.common.SeleniumProtocol;
-import org.openqa.grid.common.exception.GridException;
-import org.openqa.grid.internal.exception.NewSessionException;
-import org.openqa.grid.internal.utils.ForwardConfiguration;
-import org.openqa.grid.internal.Registry;
-import org.openqa.grid.internal.TestSession;
-import org.openqa.jetty.jetty.servlet.ServletHttpResponse;
-
-/**
- * Handles an individual request, scope is a single request and hence a single thread.
- */
-public class WebDriverRequestHandler extends RequestHandler {
-
- private static final Logger log = Logger.getLogger(WebDriverRequestHandler.class.getName());
-
- protected WebDriverRequestHandler(HttpServletRequest request, HttpServletResponse response,
- Registry registry) {
- super(request, response, registry);
- }
-
-
- @Override
- public RequestType extractRequestType() {
-
- if ("/session".equals(getRequest().getPathInfo())) {
- return RequestType.START_SESSION;
- } else if (getRequest().getMethod().equalsIgnoreCase("DELETE")) {
- ExternalSessionKey
- externalKey = ExternalSessionKey.fromWebDriverRequest(getRequest().getPathInfo());
- if (getRequest().getPathInfo().endsWith("/session/" + externalKey.getKey())) {
- return RequestType.STOP_SESSION;
- }
- }
- return RequestType.REGULAR;
- }
-
- @Override
- public ExternalSessionKey extractSession() {
- if (getRequestType() == RequestType.START_SESSION) {
- throw new IllegalAccessError("Cannot call that method of a new session request.");
- }
- String path = getRequest().getPathInfo();
- return ExternalSessionKey.fromWebDriverRequest(path);
- }
-
- // TODO freynaud parsing is so so.
- @SuppressWarnings("unchecked")
- // JSON iterator.
- @Override
- public Map<String, Object> extractDesiredCapability() {
- String json = getRequestBody();
- Map<String, Object> desiredCapability = new HashMap<String, Object>();
- try {
- JSONObject map = new JSONObject(json);
- JSONObject dc = map.getJSONObject("desiredCapabilities");
- for (Iterator iterator = dc.keys(); iterator.hasNext();) {
- String key = (String) iterator.next();
- Object value = dc.get(key);
- if (value == JSONObject.NULL) {
- value = null;
- }
- desiredCapability.put(key, value);
- }
- } catch (JSONException e) {
- throw new GridException("Cannot extract a capabilities from the request " + json);
- }
- return desiredCapability;
- }
-
- @Override
- public ExternalSessionKey forwardNewSessionRequestAndUpdateRegistry(TestSession session) throws NewSessionException{
- try {
- // here, don't forward the requestBody directly, but read the
- // desiredCapabilities from the session instead.
- // That allow the TestSessionListener.before modification of the
- // capability map to be propagated.
- JSONObject c = new JSONObject();
- c.put("desiredCapabilities", session.getRequestedCapabilities());
- String content = c.toString();
- ForwardConfiguration config = new ForwardConfiguration();
- config.setProtocol(SeleniumProtocol.WebDriver);
- config.setNewSessionRequest(true);
- config.setContentOverWrite(content);
- session.forward(getRequest(), getResponse(), config);
- } catch (IOException e) {
- //log.warning("Error forwarding the request " + e.getMessage());
- throw new NewSessionException("Error forwarding the request " + e.getMessage(),e);
- } catch (JSONException e) {
- //log.warning("Error with the request " + e.getMessage());
- throw new NewSessionException("Error with the request " + e.getMessage(),e);
- }
-
- if (getResponse().containsHeader("Location")) {
- String location =
- ((ServletHttpResponse) getResponse()).getHttpResponse().getField("Location");
- ExternalSessionKey res = ExternalSessionKey.fromWebDriverRequest( location);
- if ( res!=null){
- return res;
- }else {
- throw new NewSessionException("couldn't extract the new session from the response header.");
- }
- } else {
- //log.warning("Error, header should contain Location");
- throw new NewSessionException("Error, header should contain Location ");
- }
-
- }
-}
Index: java/server/src/org/openqa/grid/internal/NewSessionRequestQueue.java
===================================================================
--- java/server/src/org/openqa/grid/internal/NewSessionRequestQueue.java (revision 15924)
+++ java/server/src/org/openqa/grid/internal/NewSessionRequestQueue.java (working copy)
@@ -108,7 +108,7 @@
public synchronized Iterable<DesiredCapabilities> getDesiredCapabilities() {
List<DesiredCapabilities> result = new ArrayList<DesiredCapabilities>();
for (RequestHandler req : newSessionRequests) {
- result.add(new DesiredCapabilities(req.getDesiredCapabilities()));
+ result.add(new DesiredCapabilities(req.getRequest().getDesiredCapabilities()));
}
return result;
}
Index: java/server/src/org/openqa/grid/web/servlet/handler/SeleniumBasedRequest.java
===================================================================
--- java/server/src/org/openqa/grid/web/servlet/handler/SeleniumBasedRequest.java (revision 0)
+++ java/server/src/org/openqa/grid/web/servlet/handler/SeleniumBasedRequest.java (revision 0)
@@ -0,0 +1,187 @@
+package org.openqa.grid.web.servlet.handler;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.util.Map;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+import org.apache.commons.io.IOUtils;
+import org.openqa.grid.common.SeleniumProtocol;
+import org.openqa.grid.internal.ExternalSessionKey;
+import org.openqa.grid.internal.Registry;
+import org.openqa.grid.internal.TestSession;
+import org.openqa.grid.internal.exception.NewSessionException;
+
+/**
+ * wrapper around a selenium http request that helps accessing the internal
+ * details that are selenium related ( type of protocol, new session request
+ * etc ) Also allows to change the content of the request, or read it
+ * on the hub.
+ *
+ */
+public abstract class SeleniumBasedRequest extends HttpServletRequestWrapper {
+
+ private byte[] body;
+ private final Registry registry;
+ private final SeleniumProtocol protocol;
+ private final RequestType type;
+ private final String encoding = "UTF-8";
+ private final Map<String, Object> desiredCapability;
+
+
+ public static SeleniumBasedRequest createFromRequest(HttpServletRequest request, Registry registry) {
+ if ("/selenium-server/driver".equals(request.getServletPath())) {
+ return new LegacySeleniumRequest(request, registry);
+ } else {
+ return new WebDriverRequest(request, registry);
+ }
+ }
+
+
+ /*@Deprecated
+ public SeleniumBasedRequest(Registry registry,SeleniumProtocol protocol,RequestType type,Map<String, Object> desiredCapability){
+ super(null);
+ this.registry = registry;
+ this.protocol = protocol;
+ this.type = type;
+ this.desiredCapability = desiredCapability;
+ }*/
+
+ public SeleniumBasedRequest(HttpServletRequest httpServletRequest, Registry registry,
+ SeleniumProtocol protocol) {
+ super(httpServletRequest);
+ try {
+ InputStream is = super.getInputStream();
+ body = IOUtils.toByteArray(is);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ this.protocol = protocol;
+ this.registry = registry;
+ type = extractRequestType();
+
+ if (type == RequestType.START_SESSION) {
+ desiredCapability = extractDesiredCapability();
+ } else {
+ desiredCapability = null;
+ }
+ }
+
+ public Registry getRegistry() {
+ return registry;
+ }
+
+ /**
+ * @return the type of the request.
+ */
+ public abstract RequestType extractRequestType();
+
+ /**
+ * Extract the session from the request. This only works for a request that has a session already
+ * assigned. It shouldn't be called for a new session request.
+ *
+ * @return the external session id sent by the remote. Null is the session cannot be found.
+ */
+ public abstract ExternalSessionKey extractSession();
+
+ /**
+ * Parse the request to extract the desiredCapabilities. For non web driver protocol ( selenium1 )
+ * some mapping will be necessary
+ *
+ * @return the desired capabilities requested by the client.
+ */
+ public abstract Map<String, Object> extractDesiredCapability();
+
+
+ // TODO freynaud remove the TestSession parameter.The listener can modify the
+ // original request instead.
+ public abstract String getNewSessionRequestedCapability(TestSession session);
+
+
+
+ public RequestType getRequestType() {
+ return type;
+ }
+
+ @Override
+ public ServletInputStream getInputStream() throws IOException {
+ return new ServletInputStreamImpl(new ByteArrayInputStream(body));
+ }
+
+ @Override
+ public BufferedReader getReader() throws IOException {
+ return new BufferedReader(new InputStreamReader(getInputStream(), encoding));
+ }
+
+ public String getBody() {
+ try {
+ Charset charset = Charset.forName(encoding);
+ CharsetDecoder decoder = charset.newDecoder();
+ CharBuffer cbuf = decoder.decode(ByteBuffer.wrap(body));
+ return new String(cbuf.toString());
+ } catch (CharacterCodingException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public void setBody(String content) {
+ body = content.getBytes();
+ }
+
+
+
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("method: " + getMethod().toUpperCase() + "\n");
+ builder.append("path: " + getPathInfo() + "\n");
+ if (getBody() != null) {
+ builder.append("parameter: " + getBody());
+ }
+ return builder.toString();
+ }
+
+ public Map<String, Object> getDesiredCapabilities() {
+ return desiredCapability;
+ }
+
+ private class ServletInputStreamImpl extends ServletInputStream {
+
+ private InputStream is;
+
+ public ServletInputStreamImpl(InputStream is) {
+ this.is = is;
+ }
+
+ public int read() throws IOException {
+ return is.read();
+ }
+
+ public boolean markSupported() {
+ return false;
+ }
+
+ public synchronized void mark(int i) {
+ throw new RuntimeException("not implemented");
+ }
+
+ public synchronized void reset() throws IOException {
+ throw new RuntimeException("not implemented");
+ }
+ }
+
+
+
+}
Index: java/server/src/org/openqa/grid/web/servlet/handler/Selenium1RequestHandler.java
===================================================================
--- java/server/src/org/openqa/grid/web/servlet/handler/Selenium1RequestHandler.java (revision 15924)
+++ java/server/src/org/openqa/grid/web/servlet/handler/Selenium1RequestHandler.java (working copy)
@@ -1,173 +0,0 @@
-/*
-Copyright 2011 WebDriver committers
-Copyright 2011 Software Freedom Conservancy
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package org.openqa.grid.web.servlet.handler;
-
-import org.openqa.grid.common.RegistrationRequest;
-import org.openqa.grid.common.SeleniumProtocol;
-import org.openqa.grid.internal.ExternalSessionKey;
-import org.openqa.grid.internal.exception.NewSessionException;
-import org.openqa.grid.internal.utils.ForwardConfiguration;
-import org.openqa.grid.internal.Registry;
-import org.openqa.grid.internal.TestSession;
-import org.openqa.grid.web.utils.BrowserNameUtils;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Handler processing the selenium1 based requests. Each request body has to be read to get the
- * sessionId at least.
- */
-public class Selenium1RequestHandler extends RequestHandler {
-
- private static final Logger log = Logger.getLogger(Selenium1RequestHandler.class.getName());
-
- Selenium1RequestHandler(HttpServletRequest request, HttpServletResponse response,
- Registry registry) {
- super(request, response, registry);
- if (getRequestBody() == null) {
- throw new InstantiationError(
- "Cannot create a selenium1 request handler from a request without body");
- }
- }
-
- @Override
- public RequestType extractRequestType() {
- if (getRequestBody().contains("cmd=getNewBrowserSession")) {
- return RequestType.START_SESSION;
- } else if (getRequestBody().contains("cmd=testComplete")) {
- return RequestType.STOP_SESSION;
- } else {
- return RequestType.REGULAR;
- }
- }
-
- @Override
- public ExternalSessionKey extractSession() {
- if (getRequestType() == RequestType.START_SESSION) {
- throw new IllegalAccessError("Cannot call that method of a new session request.");
- }
- // for selenium 1, the url is ignored. The session has to be read from
- // the request body.
- String command = getRequestBody();
- String[] pieces = command.split("&");
- ExternalSessionKey externalSessionKey;
- for (String piece : pieces) {
- externalSessionKey = ExternalSessionKey.fromSe1Request( piece);
- if (externalSessionKey != null){
- return externalSessionKey;
- }
- }
- return null;
-
- }
-
- @Override
- public Map<String, Object> extractDesiredCapability() {
- if (getRequestType() != RequestType.START_SESSION) {
- throw new Error("the desired capability is only present in the new session requests.");
- }
- String[] pieces = getRequestBody().split("&");
- for (String piece : pieces) {
- try {
- piece = URLDecoder.decode(piece, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- }
- if (piece.startsWith("1=")) {
- String envt = piece.replace("1=", "");
- Map<String, Object> cap = new HashMap<String, Object>();
- // TODO freynaud : more splitting, like trying to guess the
- // plateform or version ?
-
- // We don't want to process Grid 1.0 environment names because
- // they use an explicit mapping
- // to a browser launcher string.
- if (getRegistry().getConfiguration().getGrid1Mapping().containsKey(envt)) {
- cap.put(RegistrationRequest.BROWSER, envt);
- }
-
- // Otherwise, process the environment string to extract the
- // target browser and platform.
- else {
- cap.putAll(BrowserNameUtils.parseGrid2Environment(envt));
- }
-
- return cap;
- }
- }
-
- throw new RuntimeException("Error");
- }
-
- // TODO freynaud do some real parsing here instead. BrowserString to
- // Capabilities service or so.
- @Override
- public ExternalSessionKey forwardNewSessionRequestAndUpdateRegistry(TestSession session) throws NewSessionException {
- String responseBody;
-
- try {
- String body = getRequestBody();
- String[] pieces = body.split("&");
- StringBuilder builder = new StringBuilder();
-
- for (String piece : pieces) {
- if (piece.startsWith("1=")) {
- piece = URLDecoder.decode(piece, "UTF-8");
- String parts[] = piece.split("1=");
-
- // We don't want to process Grid 1.0 environment names
- // because they use an explicit mapping
- // to a browser launcher string.
- if (getRegistry().getConfiguration().getGrid1Mapping().containsKey(parts[1])) {
- piece =
- String.format(
- "1=%s",
- URLEncoder.encode(
- BrowserNameUtils.lookupGrid1Environment(parts[1], getRegistry()), "UTF-8"));
- }
-
- // Otherwise, the requested environment includes the browser
- // name before the space.
- else {
- piece =
- (String) BrowserNameUtils.parseGrid2Environment(piece).get(
- RegistrationRequest.BROWSER);
- }
- }
- builder.append(piece).append("&");
- }
-
- ForwardConfiguration config = new ForwardConfiguration();
- config.setProtocol(SeleniumProtocol.Selenium);
- config.setNewSessionRequest(true);
- config.setContentOverWrite(builder.toString());
- responseBody = session.forward(getRequest(), getResponse(), config);
- } catch (IOException e) {
- throw new NewSessionException("Error forwarding the request " + e.getMessage(),e);
- }
- return ExternalSessionKey.fromResponseBody(responseBody);
- }
-}
Index: java/server/src/org/openqa/grid/internal/Registry.java
===================================================================
--- java/server/src/org/openqa/grid/internal/Registry.java (revision 15924)
+++ java/server/src/org/openqa/grid/internal/Registry.java (working copy)
@@ -238,12 +238,12 @@
this.hub = hub;
}
- public void addNewSessionRequest(RequestHandler request) {
+ public void addNewSessionRequest(RequestHandler handler) {
try {
lock.lock();
- proxies.verifyAbilityToHandleDesiredCapabilities(request.getDesiredCapabilities());
- newSessionQueue.add(request);
+ proxies.verifyAbilityToHandleDesiredCapabilities(handler.getRequest().getDesiredCapabilities());
+ newSessionQueue.add(handler);
fireMatcherStateChanged();
} finally {
lock.unlock();
@@ -278,12 +278,12 @@
}
- private boolean takeRequestHandler(RequestHandler request) {
- final TestSession session = proxies.getNewSession(request.getDesiredCapabilities());
+ private boolean takeRequestHandler(RequestHandler handler) {
+ final TestSession session = proxies.getNewSession(handler.getRequest().getDesiredCapabilities());
final boolean sessionCreated = session != null;
if (sessionCreated) {
activeTestSessions.add(session);
- request.bindSession(session);
+ handler.bindSession(session);
}
return sessionCreated;
}
Index: java/server/src/org/openqa/grid/web/servlet/handler/WebDriverRequest.java
===================================================================
--- java/server/src/org/openqa/grid/web/servlet/handler/WebDriverRequest.java (revision 0)
+++ java/server/src/org/openqa/grid/web/servlet/handler/WebDriverRequest.java (revision 0)
@@ -0,0 +1,78 @@
+package org.openqa.grid.web.servlet.handler;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.openqa.grid.common.SeleniumProtocol;
+import org.openqa.grid.common.exception.GridException;
+import org.openqa.grid.internal.ExternalSessionKey;
+import org.openqa.grid.internal.Registry;
+import org.openqa.grid.internal.TestSession;
+import org.openqa.grid.internal.exception.NewSessionException;
+
+public class WebDriverRequest extends SeleniumBasedRequest {
+
+ public WebDriverRequest(HttpServletRequest httpServletRequest, Registry registry) {
+ super(httpServletRequest, registry, SeleniumProtocol.WebDriver);
+ }
+
+ @Override
+ public RequestType extractRequestType() {
+ if ("/session".equals(getPathInfo())) {
+ return RequestType.START_SESSION;
+ } else if (getMethod().equalsIgnoreCase("DELETE")) {
+ ExternalSessionKey externalKey = ExternalSessionKey.fromWebDriverRequest(getPathInfo());
+ if (getPathInfo().endsWith("/session/" + externalKey.getKey())) {
+ return RequestType.STOP_SESSION;
+ }
+ }
+ return RequestType.REGULAR;
+ }
+
+ @Override
+ public ExternalSessionKey extractSession() {
+ if (getRequestType() == RequestType.START_SESSION) {
+ throw new IllegalAccessError("Cannot call that method of a new session request.");
+ }
+ String path = getPathInfo();
+ return ExternalSessionKey.fromWebDriverRequest(path);
+ }
+
+ @Override
+ public Map<String, Object> extractDesiredCapability() {
+ String json = getBody();
+ Map<String, Object> desiredCapability = new HashMap<String, Object>();
+ try {
+ JSONObject map = new JSONObject(json);
+ JSONObject dc = map.getJSONObject("desiredCapabilities");
+ for (Iterator iterator = dc.keys(); iterator.hasNext();) {
+ String key = (String) iterator.next();
+ Object value = dc.get(key);
+ if (value == JSONObject.NULL) {
+ value = null;
+ }
+ desiredCapability.put(key, value);
+ }
+ } catch (JSONException e) {
+ throw new GridException("Cannot extract a capabilities from the request " + json);
+ }
+ return desiredCapability;
+ }
+
+ @Override
+ public String getNewSessionRequestedCapability(TestSession session) {
+ try {
+ JSONObject c = new JSONObject();
+ c.put("desiredCapabilities", session.getRequestedCapabilities());
+ String content = c.toString();
+ return content;
+ } catch (JSONException e) {
+ throw new NewSessionException("Error with the request " + e.getMessage(),e);
+ }
+ }
+}
Index: java/server/src/org/openqa/grid/internal/TestSession.java
===================================================================
--- java/server/src/org/openqa/grid/internal/TestSession.java (revision 15924)
+++ java/server/src/org/openqa/grid/internal/TestSession.java (working copy)
@@ -38,6 +38,10 @@
import org.openqa.grid.internal.listeners.CommandListener;
import org.openqa.grid.internal.utils.ForwardConfiguration;
import org.openqa.grid.web.Hub;
+import org.openqa.grid.web.servlet.handler.LegacySeleniumRequest;
+import org.openqa.grid.web.servlet.handler.RequestType;
+import org.openqa.grid.web.servlet.handler.SeleniumBasedRequest;
+import org.openqa.grid.web.servlet.handler.WebDriverRequest;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
@@ -188,9 +192,9 @@
/**
* Forward the request to the remote, execute the TestSessionListeners if applicable.
*/
- public void forward(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ /* public void forward(HttpServletRequest request, HttpServletResponse response) throws IOException {
forward(request, response, new ForwardConfiguration());
- }
+ }*/
private HttpClient getClient() {
return slot.getProxy().getHttpClientFactory().getGridHttpClient();
@@ -200,19 +204,20 @@
* @param config for special cases of forwards. Typically is the content has to be intercepted, or
* if the hub has to be updated before the new session request is forwarded.
*/
- public String forward(HttpServletRequest request, HttpServletResponse response,
- ForwardConfiguration config) throws IOException {
+ public String forward(SeleniumBasedRequest request, HttpServletResponse response/*,
+ ForwardConfiguration config*/) throws IOException {
String res = null;
forwardingRequest = true;
try {
if (slot.getProxy() instanceof CommandListener) {
+ System.out.println(request);
((CommandListener) slot.getProxy()).beforeCommand(this, request, response);
}
lastActivity = timeSource.currentTimeInMillis();
- HttpRequest proxyRequest = prepareProxyRequest(request, config);
+ HttpRequest proxyRequest = prepareProxyRequest(request/*, config*/);
HttpResponse proxyResponse = sendRequestToNode(proxyRequest);
@@ -221,21 +226,21 @@
response.setStatus(proxyResponse.getStatusLine().getStatusCode());
processResponseHeaders(request, response, slot.getRemoteURL(), proxyResponse);
- updateHubIfNewWebDriverSession(config, proxyResponse);
+ updateHubIfNewWebDriverSession(request, proxyResponse);
HttpEntity responseBody = proxyResponse.getEntity();
if (responseBody != null) {
try {
InputStream in = responseBody.getContent();
- boolean isSeleniumNewSessionRequest =
- config.isNewSessionRequest() && config.getProtocol() == SeleniumProtocol.Selenium;
- if (config.isBodyHasToBeRead() || isSeleniumNewSessionRequest) {
+ //boolean isSeleniumNewSessionRequest =
+ // config.isNewSessionRequest() && config.getProtocol() == SeleniumProtocol.Selenium;
+ //if (config.isBodyHasToBeRead() || isSeleniumNewSessionRequest) {
+ if (request.getRequestType() == RequestType.START_SESSION &&
+ request instanceof LegacySeleniumRequest) {
res = getResponseUtf8Content(in);
-
- if (isSeleniumNewSessionRequest) {
- updateHubNewSeleniumSession(res);
- }
+ updateHubNewSeleniumSession(res);
+
in = new ByteArrayInputStream(res.getBytes("UTF-8"));
}
@@ -263,9 +268,10 @@
setExternalKey(key);
}
- private void updateHubIfNewWebDriverSession(ForwardConfiguration config,
+ private void updateHubIfNewWebDriverSession(SeleniumBasedRequest request,
HttpResponse proxyResponse) {
- if (config.isNewSessionRequest() && config.getProtocol() == SeleniumProtocol.WebDriver) {
+ if (request.getRequestType() == RequestType.START_SESSION
+ && request instanceof WebDriverRequest) {
Header h = proxyResponse.getFirstHeader("Location");
if (h == null) {
throw new GridException(
@@ -285,7 +291,7 @@
return client.execute(host, proxyRequest);
}
- private HttpRequest prepareProxyRequest(HttpServletRequest request, ForwardConfiguration config)
+ private HttpRequest prepareProxyRequest(HttpServletRequest request/*, ForwardConfiguration config*/)
throws IOException {
URL remoteURL = slot.getRemoteURL();
@@ -305,12 +311,12 @@
}
HttpRequest proxyRequest;
- if (config.getContentOverWrite() != null) {
+ /*if (config.getContentOverWrite() != null) {
BasicHttpEntityEnclosingRequest r =
new BasicHttpEntityEnclosingRequest(request.getMethod(), uri);
r.setEntity(new StringEntity(config.getContentOverWrite()));
proxyRequest = r;
- } else if (body != null) {
+ } else */if (body != null) {
BasicHttpEntityEnclosingRequest r =
new BasicHttpEntityEnclosingRequest(request.getMethod(), uri);
r.setEntity(new InputStreamEntity(body, request.getContentLength()));
Index: java/server/src/org/openqa/grid/web/servlet/handler/LegacySeleniumRequest.java
===================================================================
--- java/server/src/org/openqa/grid/web/servlet/handler/LegacySeleniumRequest.java (revision 0)
+++ java/server/src/org/openqa/grid/web/servlet/handler/LegacySeleniumRequest.java (revision 0)
@@ -0,0 +1,134 @@
+package org.openqa.grid.web.servlet.handler;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.openqa.grid.common.RegistrationRequest;
+import org.openqa.grid.common.SeleniumProtocol;
+import org.openqa.grid.internal.ExternalSessionKey;
+import org.openqa.grid.internal.Registry;
+import org.openqa.grid.internal.TestSession;
+import org.openqa.grid.internal.exception.NewSessionException;
+import org.openqa.grid.web.utils.BrowserNameUtils;
+
+public class LegacySeleniumRequest extends SeleniumBasedRequest {
+
+ public LegacySeleniumRequest(HttpServletRequest httpServletRequest, Registry registry) {
+ super(httpServletRequest, registry, SeleniumProtocol.Selenium);
+
+ }
+
+ @Override
+ public RequestType extractRequestType() {
+ if (getBody().contains("cmd=getNewBrowserSession")) {
+ return RequestType.START_SESSION;
+ } else if (getBody().contains("cmd=testComplete")) {
+ return RequestType.STOP_SESSION;
+ } else {
+ return RequestType.REGULAR;
+ }
+
+ }
+
+ @Override
+ public ExternalSessionKey extractSession() {
+ if (getRequestType() == RequestType.START_SESSION) {
+ throw new IllegalAccessError("Cannot call that method of a new session request.");
+ }
+ // for selenium 1, the url is ignored. The session has to be read from
+ // the request body.
+ String command = getBody();
+ String[] pieces = command.split("&");
+ ExternalSessionKey externalSessionKey;
+ for (String piece : pieces) {
+ externalSessionKey = ExternalSessionKey.fromSe1Request(piece);
+ if (externalSessionKey != null) {
+ return externalSessionKey;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Map<String, Object> extractDesiredCapability() {
+ if (getRequestType() != RequestType.START_SESSION) {
+ throw new Error("the desired capability is only present in the new session requests.");
+ }
+ String[] pieces = getBody().split("&");
+ for (String piece : pieces) {
+ try {
+ piece = URLDecoder.decode(piece, "UTF-8");
+ } catch (UnsupportedEncodingException e) {}
+ if (piece.startsWith("1=")) {
+ String envt = piece.replace("1=", "");
+ Map<String, Object> cap = new HashMap<String, Object>();
+ // TODO freynaud : more splitting, like trying to guess the
+ // plateform or version ?
+
+ // We don't want to process Grid 1.0 environment names because
+ // they use an explicit mapping
+ // to a browser launcher string.
+ if (getRegistry().getConfiguration().getGrid1Mapping().containsKey(envt)) {
+ cap.put(RegistrationRequest.BROWSER, envt);
+ }
+
+ // Otherwise, process the environment string to extract the
+ // target browser and platform.
+ else {
+ cap.putAll(BrowserNameUtils.parseGrid2Environment(envt));
+ }
+
+ return cap;
+ }
+ }
+
+ throw new RuntimeException("Error");
+ }
+
+ @Override
+ public String getNewSessionRequestedCapability(TestSession session) {
+ try {
+ String body = getBody();
+ String[] pieces = body.split("&");
+ StringBuilder builder = new StringBuilder();
+
+ for (String piece : pieces) {
+ if (piece.startsWith("1=")) {
+ piece = URLDecoder.decode(piece, "UTF-8");
+ String parts[] = piece.split("1=");
+
+ // We don't want to process Grid 1.0 environment names
+ // because they use an explicit mapping
+ // to a browser launcher string.
+ if (getRegistry().getConfiguration().getGrid1Mapping().containsKey(parts[1])) {
+ piece =
+ String.format(
+ "1=%s",
+ URLEncoder.encode(
+ BrowserNameUtils.lookupGrid1Environment(parts[1], getRegistry()), "UTF-8"));
+ }
+
+ // Otherwise, the requested environment includes the browser
+ // name before the space.
+ else {
+ piece =
+ (String) BrowserNameUtils.parseGrid2Environment(piece).get(
+ RegistrationRequest.BROWSER);
+ }
+ }
+ builder.append(piece).append("&");
+ }
+ return builder.toString();
+ } catch (UnsupportedEncodingException ignore) {
+
+ }
+ throw new NewSessionException("Error with the request ");
+
+ }
+
+}
Index: java/server/src/org/openqa/grid/web/servlet/DriverServlet.java
===================================================================
--- java/server/src/org/openqa/grid/web/servlet/DriverServlet.java (revision 15924)
+++ java/server/src/org/openqa/grid/web/servlet/DriverServlet.java (working copy)
@@ -77,7 +77,7 @@
throws IOException {
RequestHandler req = null;
try {
- req = RequestHandler.createHandler(request, response, getRegistry());
+ req = new RequestHandler(request, response, getRegistry());
req.process();
} catch (Throwable e) {
Index: java/server/src/org/openqa/grid/web/servlet/handler/RequestHandler.java
===================================================================
--- java/server/src/org/openqa/grid/web/servlet/handler/RequestHandler.java (revision 15924)
+++ java/server/src/org/openqa/grid/web/servlet/handler/RequestHandler.java (working copy)
@@ -17,23 +17,7 @@
package org.openqa.grid.web.servlet.handler;
-import org.openqa.grid.common.exception.ClientGoneException;
-import org.openqa.grid.common.exception.GridException;
-import org.openqa.grid.internal.ExternalSessionKey;
-import org.openqa.grid.internal.Registry;
-import org.openqa.grid.internal.RemoteProxy;
-import org.openqa.grid.internal.SessionTerminationReason;
-import org.openqa.grid.internal.TestSession;
-import org.openqa.grid.internal.exception.NewSessionException;
-import org.openqa.grid.internal.listeners.Prioritizer;
-import org.openqa.grid.internal.listeners.TestSessionListener;
-import org.openqa.grid.internal.utils.ForwardConfiguration;
-
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -44,7 +28,18 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.openqa.grid.common.exception.ClientGoneException;
+import org.openqa.grid.common.exception.GridException;
+import org.openqa.grid.internal.ExternalSessionKey;
+import org.openqa.grid.internal.Registry;
+import org.openqa.grid.internal.RemoteProxy;
+import org.openqa.grid.internal.SessionTerminationReason;
+import org.openqa.grid.internal.TestSession;
+import org.openqa.grid.internal.exception.NewSessionException;
+import org.openqa.grid.internal.listeners.Prioritizer;
+import org.openqa.grid.internal.listeners.TestSessionListener;
+
/**
* Base stuff to handle the request coming from a remote. Ideally, there should be only 1 concrete
* class, but to support both legacy selenium1 and web driver, 2 classes are needed. <p/> {@link
@@ -55,14 +50,12 @@
* thread. The instance is also accessed by the matcher thread.
*/
@SuppressWarnings("JavaDoc")
-public abstract class RequestHandler implements Comparable<RequestHandler> {
+public class RequestHandler implements Comparable<RequestHandler> {
private final Registry registry;
- private final HttpServletRequest request;
+ private final SeleniumBasedRequest request;
private final HttpServletResponse response;
- private String body = null;
- private boolean bodyHasBeenRead = false;
private volatile Map<String, Object> desiredCapabilities = null;
private RequestType requestType = null;
private volatile TestSession session = null;
@@ -73,73 +66,46 @@
private static final Logger log = Logger.getLogger(RequestHandler.class.getName());
private final Thread waitingThread;
- /**
- * Detect what kind of protocol ( selenium1 vs webdriver ) is used by the request and create the
- * associated handler.
- */
- public static RequestHandler createHandler(HttpServletRequest request,
- HttpServletResponse response, Registry registry) {
- if (isSeleniumProtocol(request)) {
- return new Selenium1RequestHandler(request, response, registry);
- } else {
- return new WebDriverRequestHandler(request, response, registry);
- }
- }
+
+
- protected RequestHandler(HttpServletRequest request, HttpServletResponse response,
- Registry registry) {
- this.request = request;
+ public RequestHandler(HttpServletRequest request, HttpServletResponse response,
+ Registry registry) {
+ this.request = SeleniumBasedRequest.createFromRequest(request, registry);;
this.response = response;
this.registry = registry;
this.waitingThread = Thread.currentThread();
}
- /**
- * @return the type of the request.
- */
- public abstract RequestType extractRequestType();
- /**
- * Extract the session from the request. This only works for a request that has a session already
- * assigned. It shouldn't be called for a new session request.
- *
- * @return the external session id sent by the remote. Null is the session cannot be found.
- */
- public abstract ExternalSessionKey extractSession();
/**
- * Parse the request to extract the desiredCapabilities. For non web driver protocol ( selenium1 )
- * some mapping will be necessary
- *
- * @return the desired capabilities requested by the client.
- */
- public abstract Map<String, Object> extractDesiredCapability();
-
- /**
* Forward the new session request to the TestSession that has been assigned, and parse the
* response to extract and return the external key assigned by the remote.
*
- * @return the external key sent by the remote.
* @throws NewSessionException in case anything wrong happens during the new session process.
*/
- public abstract ExternalSessionKey forwardNewSessionRequestAndUpdateRegistry(TestSession session)
- throws NewSessionException;
+ public void forwardNewSessionRequestAndUpdateRegistry(TestSession session)
+ throws NewSessionException {
+ try {
+ String content = request.getNewSessionRequestedCapability(session);
+ getRequest().setBody(content);
+ session.forward(getRequest(), getResponse());
+ } catch (IOException e) {
+ //log.warning("Error forwarding the request " + e.getMessage());
+ throw new NewSessionException("Error forwarding the request " + e.getMessage(), e);
+ }
+ }
protected void forwardRequest(TestSession session, RequestHandler handler) throws IOException {
- if (bodyHasBeenRead) {
- ForwardConfiguration config = new ForwardConfiguration();
- config.setContentOverWrite(getRequestBody());
- session.forward(request, response, config);
- } else {
- session.forward(request, response);
- }
+ session.forward(request, response);
}
/**
* forwards the request to the remote, allocating / releasing the resources if necessary.
*/
public void process() {
- switch (getRequestType()) {
+ switch (request.getRequestType()) {
case START_SESSION:
try {
registry.addNewSessionRequest(this);
@@ -157,24 +123,24 @@
if (session == null) {
ExternalSessionKey sessionKey = null;
try {
- sessionKey = extractSession();
- } catch (RuntimeException ignore) {
- }
+ sessionKey = request.extractSession();
+ } catch (RuntimeException ignore) {}
throw new GridException("Session [" + sessionKey + "] not available - "
- + registry.getActiveSessions());
+ + registry.getActiveSessions());
}
try {
forwardRequest(session, this);
} catch (Throwable t) {
- SessionTerminationReason reason = t instanceof ClientGoneException ?
- SessionTerminationReason.CLIENT_GONE :
- SessionTerminationReason.FORWARDING_TO_NODE_FAILED;
+ SessionTerminationReason reason =
+ t instanceof ClientGoneException
+ ? SessionTerminationReason.CLIENT_GONE
+ : SessionTerminationReason.FORWARDING_TO_NODE_FAILED;
log.log(Level.SEVERE, "cannot forward the request " + t.getMessage(), t);
registry.terminate(session, reason);
throw new GridException("cannot forward the request " + t.getMessage(), t);
}
- if (getRequestType() == RequestType.STOP_SESSION) {
+ if (request.getRequestType() == RequestType.STOP_SESSION) {
registry.terminate(session, SessionTerminationReason.CLIENT_STOPPED_SESSION);
}
break;
@@ -192,7 +158,7 @@
}
}
-
+
/**
* calls the TestSessionListener is the proxy for that node has one specified.
*
@@ -243,36 +209,13 @@
* reads the input stream of the request and returns its content.
*/
protected String getRequestBody() {
- if (!bodyHasBeenRead) {
- bodyHasBeenRead = true;
- StringBuilder sb = new StringBuilder();
- String line;
- try {
- InputStream is = request.getInputStream();
- if (is == null) {
- return null;
- }
- BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
- while ((line = reader.readLine()) != null) {
- // TODO freynaud bug ?
- sb.append(line);/* .append("\n"); */
-
- }
- is.close();
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- body = sb.toString();
- }
- return body;
+ return request.getBody();
}
/**
* the HttpServletRequest this hanlder is processing.
*/
- public HttpServletRequest getRequest() {
+ public SeleniumBasedRequest getRequest() {
return request;
}
@@ -283,36 +226,19 @@
return response;
}
- public Map<String, Object> getDesiredCapabilities() {
- if (desiredCapabilities == null) {
- desiredCapabilities = extractDesiredCapability();
- }
- return desiredCapabilities;
- }
- protected void setDesiredCapabilities(Map<String, Object> desiredCapabilities) {
- this.desiredCapabilities = desiredCapabilities;
- }
public int compareTo(RequestHandler o) {
Prioritizer prioritizer = registry.getPrioritizer();
if (prioritizer != null) {
- return prioritizer.compareTo(this.getDesiredCapabilities(), o.getDesiredCapabilities());
+ return prioritizer.compareTo(this.getRequest().getDesiredCapabilities(), o.getRequest()
+ .getDesiredCapabilities());
} else {
return 0;
}
}
- protected RequestType getRequestType() {
- if (requestType == null) {
- requestType = extractRequestType();
- }
- return requestType;
- }
- protected void setRequestType(RequestType requestType) {
- this.requestType = requestType;
- }
protected void setSession(TestSession session) {
this.session = session;
@@ -325,7 +251,7 @@
protected TestSession getSession() {
if (session == null) {
- ExternalSessionKey externalKey = extractSession();
+ ExternalSessionKey externalKey = request.extractSession();
session = registry.getExistingSession(externalKey);
}
return session;
@@ -352,7 +278,6 @@
public String toString() {
StringBuilder b = new StringBuilder();
b.append("session :").append(session).append(" , ");
- b.append("cap : ").append(getDesiredCapabilities());
b.append("\n");
return b.toString();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment