Selenium Grid is a distributed testing infrastructure that allows running WebDriver tests in parallel across multiple machines and browsers.
—
The request routing system handles incoming HTTP requests and routes them to appropriate grid components, providing the main entry point for WebDriver clients and grid management operations.
Main router class that processes HTTP requests and coordinates with other grid components.
/**
* HTTP request router that serves as the main entry point for WebDriver requests
*/
class Router {
/** Constructor with required grid component dependencies */
Router(Tracer tracer, HttpClient.Factory clientFactory, SessionMap sessions,
NewSessionQueue queue, Distributor distributor);
/** Check if the router is ready to handle requests */
boolean isReady();
/** Check if this router can handle the given request */
boolean matches(HttpRequest req);
/** Execute the HTTP request and return response */
HttpResponse execute(HttpRequest req);
/** Close the router and cleanup resources */
void close();
}Usage Example:
// Create router with grid components
Router router = new Router(
tracer,
httpClientFactory,
sessionMap,
sessionQueue,
distributor
);
// Router automatically handles:
// - POST /session (new session creation)
// - WebDriver commands (/session/{id}/*)
// - Grid status endpoints
// - WebSocket proxy connections
// Check router readiness
if (router.isReady()) {
System.out.println("Router ready to accept requests");
}
// Process HTTP requests
HttpResponse response = router.execute(incomingRequest);Specialized handler for managing WebDriver session-related requests.
/**
* Handler for WebDriver session operations
*/
class HandleSession {
HandleSession(SessionMap sessions, HttpClient.Factory httpClientFactory);
/** Check if this handler matches the request */
boolean matches(HttpRequest req);
/** Execute the session-related request */
HttpResponse execute(HttpRequest req);
/** Get request details for debugging */
String toString();
}Handler for grid status and monitoring endpoints.
/**
* Handler for grid status and monitoring endpoints
*/
class GridStatusHandler {
GridStatusHandler(JsonOutput json, Distributor distributor);
/** Check if this handler matches the request */
boolean matches(HttpRequest req);
/** Execute the status request */
HttpResponse execute(HttpRequest req);
}Handler for proxying WebSocket connections between clients and nodes.
/**
* WebSocket proxy for real-time communication with nodes
*/
class ProxyWebsocketsIntoGrid {
ProxyWebsocketsIntoGrid(HttpClient.Factory httpClientFactory, SessionMap sessions);
/** Check if this handler matches the WebSocket request */
boolean matches(HttpRequest req);
/** Execute the WebSocket proxy setup */
HttpResponse execute(HttpRequest req);
}Router-specific configuration settings and command-line flags.
/**
* Configuration options for router behavior
*/
class RouterOptions {
static final String ROUTER_SECTION = "router";
/** Get router session timeout */
Duration getSessionTimeout(Config config);
/** Get request timeout for upstream requests */
Duration getRequestTimeout(Config config);
/** Get whether to enable WebSocket proxying */
boolean getWebSocketEnabled(Config config);
/** Get router host binding */
String getRouterHost(Config config);
/** Get router port */
int getRouterPort(Config config);
}
/**
* Command-line flags for router configuration
*/
class RouterFlags {
@Parameter(names = {"--session-timeout"},
description = "Session timeout in seconds")
int sessionTimeout = 300;
@Parameter(names = {"--request-timeout"},
description = "Request timeout in seconds")
int requestTimeout = 30;
@Parameter(names = {"--enable-websockets"},
description = "Enable WebSocket proxying")
boolean enableWebSockets = true;
@Parameter(names = {"--router-host"},
description = "Router host binding")
String routerHost = "0.0.0.0";
@Parameter(names = {"--router-port"},
description = "Router port")
int routerPort = 4444;
}// 1. Client sends POST /session with capabilities
HttpRequest newSessionRequest = new HttpRequest(POST, "/session")
.setContent(asJson(Map.of("capabilities", capabilities)));
// 2. Router processes request
if (router.matches(newSessionRequest)) {
HttpResponse response = router.execute(newSessionRequest);
// 3. Router coordinates with:
// - SessionQueue to queue the request
// - Distributor to find available node
// - SessionMap to track the created session
// - Returns session ID and WebDriver endpoint
}// 1. Client sends WebDriver command to existing session
HttpRequest webdriverCommand = new HttpRequest(POST, "/session/abc-123/element")
.setContent(asJson(Map.of("using", "id", "value", "submit-button")));
// 2. Router looks up session location
if (router.matches(webdriverCommand)) {
HttpResponse response = router.execute(webdriverCommand);
// 3. Router:
// - Uses SessionMap to find which node owns the session
// - Proxies request to the appropriate node
// - Returns node's response to client
}// Grid status endpoint
HttpRequest statusRequest = new HttpRequest(GET, "/status");
HttpResponse statusResponse = router.execute(statusRequest);
// Response includes:
// - Overall grid readiness
// - Node count and availability
// - Active session count
// - Supported capabilities across all nodesThe router handles several URL patterns:
| Pattern | Purpose | Handler |
|---|---|---|
POST /session | Create new session | Internal routing to Distributor |
GET,DELETE /session/{id} | Session lifecycle | HandleSession |
POST /session/{id}/* | WebDriver commands | HandleSession |
GET /status | Grid status | GridStatusHandler |
GET /ui/* | Grid UI assets | Static file handler |
| WebSocket upgrades | Real-time proxy | ProxyWebsocketsIntoGrid |
// Router error responses
try {
HttpResponse response = router.execute(request);
if (response.getStatus() == HTTP_NOT_FOUND) {
// Session not found or invalid endpoint
} else if (response.getStatus() == HTTP_INTERNAL_ERROR) {
// Node communication failure or internal error
} else if (response.getStatus() == HTTP_REQUEST_TIMEOUT) {
// Request timeout (node unresponsive)
}
} catch (Exception e) {
// Network errors, malformed requests, etc.
System.err.println("Router error: " + e.getMessage());
}// Router depends on all major grid components
public class GridRouter {
public static Router create(Config config) {
// Create dependencies
EventBus eventBus = new GuavaEventBus();
SessionMap sessionMap = LocalSessionMap.create(config);
NewSessionQueue sessionQueue = LocalNewSessionQueue.create(config);
Distributor distributor = LocalDistributor.create(config);
// Create router with all components
return new Router(
tracer,
httpClientFactory,
sessionMap,
sessionQueue,
distributor
);
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-grid