Added tests for HTTP method script matching
diff --git a/test/java/org/apache/sling/junit/teleporter/customizers/ITCustomizer.java b/test/java/org/apache/sling/junit/teleporter/customizers/ITCustomizer.java
index 1ec4d79..a5ad300 100644
--- a/test/java/org/apache/sling/junit/teleporter/customizers/ITCustomizer.java
+++ b/test/java/org/apache/sling/junit/teleporter/customizers/ITCustomizer.java
@@ -17,12 +17,11 @@
 package org.apache.sling.junit.teleporter.customizers;
 
 import org.apache.sling.junit.rules.TeleporterRule;
-import org.apache.sling.testing.clients.util.TimeoutsProvider;
 import org.apache.sling.testing.teleporter.client.ClientSideTeleporter;
 
 public class ITCustomizer implements TeleporterRule.Customizer {
 
-    public static final String BASE_URL_PROP = "ClientSideTeleporter.baseUrl";
+    public static final String BASE_URL_PROP = "launchpad.http.server.url";
 
     @Override
     public void customize(TeleporterRule t, String options) {
@@ -30,6 +29,6 @@
         cst.setBaseUrl(System.getProperty(BASE_URL_PROP, BASE_URL_PROP + "_IS_NOT_SET"));
         cst.setServerCredentials("admin", "admin");
         cst.includeDependencyPrefix("org.apache.sling.scripting.resolver.internal");
-        cst.setTestReadyTimeoutSeconds(TimeoutsProvider.getInstance().getTimeout(5));
+        cst.setTestReadyTimeoutSeconds(20);
     }
-}
\ No newline at end of file
+}
diff --git a/test/java/org/apache/sling/scripting/resolver/internal/AbstractEndpointIT.java b/test/java/org/apache/sling/scripting/resolver/internal/AbstractEndpointIT.java
new file mode 100644
index 0000000..aad08f4
--- /dev/null
+++ b/test/java/org/apache/sling/scripting/resolver/internal/AbstractEndpointIT.java
@@ -0,0 +1,148 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License.  You may obtain a copy of the License at
+ ~
+ ~   http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied.  See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scripting.resolver.internal;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpOptions;
+import org.apache.http.client.methods.HttpPatch;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.methods.HttpTrace;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.sling.junit.teleporter.customizers.ITCustomizer;
+import org.apache.sling.testing.junit.rules.SlingInstanceRule;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+
+
+public abstract class AbstractEndpointIT {
+
+    protected int contentFindTimeout = 20000;
+    protected int contentFindRetryDelay = 1000;
+    private static CloseableHttpClient httpClient;
+
+    @ClassRule
+    public static final SlingInstanceRule SLING_INSTANCE_RULE = new SlingInstanceRule();
+
+    private Map<String, Document> documentMap = new ConcurrentHashMap<>();
+
+    @BeforeClass
+    public static void setUp() {
+        httpClient = HttpClientBuilder.create().build();
+    }
+
+    @AfterClass
+    public static void tearDown() throws IOException {
+        httpClient.close();
+    }
+
+    /**
+     * Retrieves a jsoup Document from the passed {@code url}. The URL can contain selectors and extensions, but it has to identify a Sling
+     * content {@link org.apache.sling.api.resource.Resource}.
+     *
+     * @param url the URL from which to retrieve the {@link Document}
+     * @return the Document
+     * @throws Exception if the resource was not found before the timeout elapsed
+     */
+    protected Document getDocument(String url) throws Exception {
+        return getDocument(url, HttpGet.METHOD_NAME);
+    }
+
+    protected Document getDocument(String url, String httpMethod, NameValuePair... parameters) throws Exception {
+        URIBuilder uriBuilder = new URIBuilder(url);
+        uriBuilder.setParameters(parameters);
+        URI uri = uriBuilder.build();
+        Document document = documentMap.get(httpMethod + ":" + uri.toString());
+        if (document == null) {
+            HttpResponse response = getResponse(httpMethod, url, 200);
+            document = Jsoup.parse(response.getEntity().getContent(), StandardCharsets.UTF_8.name(),
+                    System.getProperty(ITCustomizer.BASE_URL_PROP, ITCustomizer.BASE_URL_PROP +
+                            "_IS_NOT_SET"));
+            documentMap.put(httpMethod + ":" + uri, document);
+        }
+        return document;
+    }
+
+    protected HttpResponse getResponse(String method, String url, int statusCode, NameValuePair... parameters) throws Exception {
+        String resourcePath = url.substring(0, url.indexOf('.'));
+        SLING_INSTANCE_RULE.getAdminClient().waitExists(resourcePath, contentFindTimeout, contentFindRetryDelay);
+        HttpUriRequest request = prepareRequest(method, url, parameters);
+        HttpResponse response = httpClient.execute(request);
+        Assert.assertNotNull(response);
+        Assert.assertEquals("URL " + url + " did not return a " + statusCode + " status code.", statusCode,
+                response.getStatusLine().getStatusCode
+                        ());
+        return response;
+    }
+
+    protected HttpUriRequest prepareRequest(String method, String url, NameValuePair... parameters) throws URISyntaxException {
+        HttpRequestBase request = null;
+        URIBuilder uriBuilder =
+                new URIBuilder(System.getProperty(ITCustomizer.BASE_URL_PROP, ITCustomizer.BASE_URL_PROP + "_IS_NOT_SET") + url);
+        uriBuilder.setParameters(parameters);
+        switch (method) {
+            case HttpGet.METHOD_NAME:
+                request = new HttpGet(uriBuilder.build());
+                break;
+            case HttpHead.METHOD_NAME:
+                request = new HttpHead(uriBuilder.build());
+                break;
+            case HttpOptions.METHOD_NAME:
+                request = new HttpOptions(uriBuilder.build());
+                break;
+            case HttpPost.METHOD_NAME:
+                request = new HttpPost(uriBuilder.build());
+                break;
+            case HttpPut.METHOD_NAME:
+                request = new HttpPut(uriBuilder.build());
+                break;
+            case HttpPatch.METHOD_NAME:
+                request = new HttpPatch(uriBuilder.build());
+                break;
+            case HttpTrace.METHOD_NAME:
+                request = new HttpTrace(uriBuilder.build());
+                break;
+            case HttpDelete.METHOD_NAME:
+                request = new HttpDelete(uriBuilder.build());
+                break;
+        }
+        return request;
+    }
+
+}
diff --git a/test/java/org/apache/sling/scripting/resolver/internal/EndpointIT.java b/test/java/org/apache/sling/scripting/resolver/internal/EndpointIT.java
index df78b5b..585a4cd 100644
--- a/test/java/org/apache/sling/scripting/resolver/internal/EndpointIT.java
+++ b/test/java/org/apache/sling/scripting/resolver/internal/EndpointIT.java
@@ -16,70 +16,39 @@
  */
 package org.apache.sling.scripting.resolver.internal;
 
-import java.io.IOException;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.sling.testing.clients.SlingClient;
-import org.apache.sling.testing.junit.rules.SlingInstanceRule;
-import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
 import org.junit.Test;
 
-import static org.apache.sling.junit.teleporter.customizers.ITCustomizer.BASE_URL_PROP;
-
-public class EndpointIT {
-
-    @ClassRule
-    public static final SlingInstanceRule SLING_INSTANCE_RULE = new SlingInstanceRule();
-
-    @BeforeClass
-    public static void before() throws Exception {
-        SlingClient client = SLING_INSTANCE_RULE.getAdminClient();
-        client.waitExists("/content/srr/examples/hello", 20 * 1000, 1000);
-        client.waitExists("/content/srr/examples/hello-v1", 20 * 1000, 1000);
-        client.waitExists("/content/srr/examples/hello-v2", 20 * 1000, 1000);
-        client.waitExists("/content/srr/examples/hi", 20 * 1000, 1000);
-        client.waitExists("/content/srr/examples/hi-v1", 20 * 1000, 1000);
-    }
+public class EndpointIT extends AbstractEndpointIT {
 
     @Test
-    public void testHelloEndpoint() throws IOException, InterruptedException {
-        Document document = get("content/srr/examples/hello.html", 200);
-
+    public void testHelloEndpoint() throws Exception {
+        Document document = getDocument("/content/srr/examples/hello.html");
         Assert.assertEquals("We're testing some serious scripting here in Version 2", document.select("h2").html());
         Assert.assertTrue(document.body().html().contains("World2"));
         Assert.assertTrue(document.body().html().contains("Hello2"));
     }
 
     @Test
-    public void testHelloEndpointV1() throws IOException, InterruptedException {
-        Document document = get("content/srr/examples/hello-v1.html", 200);
-
+    public void testHelloEndpointV1() throws Exception {
+        Document document = getDocument("content/srr/examples/hello-v1.html");
         Assert.assertEquals("We're testing some serious scripting here", document.select("h2").html());
         Assert.assertTrue(document.body().html().contains("World"));
         Assert.assertTrue(document.body().html().contains("Hello"));
     }
 
     @Test
-    public void testHelloEndpointV2() throws IOException, InterruptedException {
-        Document document = get("content/srr/examples/hello-v2.html", 200);
-
+    public void testHelloEndpointV2() throws Exception {
+        Document document = getDocument("content/srr/examples/hello-v2.html");
         Assert.assertEquals("We're testing some serious scripting here in Version 2", document.select("h2").html());
         Assert.assertTrue(document.body().html().contains("World2"));
         Assert.assertTrue(document.body().html().contains("Hello2"));
     }
 
     @Test
-    public void testHiEndpoint() throws IOException, InterruptedException {
-        Document document = get("content/srr/examples/hi.html", 200);
-
+    public void testHiEndpoint() throws Exception {
+        Document document = getDocument("content/srr/examples/hi.html");
         Assert.assertEquals("We're testing some serious scripting here", document.select("h2").html());
         Assert.assertTrue(document.body().html().contains("World"));
         Assert.assertTrue(document.body().html().contains("Hallo"));
@@ -87,27 +56,11 @@
     }
 
     @Test
-    public void testHiEndpointV1() throws IOException, InterruptedException {
-        Document document = get("content/srr/examples/hi-v1.html", 200);
-
+    public void testHiEndpointV1() throws Exception {
+        Document document = getDocument("content/srr/examples/hi-v1.html");
         Assert.assertEquals("We're testing some serious scripting here", document.select("h2").html());
         Assert.assertTrue(document.body().html().contains("World"));
         Assert.assertTrue(document.body().html().contains("Hallo"));
         Assert.assertFalse(document.body().html().contains("Hello"));
     }
-
-    private Document get(String path, long expected) throws IOException, InterruptedException {
-        HttpClient client = HttpClientBuilder.create().build();
-        HttpGet get = new HttpGet(System.getProperty(BASE_URL_PROP, BASE_URL_PROP + "_IS_NOT_SET") + path);
-        RequestConfig requestConfig = RequestConfig.custom()
-                .setSocketTimeout(1000)
-                .setConnectTimeout(1000)
-                .setConnectionRequestTimeout(1000)
-                .build();
-        get.setConfig(requestConfig);
-        HttpResponse response = client.execute(get);
-        Assert.assertNotNull(response);
-        Assert.assertEquals(expected, response.getStatusLine().getStatusCode());
-        return Jsoup.parse(response.getEntity().getContent(), "UTF-8", System.getProperty(BASE_URL_PROP, BASE_URL_PROP + "_IS_NOT_SET"));
-    }
 }
diff --git a/test/java/org/apache/sling/scripting/resolver/internal/ScriptMatchIT.java b/test/java/org/apache/sling/scripting/resolver/internal/ScriptMatchIT.java
new file mode 100644
index 0000000..217ee59
--- /dev/null
+++ b/test/java/org/apache/sling/scripting/resolver/internal/ScriptMatchIT.java
@@ -0,0 +1,88 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License.  You may obtain a copy of the License at
+ ~
+ ~   http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied.  See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scripting.resolver.internal;
+
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpOptions;
+import org.apache.http.client.methods.HttpPatch;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpTrace;
+import org.jsoup.nodes.Document;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ScriptMatchIT extends AbstractEndpointIT {
+
+    @Test
+    public void testGETMethodMatching() throws Exception {
+        testHttpMethodScriptMatching("/content/srr/examples/script-matching.html", HttpGet.METHOD_NAME);
+    }
+
+    @Test
+    public void testHEADMethodMatching() throws Exception {
+        HttpResponse response = getResponse(HttpHead.METHOD_NAME, "/content/srr/examples/script-matching.html", 200);
+        Header[] header = response.getHeaders("X-Script-Name");
+        assertEquals("Expected to find one X-Script-Name header.", 1, header.length);
+        assertEquals("/javax.script/org.apache.sling.scripting.examplebundle.scriptmatching/1.0.0/HEAD.html", header[0].getValue());
+    }
+
+    @Test
+    public void testOPTIONSMethodMatching() throws Exception {
+        testHttpMethodScriptMatching("/content/srr/examples/script-matching.html", HttpOptions.METHOD_NAME);
+    }
+
+    @Test
+    public void testPOSTMethodMatching() throws Exception {
+        testHttpMethodScriptMatching("/content/srr/examples/script-matching.html", HttpPost.METHOD_NAME);
+    }
+
+    @Test
+    public void testPATCHMethodMatching() throws Exception {
+        testHttpMethodScriptMatching("/content/srr/examples/script-matching.html", HttpPatch.METHOD_NAME);
+    }
+
+    @Test
+    public void testPUTMethodMatching() throws Exception {
+        testHttpMethodScriptMatching("/content/srr/examples/script-matching.html", HttpPut.METHOD_NAME);
+    }
+
+    @Test
+    public void testDELETEMethodMatching() throws Exception {
+        testHttpMethodScriptMatching("/content/srr/examples/script-matching.html", HttpDelete.METHOD_NAME);
+    }
+
+    @Test
+    public void testTRACEMethodMatching() throws Exception {
+        testHttpMethodScriptMatching("/content/srr/examples/script-matching.html", HttpTrace.METHOD_NAME);
+    }
+
+    private void testHttpMethodScriptMatching(String url, String httpMethod) throws Exception {
+        Document document = getDocument(url, httpMethod);
+        assertTrue(document.select("div").html().contains(String.format("/javax.script/org.apache.sling.scripting.examplebundle" +
+                ".scriptmatching/1.0.0/%s.html matched", httpMethod)));
+    }
+
+}
diff --git a/test/provisioning/it-model.txt b/test/provisioning/it-model.txt
index 9ed3807..41c4539 100644
--- a/test/provisioning/it-model.txt
+++ b/test/provisioning/it-model.txt
@@ -26,3 +26,7 @@
   org.apache.sling/org.apache.sling.scripting.examplebundle
   org.apache.sling/org.apache.sling.scripting.examplebundle.hi
   org.apache.sling/org.apache.sling.junit.core/1.0.26
+
+[configurations]
+  org.apache.sling.engine.impl.SlingMainServlet
+    sling.trace.allow=B"true"