|
21 | 21 | import static com.google.common.base.Strings.nullToEmpty;
|
22 | 22 |
|
23 | 23 | import com.google.common.annotations.VisibleForTesting;
|
24 |
| -import com.google.common.base.Strings; |
| 24 | +import com.google.common.base.Preconditions; |
25 | 25 | import com.google.common.collect.ImmutableMap;
|
26 | 26 | import com.google.common.io.ByteStreams;
|
27 | 27 | import com.google.common.io.Files;
|
28 | 28 | import com.google.common.net.HttpHeaders;
|
29 | 29 | import com.google.common.net.MediaType;
|
30 | 30 |
|
31 | 31 | import org.openqa.selenium.logging.LoggingHandler;
|
32 |
| -import org.openqa.selenium.remote.http.HttpMethod; |
33 |
| -import org.openqa.selenium.remote.http.HttpRequest; |
34 |
| -import org.openqa.selenium.remote.http.HttpResponse; |
35 | 32 | import org.openqa.selenium.remote.server.log.LoggingManager;
|
36 | 33 | import org.openqa.selenium.remote.server.log.PerSessionLogHandler;
|
37 | 34 | import org.openqa.selenium.remote.server.xdrpc.CrossDomainRpc;
|
38 | 35 | import org.openqa.selenium.remote.server.xdrpc.CrossDomainRpcLoader;
|
39 | 36 |
|
| 37 | +import java.io.ByteArrayInputStream; |
40 | 38 | import java.io.IOException;
|
41 | 39 | import java.io.InputStream;
|
42 | 40 | import java.io.OutputStream;
|
43 | 41 | import java.net.URL;
|
44 |
| -import java.util.Enumeration; |
45 | 42 | import java.util.concurrent.TimeUnit;
|
46 | 43 | import java.util.function.Supplier;
|
47 | 44 | import java.util.logging.Handler;
|
48 | 45 | import java.util.logging.Logger;
|
49 | 46 |
|
| 47 | +import javax.servlet.ReadListener; |
50 | 48 | import javax.servlet.ServletException;
|
| 49 | +import javax.servlet.ServletInputStream; |
51 | 50 | import javax.servlet.http.HttpServlet;
|
52 | 51 | import javax.servlet.http.HttpServletRequest;
|
| 52 | +import javax.servlet.http.HttpServletRequestWrapper; |
53 | 53 | import javax.servlet.http.HttpServletResponse;
|
54 | 54 |
|
55 | 55 | public class DriverServlet extends HttpServlet {
|
@@ -204,63 +204,32 @@ private void handleCrossDomainRpc(
|
204 | 204 | return;
|
205 | 205 | }
|
206 | 206 |
|
207 |
| - HttpRequest request = new HttpRequest( |
208 |
| - HttpMethod.valueOf(rpc.getMethod()), |
209 |
| - rpc.getPath()); |
210 |
| - request.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8.toString()); |
211 |
| - request.setContent(rpc.getContent()); |
212 |
| - |
213 |
| - HttpResponse response = commandHandler.handleRequest(request); |
214 |
| - sendResponse(response, servletResponse); |
215 |
| - } |
216 |
| - |
217 |
| - protected void handleRequest( |
218 |
| - HttpServletRequest servletRequest, HttpServletResponse servletResponse) |
219 |
| - throws ServletException, IOException { |
220 |
| - HttpRequest request = createInternalRequest(servletRequest); |
221 |
| - HttpResponse response = commandHandler.handleRequest(request); |
222 |
| - sendResponse(response, servletResponse); |
223 |
| - } |
| 207 | + servletRequest.setAttribute(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8.toString()); |
| 208 | + HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(servletRequest) { |
| 209 | + @Override |
| 210 | + public String getMethod() { |
| 211 | + return rpc.getMethod(); |
| 212 | + } |
224 | 213 |
|
225 |
| - private static HttpRequest createInternalRequest(HttpServletRequest servletRequest) |
226 |
| - throws IOException { |
227 |
| - String path = servletRequest.getPathInfo(); |
228 |
| - if (Strings.isNullOrEmpty(path)) { |
229 |
| - path = "/"; |
230 |
| - } |
231 |
| - HttpRequest request = new HttpRequest( |
232 |
| - HttpMethod.valueOf(servletRequest.getMethod().toUpperCase()), |
233 |
| - path); |
234 |
| - |
235 |
| - Enumeration<String> headerNames = servletRequest.getHeaderNames(); |
236 |
| - while (headerNames.hasMoreElements()) { |
237 |
| - String name = headerNames.nextElement(); |
238 |
| - Enumeration<String> headerValues = servletRequest.getHeaders(name); |
239 |
| - while (headerValues.hasMoreElements()) { |
240 |
| - String value = headerValues.nextElement(); |
241 |
| - request.setHeader(name, value); |
| 214 | + @Override |
| 215 | + public String getPathInfo() { |
| 216 | + return rpc.getPath(); |
242 | 217 | }
|
243 |
| - } |
244 | 218 |
|
245 |
| - try (InputStream stream = servletRequest.getInputStream()) { |
246 |
| - request.setContent(ByteStreams.toByteArray(stream)); |
247 |
| - } |
| 219 | + @Override |
| 220 | + public ServletInputStream getInputStream() throws IOException { |
| 221 | + return new InputStreamWrappingServletInputStream( |
| 222 | + new ByteArrayInputStream(rpc.getContent())); |
| 223 | + } |
| 224 | + }; |
248 | 225 |
|
249 |
| - return request; |
| 226 | + commandHandler.handleRequest(wrapper, servletResponse); |
250 | 227 | }
|
251 | 228 |
|
252 |
| - private void sendResponse(HttpResponse response, HttpServletResponse servletResponse) |
253 |
| - throws IOException { |
254 |
| - servletResponse.setStatus(response.getStatus()); |
255 |
| - for (String name : response.getHeaderNames()) { |
256 |
| - for (String value : response.getHeaders(name)) { |
257 |
| - servletResponse.addHeader(name, value); |
258 |
| - } |
259 |
| - } |
260 |
| - |
261 |
| - try (OutputStream output = servletResponse.getOutputStream()) { |
262 |
| - output.write(response.getContent()); |
263 |
| - } |
| 229 | + protected void handleRequest( |
| 230 | + HttpServletRequest servletRequest, HttpServletResponse servletResponse) |
| 231 | + throws ServletException, IOException { |
| 232 | + commandHandler.handleRequest(servletRequest, servletResponse); |
264 | 233 | }
|
265 | 234 |
|
266 | 235 | private class DriverSessionsSupplier implements Supplier<DriverSessions> {
|
@@ -328,4 +297,52 @@ private byte[] getResourceData(URL url) throws IOException {
|
328 | 297 | }
|
329 | 298 | }
|
330 | 299 | }
|
| 300 | + |
| 301 | + private static class InputStreamWrappingServletInputStream extends ServletInputStream { |
| 302 | + |
| 303 | + private final InputStream delegate; |
| 304 | + private int lastRead; |
| 305 | + |
| 306 | + public InputStreamWrappingServletInputStream(InputStream delegate) { |
| 307 | + this.delegate = Preconditions.checkNotNull(delegate); |
| 308 | + |
| 309 | + } |
| 310 | + |
| 311 | + @Override |
| 312 | + public int available() throws IOException { |
| 313 | + return delegate.available(); |
| 314 | + } |
| 315 | + |
| 316 | + @Override |
| 317 | + public void close() throws IOException { |
| 318 | + delegate.close(); |
| 319 | + lastRead = -1; |
| 320 | + } |
| 321 | + |
| 322 | + @Override |
| 323 | + public boolean isFinished() { |
| 324 | + return lastRead != -1; |
| 325 | + } |
| 326 | + |
| 327 | + @Override |
| 328 | + public boolean isReady() { |
| 329 | + return !isFinished(); |
| 330 | + } |
| 331 | + |
| 332 | + @Override |
| 333 | + public void setReadListener(ReadListener readListener) { |
| 334 | + throw new UnsupportedOperationException("setReadListener"); |
| 335 | + } |
| 336 | + |
| 337 | + @Override |
| 338 | + public int read() throws IOException { |
| 339 | + lastRead = delegate.read(); |
| 340 | + return lastRead; |
| 341 | + } |
| 342 | + |
| 343 | + @Override |
| 344 | + public boolean markSupported() { |
| 345 | + return false; |
| 346 | + } |
| 347 | + } |
331 | 348 | }
|
0 commit comments