From 1fb80661cb425282c3edccd58aef78f65afa68cf Mon Sep 17 00:00:00 2001 From: "kyrylo.bilchenko" Date: Fri, 29 Mar 2019 14:51:42 +0100 Subject: [PATCH 01/11] initial commit --- README.md | 2 +- browsermob-core/pom.xml | 4 +- .../bmp/filters/HarCaptureFilter.java | 56 ++++++++----------- browsermob-dist/pom.xml | 2 +- browsermob-legacy/pom.xml | 4 +- browsermob-rest/pom.xml | 2 +- mitm/pom.xml | 2 +- pom.xml | 4 +- 8 files changed, 34 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 939d1ceff..f86633c7a 100644 --- a/README.md +++ b/README.md @@ -395,7 +395,7 @@ When you build the latest code from source, you'll have access to the latest sna net.lightbody.bmp browsermob-core - 2.1.20-SNAPSHOT + 2.1.20 test ``` diff --git a/browsermob-core/pom.xml b/browsermob-core/pom.xml index fd600d3e9..4c9bb2f0c 100644 --- a/browsermob-core/pom.xml +++ b/browsermob-core/pom.xml @@ -6,7 +6,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.20-SNAPSHOT + 2.1.20 4.0.0 @@ -42,7 +42,7 @@ org.apache.maven.plugins maven-surefire-plugin - -Xmx1g -XX:MaxPermSize=256m + -Xmx1g diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java b/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java index 46b62841e..5feb037dd 100644 --- a/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java +++ b/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java @@ -10,14 +10,7 @@ import io.netty.handler.codec.http.cookie.ClientCookieDecoder; import io.netty.handler.codec.http.cookie.Cookie; import io.netty.handler.codec.http.cookie.ServerCookieDecoder; -import net.lightbody.bmp.core.har.Har; -import net.lightbody.bmp.core.har.HarCookie; -import net.lightbody.bmp.core.har.HarEntry; -import net.lightbody.bmp.core.har.HarNameValuePair; -import net.lightbody.bmp.core.har.HarPostData; -import net.lightbody.bmp.core.har.HarPostDataParam; -import net.lightbody.bmp.core.har.HarRequest; -import net.lightbody.bmp.core.har.HarResponse; +import net.lightbody.bmp.core.har.*; import net.lightbody.bmp.exception.UnsupportedCharsetException; import net.lightbody.bmp.filters.support.HttpConnectTiming; import net.lightbody.bmp.filters.util.HarCaptureUtil; @@ -33,22 +26,17 @@ import java.net.InetSocketAddress; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.Calendar; -import java.util.Date; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import static net.lightbody.bmp.filters.StatsDMetricsFilter.*; -import static net.lightbody.bmp.filters.StatsDMetricsFilter.getStatsDPort; public class HarCaptureFilter extends HttpsAwareFiltersAdapter { private static final Logger log = LoggerFactory.getLogger(HarCaptureFilter.class); private static final ThreadLocal statsDClient = new InheritableThreadLocal<>(); private static final ThreadLocal isAlreadyLoggedIn = InheritableThreadLocal.withInitial(() -> false); + private static final ThreadLocal httpObjectThreadLocal = new InheritableThreadLocal<>(); /** * The currently active HAR at the time the current request is received. @@ -251,30 +239,32 @@ public HttpResponse clientToProxyRequest(HttpObject httpObject) { public HttpObject serverToProxyResponse(HttpObject httpObject) { // if a ServerResponseCaptureFilter is configured, delegate to it to collect the server's response. if it is not // configured, we still need to capture basic information (timings, HTTP status, etc.), just not content. - if (responseCaptureFilter != null) { - responseCaptureFilter.serverToProxyResponse(httpObject); - } - - if (httpObject instanceof HttpResponse) { - HttpResponse httpResponse = (HttpResponse) httpObject; + if (Objects.isNull(httpObjectThreadLocal.get()) || httpObjectThreadLocal.get().hashCode() != httpObject.hashCode()) { + if (responseCaptureFilter != null) { + responseCaptureFilter.serverToProxyResponse(httpObject); + } - captureResponse(httpResponse); - } + if (httpObject instanceof HttpResponse) { + HttpResponse httpResponse = (HttpResponse) httpObject; - if (httpObject instanceof HttpContent) { - HttpContent httpContent = (HttpContent) httpObject; + captureResponse(httpResponse); + } - captureResponseSize(httpContent); - } + if (httpObject instanceof HttpContent) { + HttpContent httpContent = (HttpContent) httpObject; - if (httpObject instanceof LastHttpContent) { - if (dataToCapture.contains(CaptureType.RESPONSE_CONTENT)) { - captureResponseContent(responseCaptureFilter.getHttpResponse(), responseCaptureFilter.getFullResponseContents()); + captureResponseSize(httpContent); } - harEntry.getResponse().setBodySize(responseBodySize.get()); - } + if (httpObject instanceof LastHttpContent) { + if (dataToCapture.contains(CaptureType.RESPONSE_CONTENT)) { + captureResponseContent(responseCaptureFilter.getHttpResponse(), responseCaptureFilter.getFullResponseContents()); + } + harEntry.getResponse().setBodySize(responseBodySize.get()); + } + httpObjectThreadLocal.set(httpObject); + } logFailedRequestIfRequired(harEntry.getRequest(), harEntry.getResponse()); return super.serverToProxyResponse(httpObject); @@ -307,6 +297,8 @@ else if (sendFinishedNanos > 0L && responseReceiveStartedNanos == 0L) { else if (responseReceiveStartedNanos > 0L) { harEntry.getTimings().setReceive(timeoutTimestampNanos - responseReceiveStartedNanos, TimeUnit.NANOSECONDS); } + + logFailedRequestIfRequired(harEntry.getRequest(), harEntry.getResponse()); } /** diff --git a/browsermob-dist/pom.xml b/browsermob-dist/pom.xml index 25ae96448..5aba96f02 100644 --- a/browsermob-dist/pom.xml +++ b/browsermob-dist/pom.xml @@ -4,7 +4,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.20-SNAPSHOT + 2.1.20 4.0.0 diff --git a/browsermob-legacy/pom.xml b/browsermob-legacy/pom.xml index 2b6696cd4..3fb44a08b 100644 --- a/browsermob-legacy/pom.xml +++ b/browsermob-legacy/pom.xml @@ -5,7 +5,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.20-SNAPSHOT + 2.1.20 4.0.0 @@ -23,7 +23,7 @@ org.apache.maven.plugins maven-surefire-plugin - -Xmx1g -XX:MaxPermSize=256m + -Xmx1g ${use.littleproxy} diff --git a/browsermob-rest/pom.xml b/browsermob-rest/pom.xml index f05d352c6..cc04ac796 100644 --- a/browsermob-rest/pom.xml +++ b/browsermob-rest/pom.xml @@ -5,7 +5,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.20-SNAPSHOT + 2.1.20 4.0.0 diff --git a/mitm/pom.xml b/mitm/pom.xml index eeef1dcab..70979319e 100644 --- a/mitm/pom.xml +++ b/mitm/pom.xml @@ -4,7 +4,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.20-SNAPSHOT + 2.1.20 4.0.0 diff --git a/pom.xml b/pom.xml index 83dc06f58..6330bedc4 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.lightbody.bmp browsermob-proxy - 2.1.20-SNAPSHOT + 2.1.20 browsermob-core browsermob-legacy @@ -146,7 +146,7 @@ maven-surefire-plugin 2.19.1 - -Xmx1g -XX:MaxPermSize=256m + -Xmx1g From abdc7f78669da48926ed4ff66d5b2c4d121dcd40 Mon Sep 17 00:00:00 2001 From: "kyrylo.bilchenko" Date: Fri, 29 Mar 2019 16:21:30 +0100 Subject: [PATCH 02/11] promote poms --- browsermob-core/pom.xml | 2 +- .../lightbody/bmp/core/har/HarRequest.java | 39 +++++++++++++++++++ .../bmp/filters/AutoBasicAuthFilter.java | 7 +--- .../bmp/filters/BlacklistFilter.java | 2 +- .../bmp/util/BrowserMobHttpUtil.java | 20 +++++----- .../proxy/dns/ChainedHostResolverTest.java | 2 +- browsermob-legacy/pom.xml | 6 +-- pom.xml | 2 +- 8 files changed, 58 insertions(+), 22 deletions(-) diff --git a/browsermob-core/pom.xml b/browsermob-core/pom.xml index 4c9bb2f0c..71a9cbb1d 100644 --- a/browsermob-core/pom.xml +++ b/browsermob-core/pom.xml @@ -14,7 +14,7 @@ BrowserMob Proxy Core (LittleProxy) Module - 7.6.16.v20140903 + 9.4.15.v20190215 diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/core/har/HarRequest.java b/browsermob-core/src/main/java/net/lightbody/bmp/core/har/HarRequest.java index 845c75780..4e549ad77 100644 --- a/browsermob-core/src/main/java/net/lightbody/bmp/core/har/HarRequest.java +++ b/browsermob-core/src/main/java/net/lightbody/bmp/core/har/HarRequest.java @@ -1,6 +1,8 @@ package net.lightbody.bmp.core.har; import com.fasterxml.jackson.annotation.JsonInclude; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -95,4 +97,41 @@ public void setComment(String comment) { this.comment = comment; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + HarRequest that = (HarRequest) o; + + return new EqualsBuilder() + .append(headersSize, that.headersSize) + .append(bodySize, that.bodySize) + .append(method, that.method) + .append(url, that.url) + .append(httpVersion, that.httpVersion) + .append(cookies, that.cookies) + .append(headers, that.headers) + .append(queryString, that.queryString) + .append(postData, that.postData) + .append(comment, that.comment) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(method) + .append(url) + .append(httpVersion) + .append(cookies) + .append(headers) + .append(queryString) + .append(postData) + .append(headersSize) + .append(bodySize) + .append(comment) + .toHashCode(); + } } diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/filters/AutoBasicAuthFilter.java b/browsermob-core/src/main/java/net/lightbody/bmp/filters/AutoBasicAuthFilter.java index 758f9bfaa..4cc840d97 100644 --- a/browsermob-core/src/main/java/net/lightbody/bmp/filters/AutoBasicAuthFilter.java +++ b/browsermob-core/src/main/java/net/lightbody/bmp/filters/AutoBasicAuthFilter.java @@ -1,10 +1,7 @@ package net.lightbody.bmp.filters; import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpObject; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.*; import org.littleshoot.proxy.impl.ProxyUtils; import java.util.Map; @@ -45,7 +42,7 @@ public HttpResponse clientToProxyRequest(HttpObject httpObject) { // if there is an entry in the credentials map matching this hostname, add the credentials to the request String base64CredentialsForHostname = credentialsByHostname.get(hostname); if (base64CredentialsForHostname != null) { - httpRequest.headers().add(HttpHeaders.Names.AUTHORIZATION, "Basic " + base64CredentialsForHostname); + httpRequest.headers().add(HttpHeaderNames.AUTHORIZATION, "Basic " + base64CredentialsForHostname); } } diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/filters/BlacklistFilter.java b/browsermob-core/src/main/java/net/lightbody/bmp/filters/BlacklistFilter.java index 239179b78..0eef83d36 100644 --- a/browsermob-core/src/main/java/net/lightbody/bmp/filters/BlacklistFilter.java +++ b/browsermob-core/src/main/java/net/lightbody/bmp/filters/BlacklistFilter.java @@ -39,7 +39,7 @@ public HttpResponse clientToProxyRequest(HttpObject httpObject) { if (entry.matches(url, httpRequest.method().name())) { HttpResponseStatus status = HttpResponseStatus.valueOf(entry.getStatusCode()); - HttpResponse resp = new DefaultFullHttpResponse(httpRequest.getProtocolVersion(), status); + HttpResponse resp = new DefaultFullHttpResponse(httpRequest.protocolVersion(), status); HttpUtil.setContentLength(resp, 0L); return resp; diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/util/BrowserMobHttpUtil.java b/browsermob-core/src/main/java/net/lightbody/bmp/util/BrowserMobHttpUtil.java index a9e00c5f8..282bf61b4 100644 --- a/browsermob-core/src/main/java/net/lightbody/bmp/util/BrowserMobHttpUtil.java +++ b/browsermob-core/src/main/java/net/lightbody/bmp/util/BrowserMobHttpUtil.java @@ -51,7 +51,7 @@ public class BrowserMobHttpUtil { * Likewise, special treatment of ISO-8859-1 has been removed from the * Accept-Charset header field. * - * + *

* Technically, we would have to determine the charset on a per-content-type basis, but generally speaking, UTF-8 is a * pretty safe default. (NOTE: In the previous HTTP/1.1 spec, section 3.7.1, the default charset was defined as ISO-8859-1.) */ @@ -118,7 +118,7 @@ public static byte[] decompressContents(byte[] fullMessage) throws Decompression * * @param fullMessage brotli byte stream to decompress * @return decompressed bytes - * @throws DecompressionException thrown if the fullMessage cannot be read or decompressed for any reason + * @throws DecompressionException thrown if the fullMessage cannot be read or decompressed for any reason */ public static byte[] decompressBrotliContents(byte[] fullMessage) throws DecompressionException { InputStream brotliReader = null; @@ -167,11 +167,11 @@ public static byte[] decompressBrotliContents(byte[] fullMessage) throws Decompr public static boolean hasTextualContent(String contentType) { return contentType != null && (contentType.startsWith("text/") || - contentType.startsWith("application/x-javascript") || - contentType.startsWith("application/javascript") || - contentType.startsWith("application/json") || - contentType.startsWith("application/xml") || - contentType.startsWith("application/xhtml+xml") + contentType.startsWith("application/x-javascript") || + contentType.startsWith("application/javascript") || + contentType.startsWith("application/json") || + contentType.startsWith("application/xml") || + contentType.startsWith("application/xhtml+xml") ); } @@ -222,8 +222,8 @@ public static Charset readCharsetInContentTypeHeader(String contentTypeHeader) t MediaType mediaType; try { - mediaType = MediaType.parse(contentTypeHeader); - } catch (IllegalArgumentException e) { + mediaType = MediaType.parse(contentTypeHeader); + } catch (java.lang.IllegalArgumentException e) { log.info("Unable to parse Content-Type header: {}. Content-Type header will be ignored.", contentTypeHeader, e); return null; } @@ -307,7 +307,7 @@ public static boolean isRedirect(HttpResponse httpResponse) { * parsing the hostname, but makes no guarantees. In general, it should be validated externally, if necessary. * * @param hostWithPort string containing a hostname and optional port - * @param portNumber port to remove from the string + * @param portNumber port to remove from the string * @return string with the specified port removed, or the original string if it did not contain the portNumber */ public static String removeMatchingPort(String hostWithPort, int portNumber) { diff --git a/browsermob-core/src/test/java/net/lightbody/bmp/proxy/dns/ChainedHostResolverTest.java b/browsermob-core/src/test/java/net/lightbody/bmp/proxy/dns/ChainedHostResolverTest.java index fbf09d63c..9415f8854 100644 --- a/browsermob-core/src/test/java/net/lightbody/bmp/proxy/dns/ChainedHostResolverTest.java +++ b/browsermob-core/src/test/java/net/lightbody/bmp/proxy/dns/ChainedHostResolverTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; diff --git a/browsermob-legacy/pom.xml b/browsermob-legacy/pom.xml index 3fb44a08b..f6c2153c0 100644 --- a/browsermob-legacy/pom.xml +++ b/browsermob-legacy/pom.xml @@ -13,7 +13,7 @@ BrowserMob Proxy Legacy (Jetty) Module - 7.6.16.v20140903 + 9.4.15.v20190215 true @@ -80,13 +80,13 @@ commons-io commons-io - 2.5 + 2.6 javax.servlet servlet-api - 2.5 + 4.0.1 diff --git a/pom.xml b/pom.xml index 6330bedc4..d3cc06e58 100644 --- a/pom.xml +++ b/pom.xml @@ -241,7 +241,7 @@ com.google.guava guava - 27.0.1-jre + 27.1-jre From b3908d8d2fa3d772b6c8fc0a05f9316e100fb6ea Mon Sep 17 00:00:00 2001 From: "kyrylo.bilchenko" Date: Fri, 29 Mar 2019 16:25:59 +0100 Subject: [PATCH 03/11] promote poms --- browsermob-legacy/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browsermob-legacy/pom.xml b/browsermob-legacy/pom.xml index f6c2153c0..edbdee544 100644 --- a/browsermob-legacy/pom.xml +++ b/browsermob-legacy/pom.xml @@ -86,7 +86,7 @@ javax.servlet servlet-api - 4.0.1 + 2.5 From 64536e359714835fcc4fb34263eca4a47072f64e Mon Sep 17 00:00:00 2001 From: "kyrylo.bilchenko" Date: Fri, 29 Mar 2019 16:31:02 +0100 Subject: [PATCH 04/11] promote poms --- .../java/net/lightbody/bmp/proxy/test/util/LocalServer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java b/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java index 58f93b8f4..5ae48be0f 100644 --- a/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java +++ b/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java @@ -5,9 +5,9 @@ import net.lightbody.bmp.proxy.test.servlet.JsonServlet; import net.lightbody.bmp.proxy.test.servlet.SetCookieServlet; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.GzipHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.handler.ResourceHandler; +import org.eclipse.jetty.server.handler.gzip.GzipHandler; import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.util.resource.Resource; import org.slf4j.Logger; @@ -63,7 +63,7 @@ public void start() { throw new RuntimeException("Could not start local Jetty server for tests", e); } - this.port = server.getConnectors()[0].getLocalPort(); + this.port = server.getURI().getPort(); started.set(true); } @@ -78,7 +78,7 @@ public int getPort() { } /** - * Forces the server to gzip all responses (see {@link org.eclipse.jetty.server.handler.GzipHandler} for response codes that will + * Forces the server to gzip all responses (see {@link org.eclipse.jetty.server.handler.gzip.GzipHandler} for response codes that will * be gzipped). */ public void forceGzip() { From f46b575e63708abaafc866049c737a4cce3fa9b8 Mon Sep 17 00:00:00 2001 From: "kyrylo.bilchenko" Date: Fri, 29 Mar 2019 16:55:27 +0100 Subject: [PATCH 05/11] revert jetty --- .../java/net/lightbody/bmp/filters/BlacklistFilter.java | 2 +- browsermob-legacy/pom.xml | 5 +++-- .../java/net/lightbody/bmp/proxy/test/util/LocalServer.java | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/filters/BlacklistFilter.java b/browsermob-core/src/main/java/net/lightbody/bmp/filters/BlacklistFilter.java index 0eef83d36..239179b78 100644 --- a/browsermob-core/src/main/java/net/lightbody/bmp/filters/BlacklistFilter.java +++ b/browsermob-core/src/main/java/net/lightbody/bmp/filters/BlacklistFilter.java @@ -39,7 +39,7 @@ public HttpResponse clientToProxyRequest(HttpObject httpObject) { if (entry.matches(url, httpRequest.method().name())) { HttpResponseStatus status = HttpResponseStatus.valueOf(entry.getStatusCode()); - HttpResponse resp = new DefaultFullHttpResponse(httpRequest.protocolVersion(), status); + HttpResponse resp = new DefaultFullHttpResponse(httpRequest.getProtocolVersion(), status); HttpUtil.setContentLength(resp, 0L); return resp; diff --git a/browsermob-legacy/pom.xml b/browsermob-legacy/pom.xml index edbdee544..5f3528c4a 100644 --- a/browsermob-legacy/pom.xml +++ b/browsermob-legacy/pom.xml @@ -1,5 +1,6 @@ - + jar @@ -13,7 +14,7 @@ BrowserMob Proxy Legacy (Jetty) Module - 9.4.15.v20190215 + 7.6.16.v20140903 true diff --git a/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java b/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java index 5ae48be0f..58f93b8f4 100644 --- a/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java +++ b/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java @@ -5,9 +5,9 @@ import net.lightbody.bmp.proxy.test.servlet.JsonServlet; import net.lightbody.bmp.proxy.test.servlet.SetCookieServlet; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.GzipHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.handler.ResourceHandler; -import org.eclipse.jetty.server.handler.gzip.GzipHandler; import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.util.resource.Resource; import org.slf4j.Logger; @@ -63,7 +63,7 @@ public void start() { throw new RuntimeException("Could not start local Jetty server for tests", e); } - this.port = server.getURI().getPort(); + this.port = server.getConnectors()[0].getLocalPort(); started.set(true); } @@ -78,7 +78,7 @@ public int getPort() { } /** - * Forces the server to gzip all responses (see {@link org.eclipse.jetty.server.handler.gzip.GzipHandler} for response codes that will + * Forces the server to gzip all responses (see {@link org.eclipse.jetty.server.handler.GzipHandler} for response codes that will * be gzipped). */ public void forceGzip() { From b03e808067b6ea4cfc511d150e710b566d229c0d Mon Sep 17 00:00:00 2001 From: "kyrylo.bilchenko" Date: Mon, 1 Apr 2019 14:24:22 +0200 Subject: [PATCH 06/11] One more part done --- .../filters/ClientRequestCaptureFilter.java | 9 +- .../bmp/filters/HarCaptureFilter.java | 37 +- browsermob-legacy/pom.xml | 6 +- .../jetty/jetty/servlet/ServletHandler.java | 1349 +++++++++-------- .../jetty/servlet/ServletHttpRequest.java | 862 ++++++----- .../jetty/servlet/ServletHttpResponse.java | 28 +- .../proxy/jetty/jetty/servlet/ServletIn.java | 68 +- .../proxy/jetty/jetty/servlet/ServletOut.java | 17 + .../java/net/lightbody/bmp/proxy/HarTest.java | 612 ++++---- .../bmp/proxy/MailingListIssuesTest.java | 7 +- .../bmp/proxy/test/util/LocalServer.java | 16 +- browsermob-rest/pom.xml | 10 +- .../bmp/proxy/guice/JettyServerProvider.java | 11 +- 13 files changed, 1590 insertions(+), 1442 deletions(-) diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/filters/ClientRequestCaptureFilter.java b/browsermob-core/src/main/java/net/lightbody/bmp/filters/ClientRequestCaptureFilter.java index d6bd1b58c..3315c0640 100644 --- a/browsermob-core/src/main/java/net/lightbody/bmp/filters/ClientRequestCaptureFilter.java +++ b/browsermob-core/src/main/java/net/lightbody/bmp/filters/ClientRequestCaptureFilter.java @@ -2,12 +2,7 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.HttpContent; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpObject; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.LastHttpContent; +import io.netty.handler.codec.http.*; import net.lightbody.bmp.util.BrowserMobHttpUtil; import org.littleshoot.proxy.HttpFiltersAdapter; @@ -60,7 +55,7 @@ public HttpResponse clientToProxyRequest(HttpObject httpObject) { if (httpContent instanceof LastHttpContent) { LastHttpContent lastHttpContent = (LastHttpContent) httpContent; - trailingHeaders = lastHttpContent .trailingHeaders(); + trailingHeaders = lastHttpContent.trailingHeaders(); } } diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java b/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java index 5feb037dd..7072bb984 100644 --- a/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java +++ b/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java @@ -36,7 +36,6 @@ public class HarCaptureFilter extends HttpsAwareFiltersAdapter { private static final Logger log = LoggerFactory.getLogger(HarCaptureFilter.class); private static final ThreadLocal statsDClient = new InheritableThreadLocal<>(); private static final ThreadLocal isAlreadyLoggedIn = InheritableThreadLocal.withInitial(() -> false); - private static final ThreadLocal httpObjectThreadLocal = new InheritableThreadLocal<>(); /** * The currently active HAR at the time the current request is received. @@ -239,32 +238,30 @@ public HttpResponse clientToProxyRequest(HttpObject httpObject) { public HttpObject serverToProxyResponse(HttpObject httpObject) { // if a ServerResponseCaptureFilter is configured, delegate to it to collect the server's response. if it is not // configured, we still need to capture basic information (timings, HTTP status, etc.), just not content. - if (Objects.isNull(httpObjectThreadLocal.get()) || httpObjectThreadLocal.get().hashCode() != httpObject.hashCode()) { - if (responseCaptureFilter != null) { - responseCaptureFilter.serverToProxyResponse(httpObject); - } - - if (httpObject instanceof HttpResponse) { - HttpResponse httpResponse = (HttpResponse) httpObject; + if (responseCaptureFilter != null) { + responseCaptureFilter.serverToProxyResponse(httpObject); + } - captureResponse(httpResponse); - } + if (httpObject instanceof HttpResponse) { + HttpResponse httpResponse = (HttpResponse) httpObject; - if (httpObject instanceof HttpContent) { - HttpContent httpContent = (HttpContent) httpObject; + captureResponse(httpResponse); + } - captureResponseSize(httpContent); - } + if (httpObject instanceof HttpContent) { + HttpContent httpContent = (HttpContent) httpObject; - if (httpObject instanceof LastHttpContent) { - if (dataToCapture.contains(CaptureType.RESPONSE_CONTENT)) { - captureResponseContent(responseCaptureFilter.getHttpResponse(), responseCaptureFilter.getFullResponseContents()); - } + captureResponseSize(httpContent); + } - harEntry.getResponse().setBodySize(responseBodySize.get()); + if (httpObject instanceof LastHttpContent) { + if (dataToCapture.contains(CaptureType.RESPONSE_CONTENT)) { + captureResponseContent(responseCaptureFilter.getHttpResponse(), responseCaptureFilter.getFullResponseContents()); } - httpObjectThreadLocal.set(httpObject); + + harEntry.getResponse().setBodySize(responseBodySize.get()); } + logFailedRequestIfRequired(harEntry.getRequest(), harEntry.getResponse()); return super.serverToProxyResponse(httpObject); diff --git a/browsermob-legacy/pom.xml b/browsermob-legacy/pom.xml index 5f3528c4a..a5711ec5e 100644 --- a/browsermob-legacy/pom.xml +++ b/browsermob-legacy/pom.xml @@ -14,7 +14,7 @@ BrowserMob Proxy Legacy (Jetty) Module - 7.6.16.v20140903 + 9.4.15.v20190215 true @@ -86,8 +86,8 @@ javax.servlet - servlet-api - 2.5 + javax.servlet-api + 4.0.1 diff --git a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHandler.java b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHandler.java index 220af438d..78414813c 100644 --- a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHandler.java +++ b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHandler.java @@ -30,6 +30,7 @@ import org.apache.commons.logging.Log; import javax.servlet.*; +import javax.servlet.descriptor.JspConfigDescriptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @@ -43,50 +44,52 @@ /* --------------------------------------------------------------------- */ -/** Servlet HttpHandler. + +/** + * Servlet HttpHandler. * This handler maps requests to servlets that implement the * javax.servlet.http.HttpServlet API. - *

+ *

* This handler does not implement the full J2EE features and is intended to * be used when a full web application is not required. Specifically filters * and request wrapping are not supported. - *

+ *

* If a SessionManager is not added to the handler before it is * initialized, then a HashSessionManager with a standard * java.util.Random generator is created. - *

- * @see net.lightbody.bmp.proxy.jetty.jetty.servlet.WebApplicationHandler - * @version $Id: ServletHandler.java,v 1.133 2006/03/15 14:43:00 gregwilkins Exp $ + *

+ * * @author Greg Wilkins + * @version $Id: ServletHandler.java,v 1.133 2006/03/15 14:43:00 gregwilkins Exp $ + * @see net.lightbody.bmp.proxy.jetty.jetty.servlet.WebApplicationHandler */ -public class ServletHandler extends Container implements HttpHandler -{ +public class ServletHandler extends Container implements HttpHandler { private static Log log = LogFactory.getLog(ServletHandler.class); /* ------------------------------------------------------------ */ - public static final String __DEFAULT_SERVLET="default"; - public static final String __J_S_CONTEXT_TEMPDIR="javax.servlet.context.tempdir"; - public static final String __J_S_ERROR_EXCEPTION="javax.servlet.error.exception"; - public static final String __J_S_ERROR_EXCEPTION_TYPE="javax.servlet.error.exception_type"; - public static final String __J_S_ERROR_MESSAGE="javax.servlet.error.message"; - public static final String __J_S_ERROR_REQUEST_URI="javax.servlet.error.request_uri"; - public static final String __J_S_ERROR_SERVLET_NAME="javax.servlet.error.servlet_name"; - public static final String __J_S_ERROR_STATUS_CODE="javax.servlet.error.status_code"; - + public static final String __DEFAULT_SERVLET = "default"; + public static final String __J_S_CONTEXT_TEMPDIR = "javax.servlet.context.tempdir"; + public static final String __J_S_ERROR_EXCEPTION = "javax.servlet.error.exception"; + public static final String __J_S_ERROR_EXCEPTION_TYPE = "javax.servlet.error.exception_type"; + public static final String __J_S_ERROR_MESSAGE = "javax.servlet.error.message"; + public static final String __J_S_ERROR_REQUEST_URI = "javax.servlet.error.request_uri"; + public static final String __J_S_ERROR_SERVLET_NAME = "javax.servlet.error.servlet_name"; + public static final String __J_S_ERROR_STATUS_CODE = "javax.servlet.error.status_code"; + /* ------------------------------------------------------------ */ - private static final boolean __Slosh2Slash=File.separatorChar=='\\'; - private static String __AllowString="GET, HEAD, POST, OPTIONS, TRACE"; + private static final boolean __Slosh2Slash = File.separatorChar == '\\'; + private static String __AllowString = "GET, HEAD, POST, OPTIONS, TRACE"; + - /* ------------------------------------------------------------ */ - private boolean _usingCookies=true; - private boolean _autoInitializeServlets=true; + private boolean _usingCookies = true; + private boolean _autoInitializeServlets = true; private String _name; - + /* ------------------------------------------------------------ */ - protected PathMap _servletMap=new PathMap(); - protected Map _nameMap=new HashMap(); - protected Map _attributes=new HashMap(3); + protected PathMap _servletMap = new PathMap(); + protected Map _nameMap = new HashMap(); + protected Map _attributes = new HashMap(3); protected String _formLoginPage; protected String _formErrorPage; protected SessionManager _sessionManager; @@ -97,830 +100,791 @@ public class ServletHandler extends Container implements HttpHandler protected transient HttpContext _httpContext; /* ------------------------------------------------------------ */ - /** Constructor. + + /** + * Constructor. */ - public ServletHandler() - { - _context=new Context(); + public ServletHandler() { + _context = new Context(); } /* ------------------------------------------------------------ */ - public void setName(String name) - { - _name=name; + public void setName(String name) { + _name = name; } - + /* ------------------------------------------------------------ */ - public String getName() - { - if (_name==null) - { - _name=this.getClass().getName(); + public String getName() { + if (_name == null) { + _name = this.getClass().getName(); if (!log.isDebugEnabled()) - _name=_name.substring(_name.lastIndexOf('.')+1); + _name = _name.substring(_name.lastIndexOf('.') + 1); } return _name; } - + /* ------------------------------------------------------------ */ - public HttpContext getHttpContext() - { + public HttpContext getHttpContext() { return _httpContext; } - + /* ------------------------------------------------------------ */ - public void initialize(HttpContext context) - { - SessionManager sessionManager=getSessionManager(); - + public void initialize(HttpContext context) { + SessionManager sessionManager = getSessionManager(); - if (_httpContext!=null&& _httpContext!=context) + + if (_httpContext != null && _httpContext != context) throw new IllegalStateException("Can't initialize handler for different context"); - _httpContext=context; - + _httpContext = context; + sessionManager.initialize(this); } /* ------------------------------------------------------------ */ public void formAuthInit(String formLoginPage, - String formErrorPage) - { - _formLoginPage=formLoginPage; - _formErrorPage=formErrorPage; - } - + String formErrorPage) { + _formLoginPage = formLoginPage; + _formErrorPage = formErrorPage; + } + /* ------------------------------------------------------------ */ - public void setSessionManager(SessionManager sm) - { + public void setSessionManager(SessionManager sm) { if (isStarted()) throw new IllegalStateException("Started"); - int mii=0; - boolean setMii=false; - - if ( _sessionManager!=null) - { - mii=_sessionManager.getMaxInactiveInterval(); - setMii=true; - if (getHttpContext()!=null) + int mii = 0; + boolean setMii = false; + + if (_sessionManager != null) { + mii = _sessionManager.getMaxInactiveInterval(); + setMii = true; + if (getHttpContext() != null) _sessionManager.initialize(null); removeComponent(_sessionManager); } - _sessionManager=sm; + _sessionManager = sm; - if (_sessionManager!=null) - { - if (getHttpContext()!=null) + if (_sessionManager != null) { + if (getHttpContext() != null) _sessionManager.initialize(this); if (setMii) _sessionManager.setMaxInactiveInterval(mii); addComponent(_sessionManager); - } - - _sessionManager=sm; + } + + _sessionManager = sm; } - + /* ------------------------------------------------------------ */ - public SessionManager getSessionManager() - { - if (_sessionManager==null) - { + public SessionManager getSessionManager() { + if (_sessionManager == null) { _sessionManager = new HashSessionManager(); addComponent(_sessionManager); } return _sessionManager; } - + /* ------------------------------------------------------------ */ - public ServletContext getServletContext() { return _context; } + public ServletContext getServletContext() { + return _context; + } /* ------------------------------------------------------------ */ - public PathMap getServletMap() { return _servletMap; } - + public PathMap getServletMap() { + return _servletMap; + } + /* ------------------------------------------------------------ */ - public boolean isUsingCookies() { return _usingCookies; } - + public boolean isUsingCookies() { + return _usingCookies; + } + /* ------------------------------------------------------------ */ - /** Set the dynamic servlet path. + + /** + * Set the dynamic servlet path. + * * @deprecated Use org.mortbay.jetty.servlet.Invoker */ - public void setDynamicServletPathSpec(String dynamicServletPathSpec) - { + public void setDynamicServletPathSpec(String dynamicServletPathSpec) { log.warn("setDynamicServletPathSpec is Deprecated."); } - + /* ------------------------------------------------------------ */ - /** Set dynamic servlet initial parameters. + + /** + * Set dynamic servlet initial parameters. + * * @deprecated Use org.mortbay.jetty.servlet.Invoker */ - public void setDynamicInitParams(Map initParams) - { + public void setDynamicInitParams(Map initParams) { log.warn("setDynamicInitParams is Deprecated."); } /* ------------------------------------------------------------ */ - /** Set serving dynamic system servlets. + + /** + * Set serving dynamic system servlets. + * * @deprecated Use org.mortbay.jetty.servlet.Invoker */ - public void setServeDynamicSystemServlets(boolean b) - { + public void setServeDynamicSystemServlets(boolean b) { log.warn("setServeDynamicSystemServlets is Deprecated."); } - + /* ------------------------------------------------------------ */ - public ClassLoader getClassLoader() - { + public ClassLoader getClassLoader() { return _loader; } /* ------------------------------------------------------------ */ - /** + + /** * @param uc If true, cookies are used for sessions */ - public void setUsingCookies(boolean uc) - { - _usingCookies=uc; + public void setUsingCookies(boolean uc) { + _usingCookies = uc; } /* ------------------------------------------------------------ */ public ServletHolder newServletHolder(String name, String servletClass, - String forcedPath) - { + String forcedPath) { if (_nameMap.containsKey(name)) - throw new IllegalArgumentException("Named servlet already exists: "+name); - - ServletHolder holder = new ServletHolder(this,name,servletClass,forcedPath); + throw new IllegalArgumentException("Named servlet already exists: " + name); + + ServletHolder holder = new ServletHolder(this, name, servletClass, forcedPath); addServletHolder(holder); - + return holder; } /* ------------------------------------------------------------ */ public ServletHolder newServletHolder(String name, - String servletClass) - { - return newServletHolder(name,servletClass,null); - } - + String servletClass) { + return newServletHolder(name, servletClass, null); + } + /* ------------------------------------------------------------ */ - public ServletHolder getServletHolder(String name) - { - return (ServletHolder)_nameMap.get(name); - } + public ServletHolder getServletHolder(String name) { + return (ServletHolder) _nameMap.get(name); + } /* ------------------------------------------------------------ */ - /** + + /** * Map a servlet to a pathSpec - * @param pathSpec The pathspec to map + * + * @param pathSpec The pathspec to map * @param servletName The name of the servlet, which must have already been added. * @return The servlet holder of the mapped servlet. */ public ServletHolder mapPathToServlet(String pathSpec, - String servletName) - { - ServletHolder holder =(ServletHolder)_nameMap.get(servletName); - - if (!pathSpec.startsWith("/") && !pathSpec.startsWith("*")) - { - log.warn("pathSpec should start with '/' or '*' : "+pathSpec); - pathSpec="/"+pathSpec; - } - - if (holder==null) - throw new IllegalArgumentException("Unknown servlet: "+servletName); - _servletMap.put(pathSpec,holder); + String servletName) { + ServletHolder holder = (ServletHolder) _nameMap.get(servletName); + + if (!pathSpec.startsWith("/") && !pathSpec.startsWith("*")) { + log.warn("pathSpec should start with '/' or '*' : " + pathSpec); + pathSpec = "/" + pathSpec; + } + + if (holder == null) + throw new IllegalArgumentException("Unknown servlet: " + servletName); + _servletMap.put(pathSpec, holder); return holder; } - + /* ------------------------------------------------------------ */ - /** Add a servlet. - * @param name The servlet name. - * @param pathSpec A path specification to map this servlet to. + + /** + * Add a servlet. + * + * @param name The servlet name. + * @param pathSpec A path specification to map this servlet to. * @param servletClass The class name of the servlet. - * @param forcedPath If non null, the request attribute - * javax.servlet.include.servlet_path will be set to this path before - * service is called. + * @param forcedPath If non null, the request attribute + * javax.servlet.include.servlet_path will be set to this path before + * service is called. * @return The ServletHolder for the servlet. */ public ServletHolder addServlet(String name, String pathSpec, String servletClass, - String forcedPath) - { + String forcedPath) { ServletHolder holder = getServletHolder(name); - if (holder==null) - holder = newServletHolder(name,servletClass,forcedPath); - mapPathToServlet(pathSpec,name); - if (isStarted() && !holder.isStarted()) - { - try{holder.start();} - catch(Exception e){log.warn(LogSupport.EXCEPTION,e);} + if (holder == null) + holder = newServletHolder(name, servletClass, forcedPath); + mapPathToServlet(pathSpec, name); + if (isStarted() && !holder.isStarted()) { + try { + holder.start(); + } catch (Exception e) { + log.warn(LogSupport.EXCEPTION, e); + } } return holder; } - + /* ------------------------------------------------------------ */ - /** Add a servlet. - * @param name The servlet name. - * @param pathSpec A path specification to map this servlet to. + + /** + * Add a servlet. + * + * @param name The servlet name. + * @param pathSpec A path specification to map this servlet to. * @param servletClass The class name of the servlet. * @return The ServletHolder for the servlet. */ public ServletHolder addServlet(String name, String pathSpec, - String servletClass) - { - return addServlet(name,pathSpec,servletClass,null); + String servletClass) { + return addServlet(name, pathSpec, servletClass, null); } - + /* ------------------------------------------------------------ */ + /** * Add a servlet instance to this handler and map it to a pathspec. - * @param pathSpec The pathmapping + * + * @param pathSpec The pathmapping * @param servletClass The class of the servlet * @return The created ServletHolder */ public ServletHolder addServlet(String pathSpec, - String servletClass) - { - return addServlet(servletClass,pathSpec,servletClass,null); + String servletClass) { + return addServlet(servletClass, pathSpec, servletClass, null); } - + /* ------------------------------------------------------------ */ + /** * Register an existing ServletHolder with this handler. + * * @param holder the ServletHolder to register. */ - public void addServletHolder(ServletHolder holder) - { + public void addServletHolder(ServletHolder holder) { ServletHolder existing = (ServletHolder) - _nameMap.get(holder.getName()); - if (existing==null) - _nameMap.put(holder.getName(),holder); - else if (existing!=holder) - throw new IllegalArgumentException("Holder already exists for name: "+holder.getName()); + _nameMap.get(holder.getName()); + if (existing == null) + _nameMap.put(holder.getName(), holder); + else if (existing != holder) + throw new IllegalArgumentException("Holder already exists for name: " + holder.getName()); addComponent(holder); } - + /* ------------------------------------------------------------ */ - public boolean isAutoInitializeServlets() - { + public boolean isAutoInitializeServlets() { return _autoInitializeServlets; } /* ------------------------------------------------------------ */ - public void setAutoInitializeServlets(boolean b) - { - _autoInitializeServlets=b; + public void setAutoInitializeServlets(boolean b) { + _autoInitializeServlets = b; } - + /* ----------------------------------------------------------------- */ protected synchronized void doStart() - throws Exception - { + throws Exception { if (isStarted()) return; - - _contextLog = LogFactory.getLog("net.lightbody.bmp.proxy.jetty.jetty.context."+getHttpContext().getHttpContextName()); - - if (_contextLog==null) - _contextLog=log; - - if (_sessionManager!=null) + + _contextLog = LogFactory.getLog("net.lightbody.bmp.proxy.jetty.jetty.context." + getHttpContext().getHttpContextName()); + + if (_contextLog == null) + _contextLog = log; + + if (_sessionManager != null) _sessionManager.start(); - + // Initialize classloader - _loader=getHttpContext().getClassLoader(); + _loader = getHttpContext().getClassLoader(); if (_autoInitializeServlets) initializeServlets(); - } - + } + /* ------------------------------------------------------------ */ - /** Get Servlets. + + /** + * Get Servlets. + * * @return Array of defined servlets */ - public ServletHolder[] getServlets() - { + public ServletHolder[] getServlets() { // Sort and Initialize servlets HashSet holder_set = new HashSet(_nameMap.size()); holder_set.addAll(_nameMap.values()); - ServletHolder holders [] = (ServletHolder []) - holder_set.toArray(new ServletHolder [holder_set.size()]); - java.util.Arrays.sort (holders); + ServletHolder[] holders = (ServletHolder[]) + holder_set.toArray(new ServletHolder[holder_set.size()]); + java.util.Arrays.sort(holders); return holders; } - + /* ------------------------------------------------------------ */ - /** Initialize load-on-startup servlets. + + /** + * Initialize load-on-startup servlets. * Called automatically from start if autoInitializeServlet is true. */ public void initializeServlets() - throws Exception - { + throws Exception { MultiException mx = new MultiException(); - + // Sort and Initialize servlets ServletHolder[] holders = getServlets(); - for (int i=0; i0;) - { - try - { + for (int i = holders.length; i-- > 0; ) { + try { if (holders[i].isStarted()) holders[i].stop(); + } catch (Exception e) { + log.warn(LogSupport.EXCEPTION, e); } - catch(Exception e){log.warn(LogSupport.EXCEPTION,e);} } - + // Stop the session manager _sessionManager.stop(); _attributes.clear(); - _loader=null; + _loader = null; } /* ------------------------------------------------------------ */ - public HttpSession getHttpSession(String id) - { + public HttpSession getHttpSession(String id) { return _sessionManager.getHttpSession(id); } - + /* ------------------------------------------------------------ */ - public HttpSession newHttpSession(HttpServletRequest request) - { + public HttpSession newHttpSession(HttpServletRequest request) { return _sessionManager.newHttpSession(request); } /* ------------------------------------------------------------ */ + /** * Set the session timeout interval in seconds. + * * @param seconds the length of the session timeout interval in seconds. */ - public void setSessionInactiveInterval(int seconds) - { + public void setSessionInactiveInterval(int seconds) { _sessionManager.setMaxInactiveInterval(seconds); } /* ----------------------------------------------------------------- */ - /** Handle request. + + /** + * Handle request. + * * @param pathInContext * @param pathParams * @param httpRequest - * @param httpResponse - * @exception IOException + * @param httpResponse + * @throws IOException */ public void handle(String pathInContext, String pathParams, HttpRequest httpRequest, HttpResponse httpResponse) - throws IOException - { + throws IOException { if (!isStarted()) return; - + // Handle TRACE - if (HttpRequest.__TRACE.equals(httpRequest.getMethod())) - { - handleTrace(httpRequest,httpResponse); + if (HttpRequest.__TRACE.equals(httpRequest.getMethod())) { + handleTrace(httpRequest, httpResponse); return; } // Look for existing request/response objects (from enterScope call) ServletHttpRequest request = (ServletHttpRequest) httpRequest.getWrapper(); ServletHttpResponse response = (ServletHttpResponse) httpResponse.getWrapper(); - if (request==null) - { + if (request == null) { // Not in ServletHttpContext, but bumble on anyway - request = new ServletHttpRequest(this,pathInContext,httpRequest); - response = new ServletHttpResponse(request,httpResponse); + request = new ServletHttpRequest(this, pathInContext, httpRequest); + response = new ServletHttpResponse(request, httpResponse); httpRequest.setWrapper(request); httpResponse.setWrapper(response); - } - else - { - request.recycle(this,pathInContext); + } else { + request.recycle(this, pathInContext); response.recycle(); } - + // Look for the servlet - Map.Entry servlet=getHolderEntry(pathInContext); - ServletHolder servletHolder=servlet==null?null:(ServletHolder)servlet.getValue(); - if(log.isDebugEnabled())log.debug("servlet="+servlet); - - try - { + Map.Entry servlet = getHolderEntry(pathInContext); + ServletHolder servletHolder = servlet == null ? null : (ServletHolder) servlet.getValue(); + if (log.isDebugEnabled()) log.debug("servlet=" + servlet); + + try { // Adjust request paths - if (servlet!=null) - { - String servletPathSpec=(String)servlet.getKey(); - request.setServletPaths(PathMap.pathMatch(servletPathSpec,pathInContext), - PathMap.pathInfo(servletPathSpec,pathInContext), - servletHolder); + if (servlet != null) { + String servletPathSpec = (String) servlet.getKey(); + request.setServletPaths(PathMap.pathMatch(servletPathSpec, pathInContext), + PathMap.pathInfo(servletPathSpec, pathInContext), + servletHolder); } - + // Handle the session ID request.setRequestedSessionId(pathParams); - HttpSession session=request.getSession(false); - if (session!=null) - ((SessionManager.Session)session).access(); - if(log.isDebugEnabled())log.debug("session="+session); - + HttpSession session = request.getSession(false); + if (session != null) + ((SessionManager.Session) session).access(); + if (log.isDebugEnabled()) log.debug("session=" + session); + // Do that funky filter and servlet thang! - if (servletHolder!=null) - dispatch(pathInContext,request,response,servletHolder, Dispatcher.__REQUEST); - } - catch(Exception e) - { - log.debug(LogSupport.EXCEPTION,e); - - Throwable th=e; - while (th instanceof ServletException) - { + if (servletHolder != null) + dispatch(pathInContext, request, response, servletHolder, Dispatcher.__REQUEST); + } catch (Exception e) { + log.debug(LogSupport.EXCEPTION, e); + + Throwable th = e; + while (th instanceof ServletException) { log.warn(LogSupport.EXCEPTION, th); - Throwable cause=((ServletException)th).getRootCause(); - if (cause==th || cause==null) + Throwable cause = ((ServletException) th).getRootCause(); + if (cause == th || cause == null) break; - th=cause; + th = cause; } - + if (th instanceof HttpException) - throw (HttpException)th; + throw (HttpException) th; if (th instanceof EOFException) - throw (IOException)th; - else if (log.isDebugEnabled() || !( th instanceof java.io.IOException)) - { - if (_contextLog!=null) - { - if (th instanceof RuntimeException) - _contextLog.error(httpRequest.getURI()+": ",th); + throw (IOException) th; + else if (log.isDebugEnabled() || !(th instanceof java.io.IOException)) { + if (_contextLog != null) { + if (th instanceof RuntimeException) + _contextLog.error(httpRequest.getURI() + ": ", th); else - _contextLog.warn(httpRequest.getURI()+": ",th); + _contextLog.warn(httpRequest.getURI() + ": ", th); } - - if(log.isDebugEnabled()) - { - if (th instanceof RuntimeException) - log.error(httpRequest.getURI()+": ",th); + + if (log.isDebugEnabled()) { + if (th instanceof RuntimeException) + log.error(httpRequest.getURI() + ": ", th); else - log.warn(httpRequest.getURI()+": ",th); + log.warn(httpRequest.getURI() + ": ", th); log.debug(httpRequest); } } - + httpResponse.getHttpConnection().forceClose(); - if (!httpResponse.isCommitted()) - { - request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION_TYPE,th.getClass()); - request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION,th); - if (th instanceof UnavailableException) - { - UnavailableException ue = (UnavailableException)th; + if (!httpResponse.isCommitted()) { + request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION_TYPE, th.getClass()); + request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION, th); + if (th instanceof UnavailableException) { + UnavailableException ue = (UnavailableException) th; if (ue.isPermanent()) - response.sendError(HttpResponse.__404_Not_Found,e.getMessage()); + response.sendError(HttpResponse.__404_Not_Found, e.getMessage()); else - response.sendError(HttpResponse.__503_Service_Unavailable,e.getMessage()); - } - else - response.sendError(HttpResponse.__500_Internal_Server_Error,e.getMessage()); - } - else - if(log.isDebugEnabled())log.debug("Response already committed for handling "+th); - } - catch(Error e) - { - log.warn("Error for "+httpRequest.getURI(),e); - if(log.isDebugEnabled())log.debug(httpRequest); - + response.sendError(HttpResponse.__503_Service_Unavailable, e.getMessage()); + } else + response.sendError(HttpResponse.__500_Internal_Server_Error, e.getMessage()); + } else if (log.isDebugEnabled()) log.debug("Response already committed for handling " + th); + } catch (Error e) { + log.warn("Error for " + httpRequest.getURI(), e); + if (log.isDebugEnabled()) log.debug(httpRequest); + httpResponse.getHttpConnection().forceClose(); - if (!httpResponse.isCommitted()) - { - request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION_TYPE,e.getClass()); - request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION,e); + if (!httpResponse.isCommitted()) { + request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION_TYPE, e.getClass()); + request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION, e); response.sendError(HttpResponse.__500_Internal_Server_Error, - e.getMessage()); - } - else - if(log.isDebugEnabled())log.debug("Response already committed for handling ",e); - } - finally - { - if (servletHolder!=null && response!=null) - { + e.getMessage()); + } else if (log.isDebugEnabled()) log.debug("Response already committed for handling ", e); + } finally { + if (servletHolder != null && response != null) { response.complete(); } } } /* ------------------------------------------------------------ */ - /** Dispatch to a servletHolder. + + /** + * Dispatch to a servletHolder. * This method may be specialized to insert extra handling in the * dispatch of a request to a specific servlet. This is used by * WebApplicatonHandler to implement dispatched filters. * The default implementation simply calls * ServletHolder.handle(request,response) + * * @param pathInContext The path used to select the servlet holder. - * @param request - * @param response - * @param servletHolder - * @param type the type of dispatch as defined in the Dispatcher class. - * @exception ServletException - * @exception UnavailableException - * @exception IOException + * @param request + * @param response + * @param servletHolder + * @param type the type of dispatch as defined in the Dispatcher class. + * @throws ServletException + * @throws IOException */ protected void dispatch(String pathInContext, HttpServletRequest request, HttpServletResponse response, - ServletHolder servletHolder, + ServletHolder servletHolder, int type) - throws ServletException, - UnavailableException, - IOException - { - servletHolder.handle(request,response); + throws ServletException, + IOException { + servletHolder.handle(request, response); } - - + + /* ------------------------------------------------------------ */ - /** ServletHolder matching path. + + /** + * ServletHolder matching path. + * * @param pathInContext Path within context. * @return PathMap Entries pathspec to ServletHolder */ - public Map.Entry getHolderEntry(String pathInContext) - { + public Map.Entry getHolderEntry(String pathInContext) { return _servletMap.getMatch(pathInContext); } - + /* ------------------------------------------------------------ */ - public Set getResourcePaths(String uriInContext) - { - try - { - uriInContext=URI.canonicalPath(uriInContext); - if (uriInContext==null) + public Set getResourcePaths(String uriInContext) { + try { + uriInContext = URI.canonicalPath(uriInContext); + if (uriInContext == null) return Collections.EMPTY_SET; - Resource resource=getHttpContext().getResource(uriInContext); - if (resource==null || !resource.isDirectory()) + Resource resource = getHttpContext().getResource(uriInContext); + if (resource == null || !resource.isDirectory()) return Collections.EMPTY_SET; - String[] contents=resource.list(); - if (contents==null || contents.length==0) + String[] contents = resource.list(); + if (contents == null || contents.length == 0) return Collections.EMPTY_SET; - HashSet set = new HashSet(contents.length*2); - for (int i=0;i0) - { - query=uriInContext.substring(q+1); - uriInContext=uriInContext.substring(0,q); + + try { + String query = null; + int q = 0; + if ((q = uriInContext.indexOf('?')) > 0) { + query = uriInContext.substring(q + 1); + uriInContext = uriInContext.substring(0, q); } - if ((q=uriInContext.indexOf(';'))>0) - uriInContext=uriInContext.substring(0,q); + if ((q = uriInContext.indexOf(';')) > 0) + uriInContext = uriInContext.substring(0, q); - String pathInContext=URI.canonicalPath(URI.decodePath(uriInContext)); - Map.Entry entry=getHolderEntry(pathInContext); - if (entry!=null) + String pathInContext = URI.canonicalPath(URI.decodePath(uriInContext)); + Map.Entry entry = getHolderEntry(pathInContext); + if (entry != null) return new Dispatcher(ServletHandler.this, - uriInContext, - pathInContext, - query, - entry); - } - catch(Exception e) - { - LogSupport.ignore(log,e); + uriInContext, + pathInContext, + query, + entry); + } catch (Exception e) { + LogSupport.ignore(log, e); } return null; } /* ------------------------------------------------------------ */ - /** Get Named dispatcher. + + /** + * Get Named dispatcher. + * * @param name The name of the servlet. If null or empty string, the - * containers default servlet is returned. + * containers default servlet is returned. * @return Request dispatcher for the named servlet. */ - public RequestDispatcher getNamedDispatcher(String name) - { - if (name == null || name.length()==0) - name=__DEFAULT_SERVLET; - - try { return new Dispatcher(ServletHandler.this,name); } - catch(Exception e) {LogSupport.ignore(log,e);} - + public RequestDispatcher getNamedDispatcher(String name) { + if (name == null || name.length() == 0) + name = __DEFAULT_SERVLET; + + try { + return new Dispatcher(ServletHandler.this, name); + } catch (Exception e) { + LogSupport.ignore(log, e); + } + return null; } - /* ------------------------------------------------------------ */ protected void notFound(HttpServletRequest request, - HttpServletResponse response) - throws IOException - { - if(log.isDebugEnabled())log.debug("Not Found "+request.getRequestURI()); - String method=request.getMethod(); - + HttpServletResponse response) + throws IOException { + if (log.isDebugEnabled()) log.debug("Not Found " + request.getRequestURI()); + String method = request.getMethod(); + // Not found special requests. - if (method.equals(HttpRequest.__GET) || - method.equals(HttpRequest.__HEAD) || - method.equals(HttpRequest.__POST)) - { + if (method.equals(HttpRequest.__GET) || + method.equals(HttpRequest.__HEAD) || + method.equals(HttpRequest.__POST)) { response.sendError(HttpResponse.__404_Not_Found); - } - else if (method.equals(HttpRequest.__TRACE)) - handleTrace(request,response); + } else if (method.equals(HttpRequest.__TRACE)) + handleTrace(request, response); else if (method.equals(HttpRequest.__OPTIONS)) - handleOptions(request,response); - else - { + handleOptions(request, response); + else { // Unknown METHOD - response.setHeader(HttpFields.__Allow,__AllowString); + response.setHeader(HttpFields.__Allow, __AllowString); response.sendError(HttpResponse.__405_Method_Not_Allowed); } } - + /* ------------------------------------------------------------ */ protected void handleTrace(HttpServletRequest request, - HttpServletResponse response) - throws IOException - { + HttpServletResponse response) + throws IOException { response.setHeader(HttpFields.__ContentType, - HttpFields.__MessageHttp); - OutputStream out = response.getOutputStream(); - ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(); - writer.write(request.toString()); - writer.flush(); - response.setIntHeader(HttpFields.__ContentLength,writer.size()); - writer.writeTo(out); - out.flush(); + HttpFields.__MessageHttp); + try (ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(); + OutputStream out = response.getOutputStream()) { + writer.write(request.toString()); + writer.flush(); + response.setIntHeader(HttpFields.__ContentLength, writer.size()); + writer.writeTo(out); + out.flush(); + } } - + /* ------------------------------------------------------------ */ protected void handleOptions(HttpServletRequest request, - HttpServletResponse response) - throws IOException - { + HttpServletResponse response) + throws IOException { // Handle OPTIONS request for entire server - if ("*".equals(request.getRequestURI())) - { + if ("*".equals(request.getRequestURI())) { // 9.2 - response.setIntHeader(HttpFields.__ContentLength,0); - response.setHeader(HttpFields.__Allow,__AllowString); + response.setIntHeader(HttpFields.__ContentLength, 0); + response.setHeader(HttpFields.__Allow, __AllowString); response.flushBuffer(); - } - else + } else response.sendError(HttpResponse.__404_Not_Found); } /* ------------------------------------------------------------ */ - public String getErrorPage(int status,ServletHttpRequest request) - { + public String getErrorPage(int status, ServletHttpRequest request) { return null; } - + /* ------------------------------------------------------------ */ - /** Get context attribute. + + /** + * Get context attribute. * Tries ServletHandler attributes and then delegated to HttpContext. + * * @param name attribute name. * @return attribute */ - protected Object getContextAttribute(String name) - { - if (ServletHandler.__J_S_CONTEXT_TEMPDIR.equals(name)) - { + protected Object getContextAttribute(String name) { + if (ServletHandler.__J_S_CONTEXT_TEMPDIR.equals(name)) { // Initialize temporary directory Object t = getHttpContext().getAttribute(ServletHandler.__J_S_CONTEXT_TEMPDIR); if (t instanceof File) - return (File)t; - + return t; + return getHttpContext().getTempDirectory(); } @@ -930,16 +894,17 @@ protected Object getContextAttribute(String name) } /* ------------------------------------------------------------ */ - /** Get context attribute names. + + /** + * Get context attribute names. * Combines ServletHandler and HttpContext attributes. */ - protected Enumeration getContextAttributeNames() - { - if (_attributes.size()==0) + protected Enumeration getContextAttributeNames() { + if (_attributes.size() == 0) return getHttpContext().getAttributeNames(); - HashSet set=new HashSet(_attributes.keySet()); - Enumeration e=getHttpContext().getAttributeNames(); - while(e.hasMoreElements()) + HashSet set = new HashSet(_attributes.keySet()); + Enumeration e = getHttpContext().getAttributeNames(); + while (e.hasMoreElements()) set.add(e.nextElement()); return Collections.enumeration(set); } @@ -948,290 +913,450 @@ protected Enumeration getContextAttributeNames() /* Set a Servlet context attribute. * Servlet Context attributes may hide HttpContext attributes. */ - protected void setContextAttribute(String name, Object value) - { - _attributes.put(name,value); + protected void setContextAttribute(String name, Object value) { + _attributes.put(name, value); } - + /* ------------------------------------------------------------ */ /* Remove a Servlet context attribute. * Servlet Context attributes may hide HttpContext attributes. */ - protected void removeContextAttribute(String name) - { + protected void removeContextAttribute(String name) { _attributes.remove(name); } - + /* ----------------------------------------------------------------- */ public void handleTrace(HttpRequest request, HttpResponse response) - throws IOException - { - boolean trace=getHttpContext().getHttpServer().getTrace(); - + throws IOException { + boolean trace = getHttpContext().getHttpServer().getTrace(); + // Handle TRACE by returning request header response.setField(HttpFields.__ContentType, - HttpFields.__MessageHttp); - if (trace) - { + HttpFields.__MessageHttp); + if (trace) { OutputStream out = response.getOutputStream(); ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(); writer.write(request.toString()); writer.flush(); - response.setIntField(HttpFields.__ContentLength,writer.size()); + response.setIntField(HttpFields.__ContentLength, writer.size()); writer.writeTo(out); out.flush(); } request.setHandled(true); } - + /* ----------------------------------------------------------------- */ - public void destroy() - { + public void destroy() { Iterator iter = _nameMap.values().iterator(); - while (iter.hasNext()) - { - Object sh=iter.next(); + while (iter.hasNext()) { + Object sh = iter.next(); iter.remove(); removeComponent(sh); } - - if (_sessionManager!=null) + + if (_sessionManager != null) removeComponent(_sessionManager); - _sessionManager=null; - _context=null; + _sessionManager = null; + _context = null; super.destroy(); } - + /* ----------------------------------------------------------------- */ - protected void finalize() throws Throwable - { + protected void finalize() throws Throwable { destroy(); } - + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ - class Context implements ServletContext - { + class Context implements ServletContext { @Override public String getContextPath() { return null; } /* -------------------------------------------------------- */ - ServletHandler getServletHandler() - { + ServletHandler getServletHandler() { return ServletHandler.this; } - + /* -------------------------------------------------------- */ - public ServletContext getContext(String uri) - { - ServletHandler handler= (ServletHandler) - getHttpContext().getHttpServer() - .findHandler(net.lightbody.bmp.proxy.jetty.jetty.servlet.ServletHandler.class, - uri, - getHttpContext().getVirtualHosts()); - if (handler!=null) + public ServletContext getContext(String uri) { + ServletHandler handler = (ServletHandler) + getHttpContext().getHttpServer() + .findHandler(net.lightbody.bmp.proxy.jetty.jetty.servlet.ServletHandler.class, + uri, + getHttpContext().getVirtualHosts()); + if (handler != null) return handler.getServletContext(); return null; } /* ------------------------------------------------------------ */ - public int getMajorVersion() - { + public int getMajorVersion() { return 2; } /* ------------------------------------------------------------ */ - public int getMinorVersion() - { + public int getMinorVersion() { return 4; } + @Override + public int getEffectiveMajorVersion() { + return 0; + } + + @Override + public int getEffectiveMinorVersion() { + return 0; + } + /* ------------------------------------------------------------ */ - public String getMimeType(String file) - { + public String getMimeType(String file) { return getHttpContext().getMimeByExtension(file); } /* ------------------------------------------------------------ */ - public Set getResourcePaths(String uriInContext) - { + public Set getResourcePaths(String uriInContext) { return ServletHandler.this.getResourcePaths(uriInContext); } /* ------------------------------------------------------------ */ public URL getResource(String uriInContext) - throws MalformedURLException - { + throws MalformedURLException { return ServletHandler.this.getResource(uriInContext); } /* ------------------------------------------------------------ */ - public InputStream getResourceAsStream(String uriInContext) - { + public InputStream getResourceAsStream(String uriInContext) { return ServletHandler.this.getResourceAsStream(uriInContext); } /* ------------------------------------------------------------ */ - public String getRealPath(String path) - { + public String getRealPath(String path) { return ServletHandler.this.getRealPath(path); } /* ------------------------------------------------------------ */ - public RequestDispatcher getRequestDispatcher(String uriInContext) - { + public RequestDispatcher getRequestDispatcher(String uriInContext) { return ServletHandler.this.getRequestDispatcher(uriInContext); } /* ------------------------------------------------------------ */ - public RequestDispatcher getNamedDispatcher(String name) - { + public RequestDispatcher getNamedDispatcher(String name) { return ServletHandler.this.getNamedDispatcher(name); } - + /* ------------------------------------------------------------ */ + /** - * @deprecated + * @deprecated */ - public Servlet getServlet(String name) - { + public Servlet getServlet(String name) { return null; } /* ------------------------------------------------------------ */ + /** - * @deprecated + * @deprecated */ - public Enumeration getServlets() - { + public Enumeration getServlets() { return Collections.enumeration(Collections.EMPTY_LIST); } /* ------------------------------------------------------------ */ + /** - * @deprecated + * @deprecated */ - public Enumeration getServletNames() - { + public Enumeration getServletNames() { return Collections.enumeration(Collections.EMPTY_LIST); } - + /* ------------------------------------------------------------ */ - /** Servlet Log. + + /** + * Servlet Log. * Log message to servlet log. Use either the system log or a * LogSinkset via the context attribute * org.mortbay.jetty.servlet.Context.LogSink - * @param msg + * + * @param msg */ - public void log(String msg) - { + public void log(String msg) { _contextLog.info(msg); } /* ------------------------------------------------------------ */ + /** * @deprecated As of Java Servlet API 2.1, use - * {@link #log(String message, Throwable throwable)} - * instead. + * {@link #log(String message, Throwable throwable)} + * instead. */ - public void log(Exception e, String msg) - { - _contextLog.warn(msg,e); + public void log(Exception e, String msg) { + _contextLog.warn(msg, e); } /* ------------------------------------------------------------ */ - public void log(String msg, Throwable th) - { - _contextLog.warn(msg,th); + public void log(String msg, Throwable th) { + _contextLog.warn(msg, th); } /* ------------------------------------------------------------ */ - public String getServerInfo() - { + public String getServerInfo() { return Version.getImplVersion(); } /* ------------------------------------------------------------ */ - /** Get context init parameter. + + /** + * Get context init parameter. * Delegated to HttpContext. + * * @param param param name * @return param value or null */ - public String getInitParameter(String param) - { + public String getInitParameter(String param) { return getHttpContext().getInitParameter(param); } /* ------------------------------------------------------------ */ - /** Get context init parameter names. + + /** + * Get context init parameter names. * Delegated to HttpContext. + * * @return Enumeration of names */ - public Enumeration getInitParameterNames() - { + public Enumeration getInitParameterNames() { return getHttpContext().getInitParameterNames(); } - + @Override + public boolean setInitParameter(String s, String s1) { + return false; + } + + /* ------------------------------------------------------------ */ - /** Get context attribute. + + /** + * Get context attribute. * Tries ServletHandler attributes and then delegated to HttpContext. + * * @param name attribute name. * @return attribute */ - public Object getAttribute(String name) - { + public Object getAttribute(String name) { return getContextAttribute(name); } /* ------------------------------------------------------------ */ - /** Get context attribute names. + + /** + * Get context attribute names. * Combines ServletHandler and HttpContext attributes. */ - public Enumeration getAttributeNames() - { + public Enumeration getAttributeNames() { return getContextAttributeNames(); } /* ------------------------------------------------------------ */ - /** Set context attribute names. + + /** + * Set context attribute names. * Sets the ServletHandler attributes and may hide HttpContext attributes. - * @param name attribute name. + * + * @param name attribute name. * @param value attribute value */ - public void setAttribute(String name, Object value) - { + public void setAttribute(String name, Object value) { setContextAttribute(name, value); } /* ------------------------------------------------------------ */ - /** Remove context attribute. + + /** + * Remove context attribute. * Puts a null into the ServletHandler attributes and may hide a HttpContext attribute. + * * @param name attribute name. */ - public void removeAttribute(String name) - { + public void removeAttribute(String name) { removeContextAttribute(name); } - + /* ------------------------------------------------------------ */ - public String getServletContextName() - { + public String getServletContextName() { if (getHttpContext() instanceof WebApplicationContext) - return ((WebApplicationContext)getHttpContext()).getDisplayName(); + return ((WebApplicationContext) getHttpContext()).getDisplayName(); + return null; + } + + @Override + public ServletRegistration.Dynamic addServlet(String s, String s1) { + return null; + } + + @Override + public ServletRegistration.Dynamic addServlet(String s, Servlet servlet) { + return null; + } + + @Override + public ServletRegistration.Dynamic addServlet(String s, Class aClass) { + return null; + } + + @Override + public ServletRegistration.Dynamic addJspFile(String s, String s1) { + return null; + } + + @Override + public T createServlet(Class aClass) throws ServletException { + return null; + } + + @Override + public ServletRegistration getServletRegistration(String s) { + return null; + } + + @Override + public Map getServletRegistrations() { + return null; + } + + @Override + public FilterRegistration.Dynamic addFilter(String s, String s1) { + return null; + } + + @Override + public FilterRegistration.Dynamic addFilter(String s, Filter filter) { + return null; + } + + @Override + public FilterRegistration.Dynamic addFilter(String s, Class aClass) { return null; } + @Override + public T createFilter(Class aClass) throws ServletException { + return null; + } + + @Override + public FilterRegistration getFilterRegistration(String s) { + return null; + } + + @Override + public Map getFilterRegistrations() { + return null; + } + + @Override + public SessionCookieConfig getSessionCookieConfig() { + return null; + } + + @Override + public void setSessionTrackingModes(Set set) { + + } + + @Override + public Set getDefaultSessionTrackingModes() { + return null; + } + + @Override + public Set getEffectiveSessionTrackingModes() { + return null; + } + + @Override + public void addListener(String s) { + + } + + @Override + public void addListener(T t) { + + } + + @Override + public void addListener(Class aClass) { + + } + + @Override + public T createListener(Class aClass) throws ServletException { + return null; + } + + @Override + public JspConfigDescriptor getJspConfigDescriptor() { + return null; + } + + @Override + public ClassLoader getClassLoader() { + return null; + } + + @Override + public void declareRoles(String... strings) { + + } + + @Override + public String getVirtualServerName() { + return null; + } + + @Override + public int getSessionTimeout() { + return 0; + } + + @Override + public void setSessionTimeout(int i) { + + } + + @Override + public String getRequestCharacterEncoding() { + return null; + } + + @Override + public void setRequestCharacterEncoding(String s) { + + } + + @Override + public String getResponseCharacterEncoding() { + return null; + } + + @Override + public void setResponseCharacterEncoding(String s) { + + } + /* ------------------------------------------------------------ */ - public String toString() - { - return "ServletContext["+getHttpContext()+"]"; + public String toString() { + return "ServletContext[" + getHttpContext() + "]"; } - } + } } diff --git a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHttpRequest.java b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHttpRequest.java index 97b2f45aa..9a6cc4f02 100644 --- a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHttpRequest.java +++ b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHttpRequest.java @@ -25,491 +25,437 @@ import net.lightbody.bmp.proxy.jetty.util.*; import org.apache.commons.logging.Log; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletRequestWrapper; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; +import javax.servlet.*; +import javax.servlet.http.*; +import java.io.*; import java.security.Principal; import java.util.*; /* ------------------------------------------------------------ */ -/** Servlet Request Wrapper. + +/** + * Servlet Request Wrapper. * This class wraps a Jetty HTTP request as a 2.2 Servlet * request. - *

+ *

* Note that this wrapper is not synchronized and if a request is to * be operated on by multiple threads, then higher level * synchronizations may be required. - * - * @version $Id: ServletHttpRequest.java,v 1.65 2005/08/13 00:01:27 gregwilkins Exp $ + * * @author Greg Wilkins (gregw) + * @version $Id: ServletHttpRequest.java,v 1.65 2005/08/13 00:01:27 gregwilkins Exp $ */ public class ServletHttpRequest - implements HttpServletRequest -{ + implements HttpServletRequest { private static Log log = LogFactory.getLog(ServletHttpRequest.class); /* -------------------------------------------------------------- */ public static final String - __SESSIONID_NOT_CHECKED = "not checked", - __SESSIONID_URL = "url", - __SESSIONID_COOKIE = "cookie", - __SESSIONID_NONE = "none"; + __SESSIONID_NOT_CHECKED = "not checked", + __SESSIONID_URL = "url", + __SESSIONID_COOKIE = "cookie", + __SESSIONID_NONE = "none"; - private static final Enumeration __emptyEnum = - Collections.enumeration(Collections.EMPTY_LIST); + private static final Enumeration __emptyEnum = + Collections.enumeration(Collections.EMPTY_LIST); private static final Collection __defaultLocale = - Collections.singleton(Locale.getDefault()); + Collections.singleton(Locale.getDefault()); - private ServletHandler _servletHandler; + private ServletHandler _servletHandler; private HttpRequest _httpRequest; private ServletHttpResponse _servletHttpResponse; - private String _contextPath=null; - private String _servletPath=null; - private String _pathInfo=null; - private String _query=null; - private String _pathTranslated=null; - private String _requestedSessionId=null; - private HttpSession _session=null; - private String _sessionIdState=__SESSIONID_NOT_CHECKED; - private ServletIn _in =null; - private BufferedReader _reader=null; - private int _inputState=0; + private String _contextPath = null; + private String _servletPath = null; + private String _pathInfo = null; + private String _query = null; + private String _pathTranslated = null; + private String _requestedSessionId = null; + private HttpSession _session = null; + private String _sessionIdState = __SESSIONID_NOT_CHECKED; + private ServletIn _in = null; + private BufferedReader _reader = null; + private int _inputState = 0; private ServletHolder _servletHolder; private String _pathInContext; - + /* ------------------------------------------------------------ */ - /** Constructor. + + /** + * Constructor. */ public ServletHttpRequest(ServletHandler servletHandler, - String pathInContext, - HttpRequest request) - { - _servletHandler=servletHandler; - _pathInContext=pathInContext; - _contextPath=_servletHandler.getHttpContext().getContextPath(); - if (_contextPath.length()<=1) - _contextPath=""; - - _httpRequest=request; - } - - /* ------------------------------------------------------------ */ - void recycle(ServletHandler servletHandler,String pathInContext) - { - _servletHandler=servletHandler; - _pathInContext=pathInContext; - _servletPath=null; - _pathInfo=null; - _query=null; - _pathTranslated=null; - _requestedSessionId=null; - _session=null; - _sessionIdState=__SESSIONID_NOT_CHECKED; - _in=null; - _reader=null; - _inputState=0; - _servletHolder=null; - - if (servletHandler!=null) - _contextPath=_servletHandler.getHttpContext().getContextPath(); - if (_contextPath!=null&&_contextPath.length()<=1) - _contextPath=""; - } - - - /* ------------------------------------------------------------ */ - ServletHandler getServletHandler() - { + String pathInContext, + HttpRequest request) { + _servletHandler = servletHandler; + _pathInContext = pathInContext; + _contextPath = _servletHandler.getHttpContext().getContextPath(); + if (_contextPath.length() <= 1) + _contextPath = ""; + + _httpRequest = request; + } + + /* ------------------------------------------------------------ */ + void recycle(ServletHandler servletHandler, String pathInContext) { + _servletHandler = servletHandler; + _pathInContext = pathInContext; + _servletPath = null; + _pathInfo = null; + _query = null; + _pathTranslated = null; + _requestedSessionId = null; + _session = null; + _sessionIdState = __SESSIONID_NOT_CHECKED; + _in = null; + _reader = null; + _inputState = 0; + _servletHolder = null; + + if (servletHandler != null) + _contextPath = _servletHandler.getHttpContext().getContextPath(); + if (_contextPath != null && _contextPath.length() <= 1) + _contextPath = ""; + } + + + /* ------------------------------------------------------------ */ + ServletHandler getServletHandler() { return _servletHandler; } /* ------------------------------------------------------------ */ - void setServletHandler(ServletHandler servletHandler) - { - _servletHandler=servletHandler; + void setServletHandler(ServletHandler servletHandler) { + _servletHandler = servletHandler; } - + /* ------------------------------------------------------------ */ - /** Set servletpath and pathInfo. + + /** + * Set servletpath and pathInfo. * Called by the Handler before passing a request to a particular * holder to split the context path into a servlet path and path info. - * @param servletPath - * @param pathInfo + * + * @param servletPath + * @param pathInfo */ void setServletPaths(String servletPath, String pathInfo, - ServletHolder holder) - { - _servletPath=servletPath; - _pathInfo=pathInfo; - _servletHolder=holder; + ServletHolder holder) { + _servletPath = servletPath; + _pathInfo = pathInfo; + _servletHolder = holder; } - + /* ------------------------------------------------------------ */ - ServletHolder getServletHolder() - { + ServletHolder getServletHolder() { return _servletHolder; } - + /* ------------------------------------------------------------ */ - String getPathInContext() - { + String getPathInContext() { return _pathInContext; } - + /* ------------------------------------------------------------ */ - HttpRequest getHttpRequest() - { + HttpRequest getHttpRequest() { return _httpRequest; } - + /* ------------------------------------------------------------ */ - public ServletHttpResponse getServletHttpResponse() - { + public ServletHttpResponse getServletHttpResponse() { return _servletHttpResponse; } - + /* ------------------------------------------------------------ */ - void setServletHttpResponse(ServletHttpResponse response) - { + void setServletHttpResponse(ServletHttpResponse response) { _servletHttpResponse = response; } /* ------------------------------------------------------------ */ - public Locale getLocale() - { + public Locale getLocale() { Enumeration enm = _httpRequest.getFieldValues(HttpFields.__AcceptLanguage, - HttpFields.__separators); + HttpFields.__separators); // handle no locale if (enm == null || !enm.hasMoreElements()) return Locale.getDefault(); - + // sort the list in quality order List acceptLanguage = HttpFields.qualityList(enm); - if (acceptLanguage.size()==0) - return Locale.getDefault(); + if (acceptLanguage.size() == 0) + return Locale.getDefault(); + + int size = acceptLanguage.size(); - int size=acceptLanguage.size(); - // convert to locals - for (int i=0; i -1) - { + if (dash > -1) { country = language.substring(dash + 1).trim(); - language = language.substring(0,dash).trim(); + language = language.substring(0, dash).trim(); } - return new Locale(language,country); + return new Locale(language, country); } - return Locale.getDefault(); + return Locale.getDefault(); } - + /* ------------------------------------------------------------ */ - public Enumeration getLocales() - { + public Enumeration getLocales() { Enumeration enm = _httpRequest.getFieldValues(HttpFields.__AcceptLanguage, - HttpFields.__separators); + HttpFields.__separators); // handle no locale if (enm == null || !enm.hasMoreElements()) return Collections.enumeration(__defaultLocale); - + // sort the list in quality order List acceptLanguage = HttpFields.qualityList(enm); - - if (acceptLanguage.size()==0) + + if (acceptLanguage.size() == 0) return - Collections.enumeration(__defaultLocale); + Collections.enumeration(__defaultLocale); Object langs = null; - int size=acceptLanguage.size(); - + int size = acceptLanguage.size(); + // convert to locals - for (int i=0; i -1) - { + if (dash > -1) { country = language.substring(dash + 1).trim(); - language = language.substring(0,dash).trim(); + language = language.substring(0, dash).trim(); } - langs=LazyList.ensureSize(langs,size); - langs=LazyList.add(langs,new Locale(language,country)); + langs = LazyList.ensureSize(langs, size); + langs = LazyList.add(langs, new Locale(language, country)); } - if (LazyList.size(langs)==0) + if (LazyList.size(langs) == 0) return Collections.enumeration(__defaultLocale); - + return Collections.enumeration(LazyList.getList(langs)); } - + /* ------------------------------------------------------------ */ - public boolean isSecure() - { + public boolean isSecure() { return _httpRequest.isConfidential(); } - + /* ------------------------------------------------------------ */ - public Cookie[] getCookies() - { + public Cookie[] getCookies() { Cookie[] cookies = _httpRequest.getCookies(); - if (cookies.length==0) + if (cookies.length == 0) return null; return cookies; } - + /* ------------------------------------------------------------ */ - public long getDateHeader(String name) - { + public long getDateHeader(String name) { return _httpRequest.getDateField(name); } - + /* ------------------------------------------------------------ */ - public Enumeration getHeaderNames() - { + public Enumeration getHeaderNames() { return _httpRequest.getFieldNames(); } - + /* ------------------------------------------------------------ */ - public String getHeader(String name) - { + public String getHeader(String name) { return _httpRequest.getField(name); } - + /* ------------------------------------------------------------ */ - public Enumeration getHeaders(String s) - { - Enumeration enm=_httpRequest.getFieldValues(s); - if (enm==null) + public Enumeration getHeaders(String s) { + Enumeration enm = _httpRequest.getFieldValues(s); + if (enm == null) return __emptyEnum; return enm; } - + /* ------------------------------------------------------------ */ public int getIntHeader(String name) - throws NumberFormatException - { + throws NumberFormatException { return _httpRequest.getIntField(name); } - + /* ------------------------------------------------------------ */ - public String getMethod() - { + public String getMethod() { return _httpRequest.getMethod(); } - + /* ------------------------------------------------------------ */ - public String getContextPath() - { + public String getContextPath() { return _contextPath; } - + /* ------------------------------------------------------------ */ - public String getPathInfo() - { - if (_servletPath==null) - return null; + public String getPathInfo() { + if (_servletPath == null) + return null; return _pathInfo; } - + /* ------------------------------------------------------------ */ - public String getPathTranslated() - { - if (_pathInfo==null || _pathInfo.length()==0) + public String getPathTranslated() { + if (_pathInfo == null || _pathInfo.length() == 0) return null; - if (_pathTranslated==null) - { + if (_pathTranslated == null) { Resource resource = - _servletHandler.getHttpContext().getBaseResource(); + _servletHandler.getHttpContext().getBaseResource(); - if (resource==null) + if (resource == null) return null; - try - { - resource=resource.addPath(_pathInfo); + try { + resource = resource.addPath(_pathInfo); File file = resource.getFile(); - if (file==null) + if (file == null) return null; - _pathTranslated=file.getAbsolutePath(); - } - catch(Exception e) - { - log.debug(LogSupport.EXCEPTION,e); + _pathTranslated = file.getAbsolutePath(); + } catch (Exception e) { + log.debug(LogSupport.EXCEPTION, e); } } - + return _pathTranslated; } - + /* ------------------------------------------------------------ */ - public String getQueryString() - { - if (_query==null) - _query =_httpRequest.getQuery(); + public String getQueryString() { + if (_query == null) + _query = _httpRequest.getQuery(); return _query; } - + /* ------------------------------------------------------------ */ - public String getAuthType() - { - String at= _httpRequest.getAuthType(); - if (at== SecurityConstraint.__BASIC_AUTH) + public String getAuthType() { + String at = _httpRequest.getAuthType(); + if (at == SecurityConstraint.__BASIC_AUTH) return HttpServletRequest.BASIC_AUTH; - if (at==SecurityConstraint.__FORM_AUTH) + if (at == SecurityConstraint.__FORM_AUTH) return HttpServletRequest.FORM_AUTH; - if (at==SecurityConstraint.__DIGEST_AUTH) + if (at == SecurityConstraint.__DIGEST_AUTH) return HttpServletRequest.DIGEST_AUTH; - if (at==SecurityConstraint.__CERT_AUTH) + if (at == SecurityConstraint.__CERT_AUTH) return HttpServletRequest.CLIENT_CERT_AUTH; - if (at==SecurityConstraint.__CERT_AUTH2) + if (at == SecurityConstraint.__CERT_AUTH2) return HttpServletRequest.CLIENT_CERT_AUTH; return at; } /* ------------------------------------------------------------ */ - public String getRemoteUser() - { + public String getRemoteUser() { return _httpRequest.getAuthUser(); } /* ------------------------------------------------------------ */ - public boolean isUserInRole(String role) - { - if (_servletHolder!=null) - role=_servletHolder.getUserRoleLink(role); + public boolean isUserInRole(String role) { + if (_servletHolder != null) + role = _servletHolder.getUserRoleLink(role); return _httpRequest.isUserInRole(role); } /* ------------------------------------------------------------ */ - public Principal getUserPrincipal() - { + public Principal getUserPrincipal() { return _httpRequest.getUserPrincipal(); } - + /* ------------------------------------------------------------ */ - void setRequestedSessionId(String pathParams) - { - _requestedSessionId=null; - + void setRequestedSessionId(String pathParams) { + _requestedSessionId = null; + // try cookies first - if (_servletHandler.isUsingCookies()) - { - Cookie[] cookies=_httpRequest.getCookies(); - if (cookies!=null && cookies.length>0) - { - for (int i=0;i 0) { + for (int i = 0; i < cookies.length; i++) { + if (SessionManager.__SessionCookie.equalsIgnoreCase(cookies[i].getName())) { + if (_requestedSessionId != null) { // Multiple jsessionid cookies. Probably due to // multiple paths and/or domains. Pick the first // known session or the last defined cookie. SessionManager manager = _servletHandler.getSessionManager(); - if (manager!=null && manager.getHttpSession(_requestedSessionId)!=null) + if (manager != null && manager.getHttpSession(_requestedSessionId) != null) break; log.debug("multiple session cookies"); } - - _requestedSessionId=cookies[i].getValue(); + + _requestedSessionId = cookies[i].getValue(); _sessionIdState = __SESSIONID_COOKIE; - if(log.isDebugEnabled())log.debug("Got Session "+_requestedSessionId+" from cookie"); + if (log.isDebugEnabled()) log.debug("Got Session " + _requestedSessionId + " from cookie"); } } } } - + // check if there is a url encoded session param. - if (pathParams!=null && pathParams.startsWith(SessionManager.__SessionURL)) - { + if (pathParams != null && pathParams.startsWith(SessionManager.__SessionURL)) { String id = - pathParams.substring(SessionManager.__SessionURL.length()+1); - if(log.isDebugEnabled())log.debug("Got Session "+id+" from URL"); - - if (_requestedSessionId==null) - { - _requestedSessionId=id; + pathParams.substring(SessionManager.__SessionURL.length() + 1); + if (log.isDebugEnabled()) log.debug("Got Session " + id + " from URL"); + + if (_requestedSessionId == null) { + _requestedSessionId = id; _sessionIdState = __SESSIONID_URL; - } - else if (!id.equals(_requestedSessionId)) + } else if (!id.equals(_requestedSessionId)) log.debug("Mismatched session IDs"); } - + if (_requestedSessionId == null) - _sessionIdState = __SESSIONID_NONE; + _sessionIdState = __SESSIONID_NONE; } - + /* ------------------------------------------------------------ */ - public String getRequestedSessionId() - { + public String getRequestedSessionId() { return _requestedSessionId; } - + /* ------------------------------------------------------------ */ - public String getRequestURI() - { + public String getRequestURI() { return _httpRequest.getEncodedPath(); } - + /* ------------------------------------------------------------ */ - public StringBuffer getRequestURL() - { + public StringBuffer getRequestURL() { StringBuffer buf = _httpRequest.getRootURL(); buf.append(getRequestURI()); return buf; } - + /* ------------------------------------------------------------ */ - public String getServletPath() - { - if (_servletPath==null) + public String getServletPath() { + if (_servletPath == null) return _pathInContext; return _servletPath; } - + /* ------------------------------------------------------------ */ - public HttpSession getSession(boolean create) - { - if (_session != null && ((SessionManager.Session)_session).isValid()) + public HttpSession getSession(boolean create) { + if (_session != null && ((SessionManager.Session) _session).isValid()) return _session; - - _session=null; - + + _session = null; + String id = getRequestedSessionId(); - - if (id != null) - { - _session=_servletHandler.getHttpSession(id); + + if (id != null) { + _session = _servletHandler.getHttpSession(id); if (_session == null && !create) return null; } - - if (_session == null && create) - { - _session=newSession(); + + if (_session == null && create) { + _session = newSession(); } - + return _session; } @@ -517,169 +463,187 @@ public HttpSession getSession(boolean create) /* Create a new HttpSession. * If cookies are being used a set cookie is added to the response. */ - HttpSession newSession() - { - HttpSession session=_servletHandler.newHttpSession(this); - Cookie cookie=_servletHandler.getSessionManager().getSessionCookie(session,isSecure()); - if (cookie!=null) + HttpSession newSession() { + HttpSession session = _servletHandler.newHttpSession(this); + Cookie cookie = _servletHandler.getSessionManager().getSessionCookie(session, isSecure()); + if (cookie != null) _servletHttpResponse.getHttpResponse().addSetCookie(cookie); return session; } - + /* ------------------------------------------------------------ */ - public HttpSession getSession() - { + public HttpSession getSession() { HttpSession session = getSession(true); return session; } - + + @Override + public String changeSessionId() { + return null; + } + /* ------------------------------------------------------------ */ - public boolean isRequestedSessionIdValid() - { + public boolean isRequestedSessionIdValid() { return _requestedSessionId != null && getSession(false) != null; } - + /* -------------------------------------------------------------- */ - public boolean isRequestedSessionIdFromCookie() - { + public boolean isRequestedSessionIdFromCookie() { return _sessionIdState == __SESSIONID_COOKIE; } - + /* -------------------------------------------------------------- */ - public boolean isRequestedSessionIdFromURL() - { + public boolean isRequestedSessionIdFromURL() { return _sessionIdState == __SESSIONID_URL; } - + /* -------------------------------------------------------------- */ + /** * @deprecated */ - public boolean isRequestedSessionIdFromUrl() - { + public boolean isRequestedSessionIdFromUrl() { return isRequestedSessionIdFromURL(); } - + + @Override + public boolean authenticate(HttpServletResponse httpServletResponse) throws IOException, ServletException { + return false; + } + + @Override + public void login(String s, String s1) throws ServletException { + + } + + @Override + public void logout() throws ServletException { + + } + + @Override + public Collection getParts() throws IOException, ServletException { + return null; + } + + @Override + public Part getPart(String s) throws IOException, ServletException { + return null; + } + + @Override + public T upgrade(Class aClass) throws IOException, ServletException { + return null; + } + /* -------------------------------------------------------------- */ - public Enumeration getAttributeNames() - { + public Enumeration getAttributeNames() { return _httpRequest.getAttributeNames(); } - + /* -------------------------------------------------------------- */ - public Object getAttribute(String name) - { + public Object getAttribute(String name) { return _httpRequest.getAttribute(name); } - + /* -------------------------------------------------------------- */ - public void setAttribute(String name, Object value) - { - _httpRequest.setAttribute(name,value); + public void setAttribute(String name, Object value) { + _httpRequest.setAttribute(name, value); } - + /* -------------------------------------------------------------- */ - public void removeAttribute(String name) - { + public void removeAttribute(String name) { _httpRequest.removeAttribute(name); } - + /* -------------------------------------------------------------- */ public void setCharacterEncoding(String encoding) - throws UnsupportedEncodingException - { - if (_inputState!=0) + throws UnsupportedEncodingException { + if (_inputState != 0) throw new IllegalStateException("getReader() or getInputStream() called"); "".getBytes(encoding); - _httpRequest.setCharacterEncoding(encoding,false); + _httpRequest.setCharacterEncoding(encoding, false); } - + /* -------------------------------------------------------------- */ - public String getCharacterEncoding() - { + public String getCharacterEncoding() { return _httpRequest.getCharacterEncoding(); } - + /* -------------------------------------------------------------- */ - public int getContentLength() - { + public int getContentLength() { return _httpRequest.getContentLength(); } - + + @Override + public long getContentLengthLong() { + return 0; + } + /* -------------------------------------------------------------- */ - public String getContentType() - { + public String getContentType() { return _httpRequest.getContentType(); } - + /* -------------------------------------------------------------- */ - public ServletInputStream getInputStream() - { - if (_inputState!=0 && _inputState!=1) + public ServletInputStream getInputStream() { + if (_inputState != 0 && _inputState != 1) throw new IllegalStateException(); - if (_in==null) - _in = new ServletIn((HttpInputStream)_httpRequest.getInputStream()); - _inputState=1; - _reader=null; - return _in; + if (_in == null) + _in = new ServletIn((HttpInputStream) _httpRequest.getInputStream()); + _inputState = 1; + _reader = null; + return (ServletInputStream) _in.getInputStream(); } - + /* -------------------------------------------------------------- */ + /** * This method is not recommended as it forces the generation of a * non-optimal data structure. */ - public Map getParameterMap() - { + public Map getParameterMap() { return Collections.unmodifiableMap(_httpRequest.getParameterStringArrayMap()); } - + /* -------------------------------------------------------------- */ - public String getParameter(String name) - { + public String getParameter(String name) { return _httpRequest.getParameter(name); } - + /* -------------------------------------------------------------- */ - public Enumeration getParameterNames() - { + public Enumeration getParameterNames() { return Collections.enumeration(_httpRequest.getParameterNames()); } - + /* -------------------------------------------------------------- */ - public String[] getParameterValues(String name) - { - List v=_httpRequest.getParameterValues(name); - if (v==null) + public String[] getParameterValues(String name) { + List v = _httpRequest.getParameterValues(name); + if (v == null) return null; - String[]a=new String[v.size()]; - return (String[])v.toArray(a); + String[] a = new String[v.size()]; + return (String[]) v.toArray(a); } - + /* -------------------------------------------------------------- */ - public String getProtocol() - { + public String getProtocol() { return _httpRequest.getVersion(); } - + /* -------------------------------------------------------------- */ - public String getScheme() - { + public String getScheme() { return _httpRequest.getScheme(); } - + /* -------------------------------------------------------------- */ - public String getServerName() - { + public String getServerName() { return _httpRequest.getHost(); } - + /* -------------------------------------------------------------- */ - public int getServerPort() - { + public int getServerPort() { int port = _httpRequest.getPort(); - if (port==0) - { + if (port == 0) { if (getScheme().equalsIgnoreCase("https")) return 443; return 80; @@ -688,136 +652,158 @@ public int getServerPort() } /* -------------------------------------------------------------- */ - public int getRemotePort() - { - HttpConnection connection= _httpRequest.getHttpConnection(); - if (connection!=null) + public int getRemotePort() { + HttpConnection connection = _httpRequest.getHttpConnection(); + if (connection != null) return connection.getRemotePort(); return 0; } - + /* -------------------------------------------------------------- */ - public String getLocalName() - { - HttpConnection connection= _httpRequest.getHttpConnection(); - if (connection!=null) + public String getLocalName() { + HttpConnection connection = _httpRequest.getHttpConnection(); + if (connection != null) return connection.getServerName(); return null; } - + /* -------------------------------------------------------------- */ - public String getLocalAddr() - { - HttpConnection connection= _httpRequest.getHttpConnection(); - if (connection!=null) + public String getLocalAddr() { + HttpConnection connection = _httpRequest.getHttpConnection(); + if (connection != null) return connection.getServerAddr(); return null; } - + /* -------------------------------------------------------------- */ - public int getLocalPort() - { - HttpConnection connection= _httpRequest.getHttpConnection(); - if (connection!=null) + public int getLocalPort() { + HttpConnection connection = _httpRequest.getHttpConnection(); + if (connection != null) return connection.getServerPort(); return 0; } - + + @Override + public ServletContext getServletContext() { + return null; + } + + @Override + public AsyncContext startAsync() throws IllegalStateException { + return null; + } + + @Override + public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException { + return null; + } + + @Override + public boolean isAsyncStarted() { + return false; + } + + @Override + public boolean isAsyncSupported() { + return false; + } + + @Override + public AsyncContext getAsyncContext() { + return null; + } + + @Override + public DispatcherType getDispatcherType() { + return null; + } + /* -------------------------------------------------------------- */ public BufferedReader getReader() - throws UnsupportedEncodingException - { - if (_inputState!=0 && _inputState!=2) + throws UnsupportedEncodingException { + if (_inputState != 0 && _inputState != 2) throw new IllegalStateException(); - if (_reader==null) - { - String encoding=getCharacterEncoding(); - if (encoding==null) - encoding=StringUtil.__ISO_8859_1; - _reader=new BufferedReader(new InputStreamReader(getInputStream(),encoding)); - + if (_reader == null) { + String encoding = getCharacterEncoding(); + if (encoding == null) + encoding = StringUtil.__ISO_8859_1; + _reader = new BufferedReader(new InputStreamReader(getInputStream(), encoding)); + } - _inputState=2; + _inputState = 2; return _reader; } - + /* -------------------------------------------------------------- */ - public String getRemoteAddr() - { + public String getRemoteAddr() { return _httpRequest.getRemoteAddr(); } - + /* -------------------------------------------------------------- */ - public String getRemoteHost() - { - if (_httpRequest.getHttpConnection()==null) + public String getRemoteHost() { + if (_httpRequest.getHttpConnection() == null) return null; return _httpRequest.getRemoteHost(); } /* -------------------------------------------------------------- */ + /** - * @deprecated As of Version 2.1 of the Java Servlet API, - * use {@link javax.servlet.ServletContext#getRealPath} instead. + * @deprecated As of Version 2.1 of the Java Servlet API, + * use {@link javax.servlet.ServletException#getRealPath(String)} instead. */ - public String getRealPath(String path) - { + public String getRealPath(String path) { return _servletHandler.getServletContext().getRealPath(path); } /* ------------------------------------------------------------ */ - public RequestDispatcher getRequestDispatcher(String url) - { + public RequestDispatcher getRequestDispatcher(String url) { if (url == null) return null; - if (!url.startsWith("/")) - { - String relTo=URI.addPaths(_servletPath,_pathInfo); - int slash=relTo.lastIndexOf("/"); - if (slash>1) - relTo=relTo.substring(0,slash+1); + if (!url.startsWith("/")) { + String relTo = URI.addPaths(_servletPath, _pathInfo); + int slash = relTo.lastIndexOf("/"); + if (slash > 1) + relTo = relTo.substring(0, slash + 1); else - relTo="/"; - url=URI.addPaths(relTo,url); + relTo = "/"; + url = URI.addPaths(relTo, url); } - + return _servletHandler.getServletContext().getRequestDispatcher(url); } /* ------------------------------------------------------------ */ - public String toString() - { + public String toString() { return - getContextPath()+"+"+getServletPath()+"+"+getPathInfo()+"\n"+ - _httpRequest.toString(); + getContextPath() + "+" + getServletPath() + "+" + getPathInfo() + "\n" + + _httpRequest.toString(); } - + /* ------------------------------------------------------------ */ - /** Unwrap a ServletRequest. + + /** + * Unwrap a ServletRequest. * + * @param request + * @return The core ServletHttpRequest which must be the + * underlying request object * @see javax.servlet.ServletRequestWrapper * @see javax.servlet.http.HttpServletRequestWrapper - * @param request - * @return The core ServletHttpRequest which must be the - * underlying request object */ - public static ServletHttpRequest unwrap(ServletRequest request) - { - while (!(request instanceof ServletHttpRequest)) - { - if (request instanceof ServletRequestWrapper) - { + public static ServletHttpRequest unwrap(ServletRequest request) { + while (!(request instanceof ServletHttpRequest)) { + if (request instanceof ServletRequestWrapper) { ServletRequestWrapper wrapper = - (ServletRequestWrapper)request; - request=wrapper.getRequest(); - } - else + (ServletRequestWrapper) request; + request = wrapper.getRequest(); + } else throw new IllegalArgumentException("Does not wrap ServletHttpRequest"); } - return (ServletHttpRequest)request; + return (ServletHttpRequest) request; } } diff --git a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHttpResponse.java b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHttpResponse.java index 2acb69aeb..864a4802e 100644 --- a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHttpResponse.java +++ b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletHttpResponse.java @@ -29,6 +29,7 @@ import javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; +import java.util.Collection; import java.util.Locale; /* ------------------------------------------------------------ */ @@ -520,6 +521,26 @@ public void setStatus(int status, String message) _httpResponse.setReason(message); } + @Override + public int getStatus() { + return 0; + } + + @Override + public String getHeader(String s) { + return null; + } + + @Override + public Collection getHeaders(String s) { + return null; + } + + @Override + public Collection getHeaderNames() { + return null; + } + /* ------------------------------------------------------------ */ public ServletOutputStream getOutputStream() @@ -594,7 +615,12 @@ public void setContentLength(int len) if (!isCommitted()) setIntHeader(HttpFields.__ContentLength,len); } - + + @Override + public void setContentLengthLong(long l) { + + } + /* ------------------------------------------------------------ */ public String getContentType() { diff --git a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletIn.java b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletIn.java index a475eb2ae..010dfb5ea 100644 --- a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletIn.java +++ b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletIn.java @@ -17,78 +17,76 @@ import net.lightbody.bmp.proxy.jetty.http.HttpInputStream; -import javax.servlet.ServletInputStream; import java.io.IOException; -class ServletIn extends ServletInputStream -{ +class ServletIn extends HttpInputStream { HttpInputStream _in; /* ------------------------------------------------------------ */ - ServletIn(HttpInputStream in) - { - _in=in; + ServletIn(HttpInputStream in) { + super(in); + _in = in; } - + /* ------------------------------------------------------------ */ + @Override public int read() - throws IOException - { + throws IOException { return _in.read(); } - + /* ------------------------------------------------------------ */ - public int read(byte b[]) throws IOException - { + @Override + public int read(byte b[]) throws IOException { return _in.read(b); } - + /* ------------------------------------------------------------ */ - public int read(byte b[], int off, int len) throws IOException - { - return _in.read(b,off,len); + @Override + public int read(byte b[], int off, int len) throws IOException { + return _in.read(b, off, len); } - + /* ------------------------------------------------------------ */ - public long skip(long len) throws IOException - { + @Override + public long skip(long len) throws IOException { return _in.skip(len); } - + /* ------------------------------------------------------------ */ + @Override public int available() - throws IOException - { + throws IOException { return _in.available(); } - + /* ------------------------------------------------------------ */ + @Override public void close() - throws IOException - { + throws IOException { _in.close(); } - + /* ------------------------------------------------------------ */ - public boolean markSupported() - { + @Override + public boolean markSupported() { return _in.markSupported(); } - + /* ------------------------------------------------------------ */ + @Override public void reset() - throws IOException - { + throws IOException { _in.reset(); } - + /* ------------------------------------------------------------ */ - public void mark(int readlimit) - { + @Override + public void mark(int readlimit) { _in.mark(readlimit); } - + } diff --git a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletOut.java b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletOut.java index 277b233c9..738c75f05 100644 --- a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletOut.java +++ b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletOut.java @@ -18,6 +18,7 @@ import net.lightbody.bmp.proxy.jetty.util.IO; import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; import java.io.IOException; import java.io.OutputStream; @@ -40,6 +41,7 @@ public void write(int ch) } /* ------------------------------------------------------------ */ + @Override public void write(byte[]b) throws IOException { @@ -47,6 +49,7 @@ public void write(byte[]b) } /* ------------------------------------------------------------ */ + @Override public void write(byte[]b,int o,int l) throws IOException { @@ -54,6 +57,7 @@ public void write(byte[]b,int o,int l) } /* ------------------------------------------------------------ */ + @Override public void flush() throws IOException { @@ -61,6 +65,7 @@ public void flush() } /* ------------------------------------------------------------ */ + @Override public void close() throws IOException { @@ -76,15 +81,27 @@ public void disable() } /* ------------------------------------------------------------ */ + @Override public void print(String s) throws IOException { if (s!=null) write(s.getBytes()); } /* ------------------------------------------------------------ */ + @Override public void println(String s) throws IOException { if (s!=null) write(s.getBytes()); write(IO.CRLF_BYTES); } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setWriteListener(WriteListener writeListener) { + + } } diff --git a/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/HarTest.java b/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/HarTest.java index 346273133..d1e5901bd 100644 --- a/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/HarTest.java +++ b/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/HarTest.java @@ -80,252 +80,252 @@ public void testRequestAndResponseSizesAreSet() throws Exception { assertEquals(13, entry.getResponse().getBodySize()); } - @Test - public void testThatProxyCanCaptureBodyInHar() throws IOException, InterruptedException { - proxy.setCaptureContent(true); - proxy.newHar("Test"); + @Test + public void testThatProxyCanCaptureBodyInHar() throws IOException, InterruptedException { + proxy.setCaptureContent(true); + proxy.newHar("Test"); - String body = IOUtils.toStringAndClose(client.execute(new HttpGet(getLocalServerHostnameAndPort() + "/a.txt")).getEntity().getContent()); + String body = IOUtils.toStringAndClose(client.execute(new HttpGet(getLocalServerHostnameAndPort() + "/a.txt")).getEntity().getContent()); - assertThat(body, containsString("this is a.txt")); + assertThat(body, containsString("this is a.txt")); Thread.sleep(500); - Har har = proxy.getHar(); - assertNotNull("Har is null", har); - HarLog log = har.getLog(); - assertNotNull("Log is null", log); - List entries = log.getEntries(); - assertNotNull("Entries are null", entries); - HarEntry entry = entries.get(0); - assertNotNull("No entry found", entry); - HarResponse response = entry.getResponse(); - assertNotNull("Response is null", response); - HarContent content = response.getContent(); - assertNotNull("Content is null", content); - String mime = content.getMimeType(); - assertEquals("Mime not matched", "text/plain", mime); - String encoding = content.getEncoding(); - assertEquals("Encoding not matched", null, encoding); - String text = content.getText(); - assertEquals("Text not matched", "this is a.txt", text); - } - - @Test - public void testThatProxyCanCaptureJsonRpc() throws IOException, InterruptedException { - proxy.setCaptureContent(true); - proxy.newHar("Test"); - - HttpPost post = new HttpPost(getLocalServerHostnameAndPort() + "/jsonrpc"); - HttpEntity entity = new StringEntity("{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"test\",\"params\":{}}"); - post.setEntity(entity); - post.addHeader("Accept", "application/json-rpc"); - post.addHeader("Content-Type", "application/json; charset=UTF-8"); - - String body = IOUtils.toStringAndClose(client.execute(post).getEntity().getContent()); - - assertThat(body, containsString("{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{}}")); + Har har = proxy.getHar(); + assertNotNull("Har is null", har); + HarLog log = har.getLog(); + assertNotNull("Log is null", log); + List entries = log.getEntries(); + assertNotNull("Entries are null", entries); + HarEntry entry = entries.get(0); + assertNotNull("No entry found", entry); + HarResponse response = entry.getResponse(); + assertNotNull("Response is null", response); + HarContent content = response.getContent(); + assertNotNull("Content is null", content); + String mime = content.getMimeType(); + assertEquals("Mime not matched", "text/plain", mime); + String encoding = content.getEncoding(); + assertEquals("Encoding not matched", null, encoding); + String text = content.getText(); + assertEquals("Text not matched", "this is a.txt", text); + } + + @Test + public void testThatProxyCanCaptureJsonRpc() throws IOException, InterruptedException { + proxy.setCaptureContent(true); + proxy.newHar("Test"); + + HttpPost post = new HttpPost(getLocalServerHostnameAndPort() + "/jsonrpc"); + HttpEntity entity = new StringEntity("{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"test\",\"params\":{}}"); + post.setEntity(entity); + post.addHeader("Accept", "application/json-rpc"); + post.addHeader("Content-Type", "application/json; charset=UTF-8"); + + String body = IOUtils.toStringAndClose(client.execute(post).getEntity().getContent()); + + assertThat(body, containsString("{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{}}")); Thread.sleep(500); - Har har = proxy.getHar(); - assertNotNull("Har is null", har); - HarLog log = har.getLog(); - assertNotNull("Log is null", log); - List entries = log.getEntries(); - assertNotNull("Entries are null", entries); - HarEntry entry = entries.get(0); - assertNotNull("No entry found", entry); - HarResponse response = entry.getResponse(); - assertNotNull("Response is null", response); - HarRequest request = entry.getRequest(); - assertNotNull("Request is null", request); - HarPostData postdata = request.getPostData(); - assertNotNull("PostData is null", postdata); - assertThat(postdata.getText(), containsString("{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"test\",\"params\":{}}")); - } - - @Test - public void testThatTraditionalPostParamsAreCaptured() throws IOException, InterruptedException { - proxy.setCaptureContent(true); - proxy.newHar("Test"); - - HttpPost post = new HttpPost(getLocalServerHostnameAndPort() + "/jsonrpc"); - post.setEntity(new UrlEncodedFormEntity(Collections.singletonList(new BasicNameValuePair("foo", "bar")))); - - IOUtils.toStringAndClose(client.execute(post).getEntity().getContent()); + Har har = proxy.getHar(); + assertNotNull("Har is null", har); + HarLog log = har.getLog(); + assertNotNull("Log is null", log); + List entries = log.getEntries(); + assertNotNull("Entries are null", entries); + HarEntry entry = entries.get(0); + assertNotNull("No entry found", entry); + HarResponse response = entry.getResponse(); + assertNotNull("Response is null", response); + HarRequest request = entry.getRequest(); + assertNotNull("Request is null", request); + HarPostData postdata = request.getPostData(); + assertNotNull("PostData is null", postdata); + assertThat(postdata.getText(), containsString("{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"test\",\"params\":{}}")); + } + + @Test + public void testThatTraditionalPostParamsAreCaptured() throws IOException, InterruptedException { + proxy.setCaptureContent(true); + proxy.newHar("Test"); + + HttpPost post = new HttpPost(getLocalServerHostnameAndPort() + "/jsonrpc"); + post.setEntity(new UrlEncodedFormEntity(Collections.singletonList(new BasicNameValuePair("foo", "bar")))); + + IOUtils.toStringAndClose(client.execute(post).getEntity().getContent()); Thread.sleep(500); - Har har = proxy.getHar(); - assertNotNull("Har is null", har); - HarLog log = har.getLog(); - assertNotNull("Log is null", log); - List entries = log.getEntries(); - assertNotNull("Entries are null", entries); - HarEntry entry = entries.get(0); - assertNotNull("No entry found", entry); - HarResponse response = entry.getResponse(); - assertNotNull("Response is null", response); - HarRequest request = entry.getRequest(); - assertNotNull("Request is null", request); - HarPostData postdata = request.getPostData(); - assertNotNull("PostData is null", postdata); - assertEquals("application/x-www-form-urlencoded", postdata.getMimeType()); - assertEquals(1, postdata.getParams().size()); - assertEquals("foo", postdata.getParams().get(0).getName()); - assertEquals("bar", postdata.getParams().get(0).getValue()); - } - - @Test - public void testThatImagesAreCapturedAsBase64EncodedContent() throws IOException, InterruptedException { - proxy.setCaptureContent(true); - proxy.newHar("Test"); - - InputStream is1 = client.execute(new HttpGet(getLocalServerHostnameAndPort() + "/c.png")).getEntity().getContent(); - ByteArrayOutputStream o1 = new ByteArrayOutputStream(); + Har har = proxy.getHar(); + assertNotNull("Har is null", har); + HarLog log = har.getLog(); + assertNotNull("Log is null", log); + List entries = log.getEntries(); + assertNotNull("Entries are null", entries); + HarEntry entry = entries.get(0); + assertNotNull("No entry found", entry); + HarResponse response = entry.getResponse(); + assertNotNull("Response is null", response); + HarRequest request = entry.getRequest(); + assertNotNull("Request is null", request); + HarPostData postdata = request.getPostData(); + assertNotNull("PostData is null", postdata); + assertEquals("application/x-www-form-urlencoded", postdata.getMimeType()); + assertEquals(1, postdata.getParams().size()); + assertEquals("foo", postdata.getParams().get(0).getName()); + assertEquals("bar", postdata.getParams().get(0).getValue()); + } + + @Test + public void testThatImagesAreCapturedAsBase64EncodedContent() throws IOException, InterruptedException { + proxy.setCaptureContent(true); + proxy.newHar("Test"); + + InputStream is1 = client.execute(new HttpGet(getLocalServerHostnameAndPort() + "/c.png")).getEntity().getContent(); + ByteArrayOutputStream o1 = new ByteArrayOutputStream(); IOUtils.copyAndClose(is1, o1); - ByteArrayOutputStream o2 = new ByteArrayOutputStream(); + ByteArrayOutputStream o2 = new ByteArrayOutputStream(); IOUtils.copyAndClose(HarTest.class.getResourceAsStream("/local-server/c.png"), o2); - assertTrue("Image does not match file system", Arrays.equals(o1.toByteArray(), o2.toByteArray())); + assertTrue("Image does not match file system", Arrays.equals(o1.toByteArray(), o2.toByteArray())); Thread.sleep(500); - Har har = proxy.getHar(); - assertNotNull("Har is null", har); - HarLog log = har.getLog(); - assertNotNull("Log is null", log); - List entries = log.getEntries(); - assertNotNull("Entries are null", entries); - HarEntry entry = entries.get(0); - assertNotNull("No entry found", entry); - HarResponse response = entry.getResponse(); - assertNotNull("Response is null", response); - HarContent content = response.getContent(); - assertNotNull("Content is null", content); - String mime = content.getMimeType(); - assertEquals("Mime not matched", "image/png", mime); - String encoding = content.getEncoding(); - assertEquals("Encoding not matched", "base64", encoding); - String text = content.getText(); - String base64 = "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"; - assertEquals("Base64 not correct", base64, text); - } - - @Test - public void testThatUrlEncodedQueryStringIsParsedCorrecty() throws IOException, InterruptedException { - proxy.setCaptureContent(true); - proxy.newHar("Test"); - - HttpGet get = new HttpGet(getLocalServerHostnameAndPort() + "/a.txt?foo=bar&a=1%262"); - client.execute(get); + Har har = proxy.getHar(); + assertNotNull("Har is null", har); + HarLog log = har.getLog(); + assertNotNull("Log is null", log); + List entries = log.getEntries(); + assertNotNull("Entries are null", entries); + HarEntry entry = entries.get(0); + assertNotNull("No entry found", entry); + HarResponse response = entry.getResponse(); + assertNotNull("Response is null", response); + HarContent content = response.getContent(); + assertNotNull("Content is null", content); + String mime = content.getMimeType(); + assertEquals("Mime not matched", "image/png", mime); + String encoding = content.getEncoding(); + assertEquals("Encoding not matched", "base64", encoding); + String text = content.getText(); + String base64 = "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"; + assertEquals("Base64 not correct", base64, text); + } + + @Test + public void testThatUrlEncodedQueryStringIsParsedCorrecty() throws IOException, InterruptedException { + proxy.setCaptureContent(true); + proxy.newHar("Test"); + + HttpGet get = new HttpGet(getLocalServerHostnameAndPort() + "/a.txt?foo=bar&a=1%262"); + client.execute(get); Thread.sleep(500); - Har har = proxy.getHar(); - assertNotNull("Har is null", har); - HarLog log = har.getLog(); - assertNotNull("Log is null", log); - List entries = log.getEntries(); - assertNotNull("Entries are null", entries); - HarEntry entry = entries.get(0); - assertNotNull("No entry found", entry); - HarRequest req = entry.getRequest(); - assertNotNull("No request found", req); - // the HAR spec is not clear on what order the parameters should show up in. intuitively, since getQueryString() - // returns a List, the order should match the query string itself, but this is not technically required. - boolean sawFoo = false; - boolean sawA = false; - for (HarNameValuePair queryStringParam : req.getQueryString()) { - if (queryStringParam.getName().equals("foo")) { - assertEquals("expected 'foo' query param's value to be 'bar'", "bar", queryStringParam.getValue()); - sawFoo = true; - } else if (queryStringParam.getName().equals("a")) { - assertEquals("expected 'a' query param's value to be '1&2'", "1&2", queryStringParam.getValue()); - sawA = true; - } else { - fail("Unexpected query param: " + queryStringParam.getName() + ", value: " + queryStringParam.getValue()); - } - } - - assertTrue("did not find query param 'foo'", sawFoo); - assertTrue("did not find query param 'a'", sawA); - } - - @Test - public void testThatGzippedContentIsProperlyCapturedInHar() throws IOException, InterruptedException { - proxy.setCaptureContent(true); - proxy.newHar("Test"); - - // gzip all requests - server.forceGzip(); - - HttpGet get = new HttpGet(getLocalServerHostnameAndPort() + "/a.txt"); - get.addHeader("Accept-Encoding", "gzip"); - String body = IOUtils.toStringAndClose(new GZIPInputStream(client.execute(get).getEntity().getContent())); - - assertThat(body, containsString("this is a.txt")); + Har har = proxy.getHar(); + assertNotNull("Har is null", har); + HarLog log = har.getLog(); + assertNotNull("Log is null", log); + List entries = log.getEntries(); + assertNotNull("Entries are null", entries); + HarEntry entry = entries.get(0); + assertNotNull("No entry found", entry); + HarRequest req = entry.getRequest(); + assertNotNull("No request found", req); + // the HAR spec is not clear on what order the parameters should show up in. intuitively, since getQueryString() + // returns a List, the order should match the query string itself, but this is not technically required. + boolean sawFoo = false; + boolean sawA = false; + for (HarNameValuePair queryStringParam : req.getQueryString()) { + if (queryStringParam.getName().equals("foo")) { + assertEquals("expected 'foo' query param's value to be 'bar'", "bar", queryStringParam.getValue()); + sawFoo = true; + } else if (queryStringParam.getName().equals("a")) { + assertEquals("expected 'a' query param's value to be '1&2'", "1&2", queryStringParam.getValue()); + sawA = true; + } else { + fail("Unexpected query param: " + queryStringParam.getName() + ", value: " + queryStringParam.getValue()); + } + } + + assertTrue("did not find query param 'foo'", sawFoo); + assertTrue("did not find query param 'a'", sawA); + } + + @Test + public void testThatGzippedContentIsProperlyCapturedInHar() throws IOException, InterruptedException { + proxy.setCaptureContent(true); + proxy.newHar("Test"); + + // gzip all requests + server.forceGzip(); + + HttpGet get = new HttpGet(getLocalServerHostnameAndPort() + "/a.txt"); + get.addHeader("Accept-Encoding", "gzip"); + String body = IOUtils.toStringAndClose(new GZIPInputStream(client.execute(get).getEntity().getContent())); + + assertThat(body, containsString("this is a.txt")); Thread.sleep(500); - Har har = proxy.getHar(); - assertNotNull("Har is null", har); - HarLog log = har.getLog(); - assertNotNull("Log is null", log); - List entries = log.getEntries(); - assertNotNull("Entries are null", entries); - HarEntry entry = entries.get(0); - assertNotNull("No entry found", entry); - HarResponse response = entry.getResponse(); - assertNotNull("Response is null", response); - HarContent content = response.getContent(); - assertNotNull("Content is null", content); - String mime = content.getMimeType(); - assertEquals("Mime not matched", "text/plain", mime); - String text = content.getText(); - assertEquals("Text not matched", "this is a.txt", text); - } - - @Test - public void testHarPagesPopulated() throws IOException, InterruptedException { - proxy.newHar("testpage1"); - - HttpGet get = new HttpGet(getLocalServerHostnameAndPort() + "/a.txt"); - IOUtils.toStringAndClose(client.execute(get).getEntity().getContent()); - - proxy.endPage(); - - proxy.newPage("testpage2"); - - IOUtils.toStringAndClose(client.execute(get).getEntity().getContent()); - IOUtils.toStringAndClose(client.execute(get).getEntity().getContent()); - - proxy.endPage(); + Har har = proxy.getHar(); + assertNotNull("Har is null", har); + HarLog log = har.getLog(); + assertNotNull("Log is null", log); + List entries = log.getEntries(); + assertNotNull("Entries are null", entries); + HarEntry entry = entries.get(0); + assertNotNull("No entry found", entry); + HarResponse response = entry.getResponse(); + assertNotNull("Response is null", response); + HarContent content = response.getContent(); + assertNotNull("Content is null", content); + String mime = content.getMimeType(); + assertEquals("Mime not matched", "text/plain", mime); + String text = content.getText(); + assertEquals("Text not matched", "this is a.txt", text); + } + + @Test + public void testHarPagesPopulated() throws IOException, InterruptedException { + proxy.newHar("testpage1"); + + HttpGet get = new HttpGet(getLocalServerHostnameAndPort() + "/a.txt"); + IOUtils.toStringAndClose(client.execute(get).getEntity().getContent()); + + proxy.endPage(); + + proxy.newPage("testpage2"); + + IOUtils.toStringAndClose(client.execute(get).getEntity().getContent()); + IOUtils.toStringAndClose(client.execute(get).getEntity().getContent()); + + proxy.endPage(); Thread.sleep(500); - Har har = proxy.getHar(); - assertNotNull("Har is null", har); - HarLog log = har.getLog(); - assertNotNull("Log is null", log); - - List entries = log.getEntries(); - assertNotNull("Entries are null", entries); - - assertNotNull("har pages are null", log.getPages()); - assertEquals("expected 2 har pages", 2, log.getPages().size()); - - HarPage page1 = log.getPages().get(0); - assertEquals("incorrect har page id", "testpage1", page1.getId()); - assertEquals("incorrect har page title", page1.getId(), page1.getTitle()); - assertNotNull("har page timings are null", page1.getPageTimings()); - - HarPageTimings timings1 = page1.getPageTimings(); - assertNotNull("har page onLoad timing is null", timings1.getOnLoad()); - assertNotEquals("har page onLoad timing should be greater than 0", 0L, timings1.getOnLoad().longValue()); - - HarPage page2 = log.getPages().get(1); - assertEquals("incorrect har page id", "testpage2", page2.getId()); - assertEquals("incorrect har page id", page2.getId(), page2.getTitle()); - assertNotNull("har page timings are null", page2.getPageTimings()); - HarPageTimings timings2 = page2.getPageTimings(); - assertNotNull("har page onLoad timing is null", timings2.getOnLoad()); - assertNotEquals("har page onLoad timing should be greater than 0", 0L, timings2.getOnLoad().longValue()); - } + Har har = proxy.getHar(); + assertNotNull("Har is null", har); + HarLog log = har.getLog(); + assertNotNull("Log is null", log); + + List entries = log.getEntries(); + assertNotNull("Entries are null", entries); + + assertNotNull("har pages are null", log.getPages()); + assertEquals("expected 2 har pages", 2, log.getPages().size()); + + HarPage page1 = log.getPages().get(0); + assertEquals("incorrect har page id", "testpage1", page1.getId()); + assertEquals("incorrect har page title", page1.getId(), page1.getTitle()); + assertNotNull("har page timings are null", page1.getPageTimings()); + + HarPageTimings timings1 = page1.getPageTimings(); + assertNotNull("har page onLoad timing is null", timings1.getOnLoad()); + assertNotEquals("har page onLoad timing should be greater than 0", 0L, timings1.getOnLoad().longValue()); + + HarPage page2 = log.getPages().get(1); + assertEquals("incorrect har page id", "testpage2", page2.getId()); + assertEquals("incorrect har page id", page2.getId(), page2.getTitle()); + assertNotNull("har page timings are null", page2.getPageTimings()); + HarPageTimings timings2 = page2.getPageTimings(); + assertNotNull("har page onLoad timing is null", timings2.getOnLoad()); + assertNotEquals("har page onLoad timing should be greater than 0", 0L, timings2.getOnLoad().longValue()); + } @Test public void testHarPageTitlePopulated() throws Exception { @@ -359,79 +359,79 @@ public void testHarPageTitlePopulated() throws Exception { assertEquals("incorrect har page title", "Test Page 2", page2.getTitle()); } - @Test - public void testIpAddressPopulatedForLocalhost() throws IOException, InterruptedException { - proxy.newHar("testIpAddressPopulated"); + @Test + public void testIpAddressPopulatedForLocalhost() throws IOException, InterruptedException { + proxy.newHar("testIpAddressPopulated"); - HttpGet get = new HttpGet("http://localhost:8080/a.txt"); - IOUtils.toStringAndClose(client.execute(get).getEntity().getContent()); + HttpGet get = new HttpGet("http://localhost:8080/a.txt"); + IOUtils.toStringAndClose(client.execute(get).getEntity().getContent()); - proxy.endPage(); + proxy.endPage(); Thread.sleep(500); - Har har = proxy.getHar(); - assertNotNull("Har is null", har); - HarLog log = har.getLog(); - assertNotNull("Log is null", log); + Har har = proxy.getHar(); + assertNotNull("Har is null", har); + HarLog log = har.getLog(); + assertNotNull("Log is null", log); - List entries = log.getEntries(); - assertNotNull("Entries are null", entries); - assertThat("Entries are empty", entries, not(empty())); + List entries = log.getEntries(); + assertNotNull("Entries are null", entries); + assertThat("Entries are empty", entries, not(empty())); - HarEntry entry = log.getEntries().get(0); - assertNotNull("entry startedDateTime is null", entry.getStartedDateTime()); + HarEntry entry = log.getEntries().get(0); + assertNotNull("entry startedDateTime is null", entry.getStartedDateTime()); - assertEquals("entry pageref is incorrect", "testIpAddressPopulated", entry.getPageref()); + assertEquals("entry pageref is incorrect", "testIpAddressPopulated", entry.getPageref()); - assertEquals("entry ip address is not correct", "127.0.0.1", entry.getServerIPAddress()); + assertEquals("entry ip address is not correct", "127.0.0.1", entry.getServerIPAddress()); } - @Test - public void testIpAddressPopulatedForIpAddressUrl() throws IOException, InterruptedException { - proxy.newHar("testIpAddressPopulatedForIpAddressUrl"); + @Test + public void testIpAddressPopulatedForIpAddressUrl() throws IOException, InterruptedException { + proxy.newHar("testIpAddressPopulatedForIpAddressUrl"); HttpGet get = new HttpGet(getLocalServerHostnameAndPort() + "/a.txt"); - IOUtils.toStringAndClose(client.execute(get).getEntity().getContent()); + IOUtils.toStringAndClose(client.execute(get).getEntity().getContent()); - proxy.endPage(); + proxy.endPage(); Thread.sleep(500); - Har har = proxy.getHar(); - assertNotNull("Har is null", har); - HarLog log = har.getLog(); - assertNotNull("Log is null", log); + Har har = proxy.getHar(); + assertNotNull("Har is null", har); + HarLog log = har.getLog(); + assertNotNull("Log is null", log); - List entries = log.getEntries(); - assertNotNull("Entries are null", entries); - assertThat("Entries are empty", entries, not(empty())); + List entries = log.getEntries(); + assertNotNull("Entries are null", entries); + assertThat("Entries are empty", entries, not(empty())); - HarEntry entry = log.getEntries().get(0); - assertNotNull("entry startedDateTime is null", entry.getStartedDateTime()); + HarEntry entry = log.getEntries().get(0); + assertNotNull("entry startedDateTime is null", entry.getStartedDateTime()); - assertEquals("entry pageref is incorrect", "testIpAddressPopulatedForIpAddressUrl", entry.getPageref()); + assertEquals("entry pageref is incorrect", "testIpAddressPopulatedForIpAddressUrl", entry.getPageref()); - assertEquals("entry ip address is not correct", "127.0.0.1", entry.getServerIPAddress()); - } + assertEquals("entry ip address is not correct", "127.0.0.1", entry.getServerIPAddress()); + } - @Test - public void testNonChunkedRequestPayloadSizesAreSet() throws Exception { - proxy.setCaptureContent(true); - proxy.newHar("test"); + @Test + public void testNonChunkedRequestPayloadSizesAreSet() throws Exception { + proxy.setCaptureContent(true); + proxy.newHar("test"); - HttpPost post = new HttpPost(getLocalServerHostnameAndPort() + "/jsonrpc"); - String jsonRpcString = "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"test\",\"params\":{}}"; - HttpEntity entity = new StringEntity(jsonRpcString); - post.setEntity(entity); - post.addHeader("Accept", "application/json-rpc"); - post.addHeader("Content-Type", "application/json; charset=UTF-8"); + HttpPost post = new HttpPost(getLocalServerHostnameAndPort() + "/jsonrpc"); + String jsonRpcString = "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"test\",\"params\":{}}"; + HttpEntity entity = new StringEntity(jsonRpcString); + post.setEntity(entity); + post.addHeader("Accept", "application/json-rpc"); + post.addHeader("Content-Type", "application/json; charset=UTF-8"); - String body = IOUtils.toStringAndClose(client.execute(post).getEntity().getContent()); + String body = IOUtils.toStringAndClose(client.execute(post).getEntity().getContent()); Thread.sleep(500); - Har har = proxy.getHar(); - HarLog log = har.getLog(); - List entries = log.getEntries(); - HarEntry entry = entries.get(0); + Har har = proxy.getHar(); + HarLog log = har.getLog(); + List entries = log.getEntries(); + HarEntry entry = entries.get(0); /* Request headers should be something like this: @@ -439,40 +439,40 @@ public void testNonChunkedRequestPayloadSizesAreSet() throws Exception { Host: 127.0.0.1:8080 User-Agent: bmp.lightbody.net/2.0-beta-10-SNAPSHOT */ - assertThat("Minimum header size not seen", entry.getRequest().getHeadersSize(), greaterThan(70L)); - assertEquals("Body size does not match POST data size", jsonRpcString.length(), entry.getRequest().getBodySize()); - } + assertThat("Minimum header size not seen", entry.getRequest().getHeadersSize(), greaterThan(70L)); + assertEquals("Body size does not match POST data size", jsonRpcString.length(), entry.getRequest().getBodySize()); + } - @Test - public void testChunkedResponseBodySizeSet() throws Exception { - proxy.setCaptureContent(true); - proxy.newHar("test"); + @Test + public void testChunkedResponseBodySizeSet() throws Exception { + proxy.setCaptureContent(true); + proxy.newHar("test"); - HttpPost post = new HttpPost(getLocalServerHostnameAndPort() + "/echopayload"); - String lengthyPost = createRandomString(100000); + HttpPost post = new HttpPost(getLocalServerHostnameAndPort() + "/echopayload"); + String lengthyPost = createRandomString(100000); - HttpEntity entity = new StringEntity(lengthyPost); - post.setEntity(entity); - post.addHeader("Content-Type", "text/unknown; charset=UTF-8"); + HttpEntity entity = new StringEntity(lengthyPost); + post.setEntity(entity); + post.addHeader("Content-Type", "text/unknown; charset=UTF-8"); - String body = IOUtils.toStringAndClose(client.execute(post).getEntity().getContent()); + String body = IOUtils.toStringAndClose(client.execute(post).getEntity().getContent()); Thread.sleep(500); - Har har = proxy.getHar(); - HarLog log = har.getLog(); - List entries = log.getEntries(); - HarEntry entry = entries.get(0); - - assertEquals("Expected response size to equal the size of the echoed POST request", lengthyPost.length(), entry.getResponse().getBodySize()); - } - - private String createRandomString(int length) { - Random random = new Random(); - StringBuilder lengthyPost = new StringBuilder(length); - for (int i = 0; i < length; i++) { - lengthyPost.append((char)(random.nextInt(94) + 32)); - } - - return lengthyPost.toString(); - } + Har har = proxy.getHar(); + HarLog log = har.getLog(); + List entries = log.getEntries(); + HarEntry entry = entries.get(0); + + assertEquals("Expected response size to equal the size of the echoed POST request", lengthyPost.length(), entry.getResponse().getBodySize()); + } + + private String createRandomString(int length) { + Random random = new Random(); + StringBuilder lengthyPost = new StringBuilder(length); + for (int i = 0; i < length; i++) { + lengthyPost.append((char) (random.nextInt(94) + 32)); + } + + return lengthyPost.toString(); + } } diff --git a/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/MailingListIssuesTest.java b/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/MailingListIssuesTest.java index d99c5c07f..d9b4850d7 100644 --- a/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/MailingListIssuesTest.java +++ b/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/MailingListIssuesTest.java @@ -35,12 +35,7 @@ public void testThatInterceptorIsCalled() throws IOException, InterruptedExcepti assumeFalse(Boolean.getBoolean("bmp.use.littleproxy")); final boolean[] interceptorHit = {false}; - proxy.addRequestInterceptor(new RequestInterceptor() { - @Override - public void process(BrowserMobHttpRequest request, Har har) { - interceptorHit[0] = true; - } - }); + proxy.addRequestInterceptor((RequestInterceptor) (request, har) -> interceptorHit[0] = true); String body = IOUtils.toStringAndClose(client.execute(new HttpGet(getLocalServerHostnameAndPort() + "/a.txt")).getEntity().getContent()); diff --git a/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java b/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java index 58f93b8f4..30494f884 100644 --- a/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java +++ b/browsermob-legacy/src/test/java/net/lightbody/bmp/proxy/test/util/LocalServer.java @@ -4,15 +4,21 @@ import net.lightbody.bmp.proxy.test.servlet.EchoServlet; import net.lightbody.bmp.proxy.test.servlet.JsonServlet; import net.lightbody.bmp.proxy.test.servlet.SetCookieServlet; +import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.GzipHandler; +import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.handler.ResourceHandler; +import org.eclipse.jetty.server.handler.gzip.GzipHandler; +import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.resource.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.nio.file.Paths; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -42,17 +48,17 @@ public void start() { servletHandler.addServletWithMapping(EchoServlet.class, "/echo"); servletHandler.addServletWithMapping(EchoPayloadServlet.class, "/echopayload"); - handlers.addHandler(servletHandler); // create a ResourceHandler to serve up static resources from the classpath at /local-server ResourceHandler resourceHandler = new ResourceHandler(); resourceHandler.setBaseResource(Resource.newClassPathResource("/local-server")); - handlers.addHandler(resourceHandler); // wrap the other handlers in a GzipHandler that does not gzip anything by default GzipHandler gzipHandler = new GzipHandler(); gzipHandler.setMinGzipSize(Integer.MAX_VALUE); + handlers.addHandler(resourceHandler); + handlers.addHandler(servletHandler); gzipHandler.setHandler(handlers); server.setHandler(gzipHandler); @@ -63,7 +69,7 @@ public void start() { throw new RuntimeException("Could not start local Jetty server for tests", e); } - this.port = server.getConnectors()[0].getLocalPort(); + this.port = server.getURI().getPort(); started.set(true); } @@ -78,7 +84,7 @@ public int getPort() { } /** - * Forces the server to gzip all responses (see {@link org.eclipse.jetty.server.handler.GzipHandler} for response codes that will + * Forces the server to gzip all responses (see {@link org.eclipse.jetty.server.handler.gzip.GzipHandler} for response codes that will * be gzipped). */ public void forceGzip() { diff --git a/browsermob-rest/pom.xml b/browsermob-rest/pom.xml index cc04ac796..e86b81edf 100644 --- a/browsermob-rest/pom.xml +++ b/browsermob-rest/pom.xml @@ -40,19 +40,19 @@ com.google.inject guice - 3.0 + 4.2.2 com.google.inject.extensions guice-servlet - 3.0 + 4.2.2 com.google.inject.extensions guice-multibindings - 3.0 + 4.2.2 @@ -63,13 +63,13 @@ org.eclipse.jetty jetty-server - 7.3.0.v20110203 + 9.4.15.v20190215 org.eclipse.jetty jetty-servlet - 7.3.0.v20110203 + 9.4.15.v20190215 diff --git a/browsermob-rest/src/main/java/net/lightbody/bmp/proxy/guice/JettyServerProvider.java b/browsermob-rest/src/main/java/net/lightbody/bmp/proxy/guice/JettyServerProvider.java index 4584620ca..2fca0da09 100644 --- a/browsermob-rest/src/main/java/net/lightbody/bmp/proxy/guice/JettyServerProvider.java +++ b/browsermob-rest/src/main/java/net/lightbody/bmp/proxy/guice/JettyServerProvider.java @@ -4,13 +4,16 @@ import com.google.inject.Provider; import com.google.inject.name.Named; import com.google.inject.servlet.GuiceFilter; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.ServletContextHandler; +import javax.servlet.DispatcherType; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.EnumSet; + public class JettyServerProvider implements Provider { private Server server; @@ -22,7 +25,7 @@ public JettyServerProvider(@Named("port") int port, @Named("address") String add ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - context.addFilter(GuiceFilter.class, "/*", 0); + context.addFilter(GuiceFilter.class, "/*", EnumSet.allOf(DispatcherType.class)); context.addServlet(DefaultServlet.class, "/"); server.setHandler(context); From 8308350a4736be3f699e6aa0dd7c497fd1271f96 Mon Sep 17 00:00:00 2001 From: "kyrylo.bilchenko" Date: Mon, 1 Apr 2019 14:25:24 +0200 Subject: [PATCH 07/11] one moe small change --- .../proxy/jetty/jetty/servlet/ServletOut.java | 57 ++++++++----------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletOut.java b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletOut.java index 738c75f05..591db2e47 100644 --- a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletOut.java +++ b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/servlet/ServletOut.java @@ -23,76 +23,65 @@ import java.io.OutputStream; -class ServletOut extends ServletOutputStream -{ +class ServletOut extends ServletOutputStream { OutputStream _out; /* ------------------------------------------------------------ */ - ServletOut(OutputStream out) - { - _out=out; + ServletOut(OutputStream out) { + _out = out; } - + /* ------------------------------------------------------------ */ public void write(int ch) - throws IOException - { + throws IOException { _out.write(ch); } - + /* ------------------------------------------------------------ */ @Override - public void write(byte[]b) - throws IOException - { + public void write(byte[] b) + throws IOException { _out.write(b); } - + /* ------------------------------------------------------------ */ @Override - public void write(byte[]b,int o,int l) - throws IOException - { - _out.write(b,o,l); + public void write(byte[] b, int o, int l) + throws IOException { + _out.write(b, o, l); } /* ------------------------------------------------------------ */ @Override public void flush() - throws IOException - { + throws IOException { _out.flush(); } - + /* ------------------------------------------------------------ */ @Override public void close() - throws IOException - { + throws IOException { super.close(); _out.close(); } - + /* ------------------------------------------------------------ */ - public void disable() - throws IOException - { - _out=IO.getNullStream(); + public void disable() { + _out = IO.getNullStream(); } /* ------------------------------------------------------------ */ @Override - public void print(String s) throws IOException - { - if (s!=null) write(s.getBytes()); + public void print(String s) throws IOException { + if (s != null) write(s.getBytes()); } /* ------------------------------------------------------------ */ @Override - public void println(String s) throws IOException - { - if (s!=null) write(s.getBytes()); - write(IO.CRLF_BYTES); + public void println(String s) throws IOException { + if (s != null) write(s.getBytes()); + write(IO.CRLF_BYTES); } @Override From 1e6321c1ad9fd924cee3f62637eddb69679d7388 Mon Sep 17 00:00:00 2001 From: "kyrylo.bilchenko" Date: Mon, 1 Apr 2019 15:36:05 +0200 Subject: [PATCH 08/11] one more small improvement --- .../proxy/http/TrustingSSLSocketFactory.java | 13 +- .../bmp/proxy/jetty/jetty/Server.java | 631 +++++++++--------- .../bmp/proxy/jetty/util/Container.java | 302 ++++----- .../bmp/util/DeleteDirectoryTask.java | 4 +- 4 files changed, 466 insertions(+), 484 deletions(-) diff --git a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/http/TrustingSSLSocketFactory.java b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/http/TrustingSSLSocketFactory.java index 3b68802c5..bdf8bfa7a 100644 --- a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/http/TrustingSSLSocketFactory.java +++ b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/http/TrustingSSLSocketFactory.java @@ -34,16 +34,11 @@ public enum SSLAlgorithm { private StreamManager streamManager; static { - sslContext = SSLContexts.createDefault(); + sslContext = org.apache.http.ssl.SSLContexts.createDefault(); try { - sslContext = SSLContexts.custom().loadTrustMaterial(null, - new TrustStrategy() { - @Override - public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { - return true; - } - } - ).build(); + sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, + (TrustStrategy) (chain, authType) -> true + ).build(); sslContext.init(null, new TrustManager[]{new TrustEverythingSSLTrustManager()}, null); } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { diff --git a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/Server.java b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/Server.java index 6b04eafb6..d483f13ef 100644 --- a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/Server.java +++ b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/jetty/Server.java @@ -35,105 +35,104 @@ /* ------------------------------------------------------------ */ -/** The Jetty HttpServer. - * + +/** + * The Jetty HttpServer. + *

* This specialization of org.mortbay.http.HttpServer adds knowledge * about servlets and their specialized contexts. It also included * support for initialization from xml configuration files * that follow the XmlConfiguration dtd. - * + *

* HttpContexts created by Server are of the type * org.mortbay.jetty.servlet.ServletHttpContext unless otherwise * specified. - * + *

* This class also provides a main() method which starts a server for * each config file passed on the command line. If the system * property JETTY_NO_SHUTDOWN_HOOK is not set to true, then a shutdown - * hook is thread is registered to stop these servers. + * hook is thread is registered to stop these servers. * + * @author Greg Wilkins (gregw) + * @version $Revision: 1.40 $ * @see net.lightbody.bmp.proxy.jetty.xml.XmlConfiguration * @see net.lightbody.bmp.proxy.jetty.jetty.servlet.ServletHttpContext - * @version $Revision: 1.40 $ - * @author Greg Wilkins (gregw) */ -public class Server extends HttpServer -{ +public class Server extends HttpServer { static Log log = LogFactory.getLog(Server.class); - private String[] _webAppConfigurationClassNames = - new String[]{"XMLConfiguration", "JettyWebConfiguration"}; + private String[] _webAppConfigurationClassNames = + new String[]{"XMLConfiguration", "JettyWebConfiguration"}; private String _configuration; private String _rootWebApp; private static ShutdownHookThread hookThread = new ShutdownHookThread(); - + /* ------------------------------------------------------------ */ - /** Constructor. + + /** + * Constructor. */ - public Server() - { + public Server() { } - + /* ------------------------------------------------------------ */ - /** Constructor. + + /** + * Constructor. + * * @param configuration The filename or URL of the XML - * configuration file. + * configuration file. */ public Server(String configuration) - throws IOException - { + throws IOException { this(Resource.newResource(configuration).getURL()); } - + /* ------------------------------------------------------------ */ - /** Constructor. + + /** + * Constructor. + * * @param configuration The filename or URL of the XML - * configuration file. + * configuration file. */ public Server(Resource configuration) - throws IOException - { + throws IOException { this(configuration.getURL()); } - + /* ------------------------------------------------------------ */ - /** Constructor. + + /** + * Constructor. + * * @param configuration The filename or URL of the XML - * configuration file. + * configuration file. */ public Server(URL configuration) - throws IOException - { - _configuration=configuration.toString(); + throws IOException { + _configuration = configuration.toString(); Server.hookThread.add(this); - try - { - XmlConfiguration config=new XmlConfiguration(configuration); + try { + XmlConfiguration config = new XmlConfiguration(configuration); config.configure(this); - } - catch(IOException e) - { + } catch (IOException e) { throw e; - } - catch(InvocationTargetException e) - { - log.warn(LogSupport.EXCEPTION,e.getTargetException()); - throw new IOException("Jetty configuration problem: "+e.getTargetException()); - } - catch(Exception e) - { - log.warn(LogSupport.EXCEPTION,e); - throw new IOException("Jetty configuration problem: "+e); + } catch (InvocationTargetException e) { + log.warn(LogSupport.EXCEPTION, e.getTargetException()); + throw new IOException("Jetty configuration problem: " + e.getTargetException()); + } catch (Exception e) { + log.warn(LogSupport.EXCEPTION, e); + throw new IOException("Jetty configuration problem: " + e); } } /* ------------------------------------------------------------ */ - public boolean getStopAtShutdown() - { + public boolean getStopAtShutdown() { return hookThread.contains(this); } - + /* ------------------------------------------------------------ */ - public void setStopAtShutdown(boolean stop) - { + public void setStopAtShutdown(boolean stop) { if (stop) hookThread.add(this); else @@ -141,268 +140,283 @@ public void setStopAtShutdown(boolean stop) } /* ------------------------------------------------------------ */ - /** Get the root webapp name. - * @return The name of the root webapp (eg. "root" for root.war). + + /** + * Get the root webapp name. + * + * @return The name of the root webapp (eg. "root" for root.war). */ - public String getRootWebApp() - { + public String getRootWebApp() { return _rootWebApp; } - + /* ------------------------------------------------------------ */ - /** Set the root webapp name. - * @param rootWebApp The name of the root webapp (eg. "root" for root.war). + + /** + * Set the root webapp name. + * + * @param rootWebApp The name of the root webapp (eg. "root" for root.war). */ - public void setRootWebApp(String rootWebApp) - { + public void setRootWebApp(String rootWebApp) { _rootWebApp = rootWebApp; } - + /* ------------------------------------------------------------ */ - /** Configure the server from an XML file. + + /** + * Configure the server from an XML file. + * * @param configuration The filename or URL of the XML - * configuration file. + * configuration file. */ public void configure(String configuration) - throws IOException - { + throws IOException { - URL url=Resource.newResource(configuration).getURL(); - if (_configuration!=null && _configuration.equals(url.toString())) + URL url = Resource.newResource(configuration).getURL(); + if (_configuration != null && _configuration.equals(url.toString())) return; - if (_configuration!=null) - throw new IllegalStateException("Already configured with "+_configuration); - try - { - XmlConfiguration config=new XmlConfiguration(url); - _configuration=url.toString(); + if (_configuration != null) + throw new IllegalStateException("Already configured with " + _configuration); + try { + XmlConfiguration config = new XmlConfiguration(url); + _configuration = url.toString(); config.configure(this); - } - catch(IOException e) - { + } catch (IOException e) { throw e; - } - catch(Exception e) - { - log.warn(LogSupport.EXCEPTION,e); - throw new IOException("Jetty configuration problem: "+e); + } catch (Exception e) { + log.warn(LogSupport.EXCEPTION, e); + throw new IOException("Jetty configuration problem: " + e); } } - + /* ------------------------------------------------------------ */ - public String getConfiguration() - { + public String getConfiguration() { return _configuration; } - + /* ------------------------------------------------------------ */ - /** Create a new ServletHttpContext. + + /** + * Create a new ServletHttpContext. * Ths method is called by HttpServer to creat new contexts. Thus * calls to addContext or getContext that result in a new Context * being created will return an * org.mortbay.jetty.servlet.ServletHttpContext instance. + * * @return ServletHttpContext */ - protected HttpContext newHttpContext() - { + protected HttpContext newHttpContext() { return new ServletHttpContext(); } - + /* ------------------------------------------------------------ */ - /** Create a new WebApplicationContext. - * Ths method is called by Server to creat new contexts for web - * applications. Thus calls to addWebApplication that result in + + /** + * Create a new WebApplicationContext. + * Ths method is called by Server to creat new contexts for web + * applications. Thus calls to addWebApplication that result in * a new Context being created will return an correct class instance. * Derived class can override this method to create instance of its * own class derived from WebApplicationContext in case it needs more * functionality. + * * @param webApp The Web application directory or WAR file. * @return WebApplicationContext */ protected WebApplicationContext newWebApplicationContext( - String webApp - ) - { + String webApp + ) { return new WebApplicationContext(webApp); } /* ------------------------------------------------------------ */ - /** Add Web Application. + + /** + * Add Web Application. + * * @param contextPathSpec The context path spec. Which must be of - * the form / or /path/* - * @param webApp The Web application directory or WAR file. + * the form / or /path/* + * @param webApp The Web application directory or WAR file. * @return The WebApplicationContext - * @exception IOException + * @throws IOException */ public WebApplicationContext addWebApplication(String contextPathSpec, String webApp) - throws IOException - { - return addWebApplication(null,contextPathSpec,webApp); + throws IOException { + return addWebApplication(null, contextPathSpec, webApp); } - + /* ------------------------------------------------------------ */ - /** Add Web Application. - * @param virtualHost Virtual host name or null + + /** + * Add Web Application. + * + * @param virtualHost Virtual host name or null * @param contextPathSpec The context path spec. Which must be of - * the form / or /path/* - * @param webApp The Web application directory or WAR file. + * the form / or /path/* + * @param webApp The Web application directory or WAR file. * @return The WebApplicationContext - * @exception IOException + * @throws IOException */ public WebApplicationContext addWebApplication(String virtualHost, String contextPathSpec, String webApp) - throws IOException - { + throws IOException { WebApplicationContext appContext = - newWebApplicationContext(webApp); + newWebApplicationContext(webApp); appContext.setContextPath(contextPathSpec); - addContext(virtualHost,appContext); - if(log.isDebugEnabled())log.debug("Web Application "+appContext+" added"); + addContext(virtualHost, appContext); + if (log.isDebugEnabled()) log.debug("Web Application " + appContext + " added"); return appContext; } - + /* ------------------------------------------------------------ */ - /** Add Web Applications. + + /** + * Add Web Applications. * Add auto webapplications to the server. The name of the * webapp directory or war is used as the context name. If a * webapp is called "root" it is added at "/". + * * @param webapps Directory file name or URL to look for auto webapplication. - * @exception IOException + * @throws IOException */ public WebApplicationContext[] addWebApplications(String webapps) - throws IOException - { - return addWebApplications(null,webapps,null,false); + throws IOException { + return addWebApplications(null, webapps, null, false); } - + /* ------------------------------------------------------------ */ - /** Add Web Applications. + + /** + * Add Web Applications. * Add auto webapplications to the server. The name of the * webapp directory or war is used as the context name. If the * webapp matches the rootWebApp it is added as the "/" context. - * @param host Virtual host name or null + * + * @param host Virtual host name or null * @param webapps Directory file name or URL to look for auto webapplication. - * @exception IOException + * @throws IOException */ public WebApplicationContext[] addWebApplications(String host, String webapps) - throws IOException - { - return addWebApplications(host,webapps,null,false); + throws IOException { + return addWebApplications(host, webapps, null, false); } - + /* ------------------------------------------------------------ */ - /** Add Web Applications. + + /** + * Add Web Applications. * Add auto webapplications to the server. The name of the * webapp directory or war is used as the context name. If the * webapp matches the rootWebApp it is added as the "/" context. - * @param host Virtual host name or null + * + * @param host Virtual host name or null * @param webapps Directory file name or URL to look for auto - * webapplication. + * webapplication. * @param extract If true, extract war files - * @exception IOException + * @throws IOException */ public WebApplicationContext[] addWebApplications(String host, String webapps, boolean extract) - throws IOException - { - return addWebApplications(host,webapps,null,extract); + throws IOException { + return addWebApplications(host, webapps, null, extract); } - + /* ------------------------------------------------------------ */ - /** Add Web Applications. + + /** + * Add Web Applications. * Add auto webapplications to the server. The name of the * webapp directory or war is used as the context name. If the * webapp matches the rootWebApp it is added as the "/" context. - * @param host Virtual host name or null - * @param webapps Directory file name or URL to look for auto - * webapplication. + * + * @param host Virtual host name or null + * @param webapps Directory file name or URL to look for auto + * webapplication. * @param defaults The defaults xml filename or URL which is - * loaded before any in the web app. Must respect the web.dtd. - * If null the default defaults file is used. If the empty string, then - * no defaults file is used. - * @param extract If true, extract war files - * @exception IOException + * loaded before any in the web app. Must respect the web.dtd. + * If null the default defaults file is used. If the empty string, then + * no defaults file is used. + * @param extract If true, extract war files + * @throws IOException */ public WebApplicationContext[] addWebApplications(String host, String webapps, String defaults, boolean extract) - throws IOException - { - return addWebApplications(host,webapps,defaults,extract,true); + throws IOException { + return addWebApplications(host, webapps, defaults, extract, true); } /* ------------------------------------------------------------ */ - /** Add Web Applications. + + /** + * Add Web Applications. * Add auto webapplications to the server. The name of the * webapp directory or war is used as the context name. If the * webapp matches the rootWebApp it is added as the "/" context. - * @param host Virtual host name or null - * @param webapps Directory file name or URL to look for auto - * webapplication. - * @param defaults The defaults xml filename or URL which is - * loaded before any in the web app. Must respect the web.dtd. - * If null the default defaults file is used. If the empty string, then - * no defaults file is used. - * @param extract If true, extract war files + * + * @param host Virtual host name or null + * @param webapps Directory file name or URL to look for auto + * webapplication. + * @param defaults The defaults xml filename or URL which is + * loaded before any in the web app. Must respect the web.dtd. + * If null the default defaults file is used. If the empty string, then + * no defaults file is used. + * @param extract If true, extract war files * @param java2CompliantClassLoader True if java2 compliance is applied to all webapplications - * @exception IOException + * @throws IOException */ public WebApplicationContext[] addWebApplications(String host, String webapps, String defaults, boolean extract, - boolean java2CompliantClassLoader) - throws IOException - { + boolean java2CompliantClassLoader) + throws IOException { ArrayList wacs = new ArrayList(); - Resource r=Resource.newResource(webapps); + Resource r = Resource.newResource(webapps); if (!r.exists()) - throw new IllegalArgumentException("No such webapps resource "+r); - + throw new IllegalArgumentException("No such webapps resource " + r); + if (!r.isDirectory()) - throw new IllegalArgumentException("Not directory webapps resource "+r); - - String[] files=r.list(); - - for (int f=0;files!=null && f + * Thread is hooked first time list of servers is changed. */ - private void createShutdownHook() { - if (!Boolean.getBoolean("JETTY_NO_SHUTDOWN_HOOK") && !hooked) { - try { - Method shutdownHook = java.lang.Runtime.class.getMethod("addShutdownHook", - new Class[] { java.lang.Thread.class }); - shutdownHook.invoke(Runtime.getRuntime(), new Object[] { this }); - this.hooked = true; - } catch (Exception e) { - if (log.isDebugEnabled()) log.debug("No shutdown hook in JVM ", e); + private static class ShutdownHookThread extends Thread { + private boolean hooked = false; + private ArrayList servers = new ArrayList(); + + /** + * Hooks this thread for shutdown. + * + * @see java.lang.Runtime#addShutdownHook(java.lang.Thread) + */ + private void createShutdownHook() { + if (!Boolean.getBoolean("JETTY_NO_SHUTDOWN_HOOK") && !hooked) { + try { + Method shutdownHook = java.lang.Runtime.class.getMethod("addShutdownHook", + new Class[]{java.lang.Thread.class}); + shutdownHook.invoke(Runtime.getRuntime(), new Object[]{this}); + this.hooked = true; + } catch (Exception e) { + if (log.isDebugEnabled()) log.debug("No shutdown hook in JVM ", e); + } + } } - } - } - /** - * Add Server to servers list. - */ - public boolean add(Server server) { - createShutdownHook(); - return this.servers.add(server); - } - - /** - * Contains Server in servers list? - */ - public boolean contains(Server server) { - return this.servers.contains(server); - } + /** + * Add Server to servers list. + */ + public boolean add(Server server) { + createShutdownHook(); + return this.servers.add(server); + } - /** - * Append all Servers from Collection - */ - public boolean addAll(Collection c) { - createShutdownHook(); - return this.servers.addAll(c); - } + /** + * Contains Server in servers list? + */ + public boolean contains(Server server) { + return this.servers.contains(server); + } - /** - * Clear list of Servers. - */ - public void clear() { - createShutdownHook(); - this.servers.clear(); - } + /** + * Append all Servers from Collection + */ + public boolean addAll(Collection c) { + createShutdownHook(); + return this.servers.addAll(c); + } - /** - * Remove Server from list. - */ - public boolean remove(Server server) { - createShutdownHook(); - return this.servers.remove(server); - } + /** + * Clear list of Servers. + */ + public void clear() { + createShutdownHook(); + this.servers.clear(); + } - /** - * Remove all Servers in Collection from list. - */ - public boolean removeAll(Collection c) { - createShutdownHook(); - return this.servers.removeAll(c); - } + /** + * Remove Server from list. + */ + public boolean remove(Server server) { + createShutdownHook(); + return this.servers.remove(server); + } - /** - * Stop all Servers in list. - */ - public void run() { - setName("Shutdown"); - log.info("Shutdown hook executing"); - Iterator it = servers.iterator(); - while (it.hasNext()) { - Server svr = (Server) it.next(); - if (svr == null) continue; - try { - svr.stop(); - } catch (Exception e) { - log.warn(LogSupport.EXCEPTION, e); + /** + * Remove all Servers in Collection from list. + */ + public boolean removeAll(Collection c) { + createShutdownHook(); + return this.servers.removeAll(c); } - log.info("Shutdown hook complete"); - // Try to avoid JVM crash - try { - Thread.sleep(1000); - } catch (Exception e) { - log.warn(LogSupport.EXCEPTION, e); + /** + * Stop all Servers in list. + */ + public void run() { + setName("Shutdown"); + log.info("Shutdown hook executing"); + Iterator it = servers.iterator(); + while (it.hasNext()) { + Server svr = (Server) it.next(); + if (svr == null) continue; + try { + svr.stop(); + } catch (Exception e) { + log.warn(LogSupport.EXCEPTION, e); + } + log.info("Shutdown hook complete"); + + // Try to avoid JVM crash + try { + Thread.sleep(1000); + } catch (Exception e) { + log.warn(LogSupport.EXCEPTION, e); + } + } } - } } - } } diff --git a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/util/Container.java b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/util/Container.java index 1c2782f22..251caa7af 100644 --- a/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/util/Container.java +++ b/browsermob-legacy/src/main/java/net/lightbody/bmp/proxy/jetty/util/Container.java @@ -28,283 +28,259 @@ /* ------------------------------------------------------------ */ -/** Abstract Container. + +/** + * Abstract Container. * Provides base handling for LifeCycle and Component events. * - * @version $Id: Container.java,v 1.4 2005/08/13 08:49:59 gregwilkins Exp $ * @author Greg Wilkins (gregw) + * @version $Id: Container.java,v 1.4 2005/08/13 08:49:59 gregwilkins Exp $ */ -public abstract class Container implements LifeCycle,EventProvider,Serializable -{ +public abstract class Container implements LifeCycle, EventProvider, Serializable { private static Log log = LogFactory.getLog(Container.class); - + private Object _eventListeners; private Object _components; - + private transient boolean _started; private transient boolean _starting; private transient boolean _stopping; - + /* ------------------------------------------------------------ */ - /** Start the server. + + /** + * Start the server. * Generate LifeCycleEvents for starting and started either side of a call to doStart */ public synchronized final void start() - throws Exception - { + throws Exception { if (_started || _starting) return; - - _starting=true; - - if (log.isDebugEnabled()) log.debug("Starting "+this); + + _starting = true; + + if (log.isDebugEnabled()) log.debug("Starting " + this); LifeCycleEvent event = new LifeCycleEvent(this); - for(int i=0;i() { @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { try { Files.delete(file); } catch (IOException e) { @@ -43,7 +43,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO } @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + public FileVisitResult postVisitDirectory(Path dir, IOException exc) { try { Files.delete(dir); } catch (IOException e) { From 8c7d90b07598a0857f2be82de0bb70f4a54c987a Mon Sep 17 00:00:00 2001 From: "kyrylo.bilchenko" Date: Mon, 1 Apr 2019 16:50:50 +0200 Subject: [PATCH 09/11] Snapshot version promotion --- README.md | 2 +- browsermob-core/pom.xml | 2 +- browsermob-dist/pom.xml | 2 +- browsermob-legacy/pom.xml | 2 +- browsermob-rest/pom.xml | 2 +- mitm/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f86633c7a..5344e8834 100644 --- a/README.md +++ b/README.md @@ -395,7 +395,7 @@ When you build the latest code from source, you'll have access to the latest sna net.lightbody.bmp browsermob-core - 2.1.20 + 2.1.21-SNAPSHOT test ``` diff --git a/browsermob-core/pom.xml b/browsermob-core/pom.xml index 71a9cbb1d..be9ae53b8 100644 --- a/browsermob-core/pom.xml +++ b/browsermob-core/pom.xml @@ -6,7 +6,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.20 + 2.1.21-SNAPSHOT 4.0.0 diff --git a/browsermob-dist/pom.xml b/browsermob-dist/pom.xml index 5aba96f02..f0a0b1777 100644 --- a/browsermob-dist/pom.xml +++ b/browsermob-dist/pom.xml @@ -4,7 +4,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.20 + 2.1.21-SNAPSHOT 4.0.0 diff --git a/browsermob-legacy/pom.xml b/browsermob-legacy/pom.xml index a5711ec5e..b7ba3e377 100644 --- a/browsermob-legacy/pom.xml +++ b/browsermob-legacy/pom.xml @@ -6,7 +6,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.20 + 2.1.21-SNAPSHOT 4.0.0 diff --git a/browsermob-rest/pom.xml b/browsermob-rest/pom.xml index e86b81edf..21e2d9ca8 100644 --- a/browsermob-rest/pom.xml +++ b/browsermob-rest/pom.xml @@ -5,7 +5,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.20 + 2.1.21-SNAPSHOT 4.0.0 diff --git a/mitm/pom.xml b/mitm/pom.xml index 70979319e..1133e6ce2 100644 --- a/mitm/pom.xml +++ b/mitm/pom.xml @@ -4,7 +4,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.20 + 2.1.21-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index d3cc06e58..58224509d 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.lightbody.bmp browsermob-proxy - 2.1.20 + 2.1.21-SNAPSHOT browsermob-core browsermob-legacy From e371d0de5e5e862dadb0839b221935428afd46c7 Mon Sep 17 00:00:00 2001 From: "kyrylo.bilchenko" Date: Tue, 2 Apr 2019 11:02:40 +0200 Subject: [PATCH 10/11] small changes in har --- README.md | 2 +- browsermob-core/pom.xml | 2 +- .../java/net/lightbody/bmp/filters/HarCaptureFilter.java | 5 ++--- browsermob-dist/pom.xml | 2 +- browsermob-legacy/pom.xml | 2 +- browsermob-rest/pom.xml | 2 +- mitm/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5344e8834..059cc6ac1 100644 --- a/README.md +++ b/README.md @@ -395,7 +395,7 @@ When you build the latest code from source, you'll have access to the latest sna net.lightbody.bmp browsermob-core - 2.1.21-SNAPSHOT + 2.1.21 test ``` diff --git a/browsermob-core/pom.xml b/browsermob-core/pom.xml index be9ae53b8..7b032a20c 100644 --- a/browsermob-core/pom.xml +++ b/browsermob-core/pom.xml @@ -6,7 +6,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.21-SNAPSHOT + 2.1.21 4.0.0 diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java b/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java index 7072bb984..684ccb659 100644 --- a/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java +++ b/browsermob-core/src/main/java/net/lightbody/bmp/filters/HarCaptureFilter.java @@ -260,10 +260,9 @@ public HttpObject serverToProxyResponse(HttpObject httpObject) { } harEntry.getResponse().setBodySize(responseBodySize.get()); + logFailedRequestIfRequired(harEntry.getRequest(), harEntry.getResponse()); } - - logFailedRequestIfRequired(harEntry.getRequest(), harEntry.getResponse()); - + return super.serverToProxyResponse(httpObject); } diff --git a/browsermob-dist/pom.xml b/browsermob-dist/pom.xml index f0a0b1777..ef6e33a97 100644 --- a/browsermob-dist/pom.xml +++ b/browsermob-dist/pom.xml @@ -4,7 +4,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.21-SNAPSHOT + 2.1.21 4.0.0 diff --git a/browsermob-legacy/pom.xml b/browsermob-legacy/pom.xml index b7ba3e377..eae18aa65 100644 --- a/browsermob-legacy/pom.xml +++ b/browsermob-legacy/pom.xml @@ -6,7 +6,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.21-SNAPSHOT + 2.1.21 4.0.0 diff --git a/browsermob-rest/pom.xml b/browsermob-rest/pom.xml index 21e2d9ca8..d24386aea 100644 --- a/browsermob-rest/pom.xml +++ b/browsermob-rest/pom.xml @@ -5,7 +5,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.21-SNAPSHOT + 2.1.21 4.0.0 diff --git a/mitm/pom.xml b/mitm/pom.xml index 1133e6ce2..93898a028 100644 --- a/mitm/pom.xml +++ b/mitm/pom.xml @@ -4,7 +4,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.21-SNAPSHOT + 2.1.21 4.0.0 diff --git a/pom.xml b/pom.xml index 58224509d..02cf5e9bd 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.lightbody.bmp browsermob-proxy - 2.1.21-SNAPSHOT + 2.1.21 browsermob-core browsermob-legacy From 39407e229a1803cd030a19183bc1dc4f28c65ff4 Mon Sep 17 00:00:00 2001 From: "kyrylo.bilchenko" Date: Tue, 2 Apr 2019 11:06:29 +0200 Subject: [PATCH 11/11] pormote snapshot --- README.md | 2 +- browsermob-core/pom.xml | 2 +- browsermob-dist/pom.xml | 2 +- browsermob-legacy/pom.xml | 2 +- browsermob-rest/pom.xml | 2 +- mitm/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 059cc6ac1..429d6e8fb 100644 --- a/README.md +++ b/README.md @@ -395,7 +395,7 @@ When you build the latest code from source, you'll have access to the latest sna net.lightbody.bmp browsermob-core - 2.1.21 + 2.1.22-SNAPSHOT test ``` diff --git a/browsermob-core/pom.xml b/browsermob-core/pom.xml index 7b032a20c..943519f11 100644 --- a/browsermob-core/pom.xml +++ b/browsermob-core/pom.xml @@ -6,7 +6,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.21 + 2.1.22-SNAPSHOT 4.0.0 diff --git a/browsermob-dist/pom.xml b/browsermob-dist/pom.xml index ef6e33a97..9116c0b59 100644 --- a/browsermob-dist/pom.xml +++ b/browsermob-dist/pom.xml @@ -4,7 +4,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.21 + 2.1.22-SNAPSHOT 4.0.0 diff --git a/browsermob-legacy/pom.xml b/browsermob-legacy/pom.xml index eae18aa65..593e98eca 100644 --- a/browsermob-legacy/pom.xml +++ b/browsermob-legacy/pom.xml @@ -6,7 +6,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.21 + 2.1.22-SNAPSHOT 4.0.0 diff --git a/browsermob-rest/pom.xml b/browsermob-rest/pom.xml index d24386aea..6f75ea6ff 100644 --- a/browsermob-rest/pom.xml +++ b/browsermob-rest/pom.xml @@ -5,7 +5,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.21 + 2.1.22-SNAPSHOT 4.0.0 diff --git a/mitm/pom.xml b/mitm/pom.xml index 93898a028..125fc87e0 100644 --- a/mitm/pom.xml +++ b/mitm/pom.xml @@ -4,7 +4,7 @@ browsermob-proxy net.lightbody.bmp - 2.1.21 + 2.1.22-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index 02cf5e9bd..bbd259c8e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.lightbody.bmp browsermob-proxy - 2.1.21 + 2.1.22-SNAPSHOT browsermob-core browsermob-legacy