{"action":"created","comment":{"url":"https://api.github.com/repos/mulesoft/mule/pulls/comments/29679811","id":29679811,"diff_hunk":"@@ -0,0 +1,240 @@\n+/*\n+ * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com\n+ * The software in this package is published under the terms of the CPAL v1.0\n+ * license, a copy of which has been included with this distribution in the\n+ * LICENSE.txt file.\n+ */\n+package org.mule.module.http.functional.requester;\n+\n+import org.apache.commons.lang.StringUtils;\n+import org.glassfish.grizzly.Connection;\n+import org.glassfish.grizzly.Grizzly;\n+import org.glassfish.grizzly.attributes.Attribute;\n+import org.glassfish.grizzly.filterchain.FilterChainBuilder;\n+import org.glassfish.grizzly.http.server.AddOn;\n+import org.glassfish.grizzly.http.server.HttpServer;\n+import org.glassfish.grizzly.http.server.NetworkListener;\n+import org.glassfish.grizzly.sni.SNIConfig;\n+import org.glassfish.grizzly.sni.SNIFilter;\n+import org.glassfish.grizzly.sni.SNIServerConfigResolver;\n+import org.glassfish.grizzly.ssl.SSLBaseFilter;\n+import org.glassfish.grizzly.ssl.SSLContextConfigurator;\n+import org.glassfish.grizzly.ssl.SSLEngineConfigurator;\n+import org.junit.*;\n+import org.mule.MessageExchangePattern;\n+import org.mule.api.MessagingException;\n+import org.mule.api.MuleEvent;\n+import org.mule.api.security.tls.TlsConfiguration;\n+import org.mule.construct.Flow;\n+import org.mule.tck.MuleTestUtils;\n+import org.mule.tck.junit4.FunctionalTestCase;\n+import org.mule.tck.junit4.rule.DynamicPort;\n+import org.mule.util.ClassUtils;\n+\n+import java.io.File;\n+import java.io.IOException;\n+import java.io.PrintWriter;\n+import java.net.InetAddress;\n+import java.net.URL;\n+import java.util.concurrent.atomic.AtomicReference;\n+\n+import static org.hamcrest.CoreMatchers.notNullValue;\n+import static org.hamcrest.core.Is.is;\n+import static org.junit.Assert.assertThat;\n+import static org.junit.Assume.assumeThat;\n+\n+public class HttpsRequesterSniTestCase extends FunctionalTestCase\n+{\n+    private static final String FQDN = \"localhost.localdomain\";\n+\n+    private static final String SERVER_PROTOCOL_ENABLED = \"SSLv3,TLSv1,TLSv1.1,TLSv1.2\";\n+\n+    @Rule\n+    public DynamicPort httpsPort = new DynamicPort(\"httpsPort\");\n+\n+    private Server server;\n+\n+    @Override\n+    protected String getConfigFile()\n+    {\n+        return \"http-request-sni-config.xml\";\n+    }\n+\n+    @BeforeClass\n+    public static void createTlsPropertiesFile() throws Exception\n+    {\n+        PrintWriter writer = new PrintWriter(getTlsPropertiesFile(), \"UTF-8\");\n+        writer.println(\"enabledProtocols=\" + SERVER_PROTOCOL_ENABLED);\n+        writer.close();\n+    }\n+\n+    @AfterClass\n+    public static void removeTlsPropertiesFile()\n+    {\n+        getTlsPropertiesFile().delete();\n+    }\n+\n+    private static File getTlsPropertiesFile()\n+    {\n+        String path = ClassUtils.getClassPathRoot(HttpsRequesterSniTestCase.class).getPath();\n+        return new File(path, String.format(TlsConfiguration.PROPERTIES_FILE_PATTERN, TlsConfiguration.DEFAULT_SECURITY_MODEL));\n+    }\n+\n+    @Before\n+    public void prepareServer() throws IOException\n+    {\n+        server = new Server(httpsPort.getNumber());\n+        server.startServer();\n+    }\n+\n+    @After\n+    public void teardownServer() {\n+        if (server != null)\n+        {\n+            server.stopServer();\n+        }\n+    }\n+\n+    @Test(expected = MessagingException.class)\n+    public void testClientSNINotSentOnNonFQDN() throws Exception\n+    {\n+        runFlow(\"requestFlowLocalhost\", MuleTestUtils.getTestEvent(\"testData\", MessageExchangePattern.REQUEST_RESPONSE, muleContext));\n+    }\n+\n+    /*\n+     * SNI requires a fully qualified domain name. \"localhost.localdomain\" is used but it is not commonly present\n+     * on MacOSX hosts. An assumption will prevent its execution unless the domain exists. Although is recommended to\n+     * add the aforementioned domain to the /etc/ file if it's not present.\n+     */\n+    @Test\n+    public void testClientSNISentOnFQDN() throws Exception\n+    {\n+        InetAddress address = null;\n+        try\n+        {\n+            address = InetAddress.getByName(FQDN);\n+        }\n+        catch (Exception e) {}\n+\n+        assumeThat(address, is(notNullValue()));\n+\n+        runFlow(\"requestFlowFQDN\", MuleTestUtils.getTestEvent(\"testData\", MessageExchangePattern.REQUEST_RESPONSE, muleContext));\n+        assertThat(server.getHostname(), is(FQDN));\n+    }\n+\n+    /**\n+     * Executes the given flow with the given {@code event}\n+     *\n+     * @param flowName the name of the flow to be executed\n+     * @param event the event which we'll use to execute the flow\n+     * @return the resulting <code>MuleEvent</code>\n+     * @throws Exception\n+     */\n+    protected MuleEvent runFlow(String flowName, MuleEvent event) throws Exception\n+    {\n+        Flow flow = lookupFlowConstruct(flowName);\n+        return flow.process(event);\n+    }\n+\n+    /**\n+     * Embedded HTTPS server that fails to serve if SNI extension is not honored\n+     */\n+    public class Server\n+    {\n+        HttpServer webServer;\n+        final AtomicReference<String> sniHostname;\n+        int port;\n+\n+        SSLEngineConfigurator sslServerEngineConfig;\n+\n+        public Server(int port)\n+        {\n+            sniHostname = new AtomicReference<String>();\n+            this.port = port;\n+        }\n+\n+        protected void startServer() throws IOException\n+        {\n+            NetworkListener networkListener = new NetworkListener(\"sample-listener\", \"localhost\", port);\n+\n+            sslServerEngineConfig = new SSLEngineConfigurator(createSSLContextConfigurator().createSSLContext(), false, false, false);\n+            networkListener.setSSLEngineConfig(sslServerEngineConfig);\n+\n+            webServer = HttpServer.createSimpleServer();\n+            webServer.addListener(networkListener);\n+            networkListener.setSecure(true);\n+            networkListener.registerAddOn(new SniAddOn());\n+            webServer.start();\n+        }\n+\n+        protected void stopServer()\n+        {\n+            sniHostname.set(StringUtils.EMPTY);\n+            webServer.shutdownNow();\n+        }\n+\n+        private SNIFilter getSniFilter()\n+        {\n+            final Attribute<String> sniHostAttr = Grizzly.DEFAULT_ATTRIBUTE_BUILDER.createAttribute(\"sni-host-attr\");\n+\n+            SNIFilter sniFilter = new SNIFilter();\n+            sniFilter.setServerSSLConfigResolver(new SNIServerConfigResolver()\n+            {\n+                @Override\n+                public SNIConfig resolve(Connection connection, String hostname)\n+                {\n+                    sniHostAttr.set(connection, hostname);\n+                    sniHostname.set(hostname);\n+                    if (StringUtils.isEmpty(hostname))\n+                    {\n+                        throw new IllegalArgumentException(\"SNI Has not been sent\");\n+                    }\n+                    return SNIConfig.newServerConfig(sslServerEngineConfig);\n+                }\n+            });\n+            return sniFilter;\n+        }\n+\n+        private SSLContextConfigurator createSSLContextConfigurator()\n+        {\n+            SSLContextConfigurator sslContextConfigurator = new SSLContextConfigurator();\n+            ClassLoader cl = HttpsRequesterSniTestCase.class.getClassLoader();\n+\n+            URL cacertsUrl = cl.getResource(\"sni-server-truststore.jks\");","path":"modules/http/src/test/java/org/mule/module/http/functional/requester/HttpsRequesterSniTestCase.java","position":201,"original_position":203,"commit_id":"561d9e431999dd2b44b8003c9f6397c3aa512435","original_commit_id":"626724d1959d2629224657105c067a007f4ee3a5","user":{"login":"afelisatti","id":3932724,"avatar_url":"https://avatars.githubusercontent.com/u/3932724?v=3","gravatar_id":"","url":"https://api.github.com/users/afelisatti","html_url":"https://github.com/afelisatti","followers_url":"https://api.github.com/users/afelisatti/followers","following_url":"https://api.github.com/users/afelisatti/following{/other_user}","gists_url":"https://api.github.com/users/afelisatti/gists{/gist_id}","starred_url":"https://api.github.com/users/afelisatti/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/afelisatti/subscriptions","organizations_url":"https://api.github.com/users/afelisatti/orgs","repos_url":"https://api.github.com/users/afelisatti/repos","events_url":"https://api.github.com/users/afelisatti/events{/privacy}","received_events_url":"https://api.github.com/users/afelisatti/received_events","type":"User","site_admin":false},"body":"Right, makes sense.","created_at":"2015-05-05T15:28:52Z","updated_at":"2015-05-05T15:28:52Z","html_url":"https://github.com/mulesoft/mule/pull/1686#discussion_r29679811","pull_request_url":"https://api.github.com/repos/mulesoft/mule/pulls/1686","_links":{"self":{"href":"https://api.github.com/repos/mulesoft/mule/pulls/comments/29679811"},"html":{"href":"https://github.com/mulesoft/mule/pull/1686#discussion_r29679811"},"pull_request":{"href":"https://api.github.com/repos/mulesoft/mule/pulls/1686"}}},"pull_request":{"url":"https://api.github.com/repos/mulesoft/mule/pulls/1686","id":34727581,"html_url":"https://github.com/mulesoft/mule/pull/1686","diff_url":"https://github.com/mulesoft/mule/pull/1686.diff","patch_url":"https://github.com/mulesoft/mule/pull/1686.patch","issue_url":"https://api.github.com/repos/mulesoft/mule/issues/1686","number":1686,"state":"open","locked":false,"title":"MULE-8265 Test support for TLS SNI Extension in Http Module Requester","user":{"login":"vromero","id":1119553,"avatar_url":"https://avatars.githubusercontent.com/u/1119553?v=3","gravatar_id":"","url":"https://api.github.com/users/vromero","html_url":"https://github.com/vromero","followers_url":"https://api.github.com/users/vromero/followers","following_url":"https://api.github.com/users/vromero/following{/other_user}","gists_url":"https://api.github.com/users/vromero/gists{/gist_id}","starred_url":"https://api.github.com/users/vromero/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vromero/subscriptions","organizations_url":"https://api.github.com/users/vromero/orgs","repos_url":"https://api.github.com/users/vromero/repos","events_url":"https://api.github.com/users/vromero/events{/privacy}","received_events_url":"https://api.github.com/users/vromero/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-05-05T14:08:55Z","updated_at":"2015-05-05T15:28:52Z","closed_at":null,"merged_at":null,"merge_commit_sha":"74dec3a46f7f04068d1b29bd4eabc02cddc41a8b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/mulesoft/mule/pulls/1686/commits","review_comments_url":"https://api.github.com/repos/mulesoft/mule/pulls/1686/comments","review_comment_url":"https://api.github.com/repos/mulesoft/mule/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mulesoft/mule/issues/1686/comments","statuses_url":"https://api.github.com/repos/mulesoft/mule/statuses/561d9e431999dd2b44b8003c9f6397c3aa512435","head":{"label":"mulesoft:MULE-8265","ref":"MULE-8265","sha":"561d9e431999dd2b44b8003c9f6397c3aa512435","user":{"login":"mulesoft","id":185740,"avatar_url":"https://avatars.githubusercontent.com/u/185740?v=3","gravatar_id":"","url":"https://api.github.com/users/mulesoft","html_url":"https://github.com/mulesoft","followers_url":"https://api.github.com/users/mulesoft/followers","following_url":"https://api.github.com/users/mulesoft/following{/other_user}","gists_url":"https://api.github.com/users/mulesoft/gists{/gist_id}","starred_url":"https://api.github.com/users/mulesoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mulesoft/subscriptions","organizations_url":"https://api.github.com/users/mulesoft/orgs","repos_url":"https://api.github.com/users/mulesoft/repos","events_url":"https://api.github.com/users/mulesoft/events{/privacy}","received_events_url":"https://api.github.com/users/mulesoft/received_events","type":"Organization","site_admin":false},"repo":{"id":7058562,"name":"mule","full_name":"mulesoft/mule","owner":{"login":"mulesoft","id":185740,"avatar_url":"https://avatars.githubusercontent.com/u/185740?v=3","gravatar_id":"","url":"https://api.github.com/users/mulesoft","html_url":"https://github.com/mulesoft","followers_url":"https://api.github.com/users/mulesoft/followers","following_url":"https://api.github.com/users/mulesoft/following{/other_user}","gists_url":"https://api.github.com/users/mulesoft/gists{/gist_id}","starred_url":"https://api.github.com/users/mulesoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mulesoft/subscriptions","organizations_url":"https://api.github.com/users/mulesoft/orgs","repos_url":"https://api.github.com/users/mulesoft/repos","events_url":"https://api.github.com/users/mulesoft/events{/privacy}","received_events_url":"https://api.github.com/users/mulesoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mulesoft/mule","description":"Mule Community Edition","fork":false,"url":"https://api.github.com/repos/mulesoft/mule","forks_url":"https://api.github.com/repos/mulesoft/mule/forks","keys_url":"https://api.github.com/repos/mulesoft/mule/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mulesoft/mule/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mulesoft/mule/teams","hooks_url":"https://api.github.com/repos/mulesoft/mule/hooks","issue_events_url":"https://api.github.com/repos/mulesoft/mule/issues/events{/number}","events_url":"https://api.github.com/repos/mulesoft/mule/events","assignees_url":"https://api.github.com/repos/mulesoft/mule/assignees{/user}","branches_url":"https://api.github.com/repos/mulesoft/mule/branches{/branch}","tags_url":"https://api.github.com/repos/mulesoft/mule/tags","blobs_url":"https://api.github.com/repos/mulesoft/mule/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mulesoft/mule/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mulesoft/mule/git/refs{/sha}","trees_url":"https://api.github.com/repos/mulesoft/mule/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mulesoft/mule/statuses/{sha}","languages_url":"https://api.github.com/repos/mulesoft/mule/languages","stargazers_url":"https://api.github.com/repos/mulesoft/mule/stargazers","contributors_url":"https://api.github.com/repos/mulesoft/mule/contributors","subscribers_url":"https://api.github.com/repos/mulesoft/mule/subscribers","subscription_url":"https://api.github.com/repos/mulesoft/mule/subscription","commits_url":"https://api.github.com/repos/mulesoft/mule/commits{/sha}","git_commits_url":"https://api.github.com/repos/mulesoft/mule/git/commits{/sha}","comments_url":"https://api.github.com/repos/mulesoft/mule/comments{/number}","issue_comment_url":"https://api.github.com/repos/mulesoft/mule/issues/comments{/number}","contents_url":"https://api.github.com/repos/mulesoft/mule/contents/{+path}","compare_url":"https://api.github.com/repos/mulesoft/mule/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mulesoft/mule/merges","archive_url":"https://api.github.com/repos/mulesoft/mule/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mulesoft/mule/downloads","issues_url":"https://api.github.com/repos/mulesoft/mule/issues{/number}","pulls_url":"https://api.github.com/repos/mulesoft/mule/pulls{/number}","milestones_url":"https://api.github.com/repos/mulesoft/mule/milestones{/number}","notifications_url":"https://api.github.com/repos/mulesoft/mule/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mulesoft/mule/labels{/name}","releases_url":"https://api.github.com/repos/mulesoft/mule/releases{/id}","created_at":"2012-12-07T19:23:06Z","updated_at":"2015-05-04T22:21:08Z","pushed_at":"2015-05-05T15:27:41Z","git_url":"git://github.com/mulesoft/mule.git","ssh_url":"git@github.com:mulesoft/mule.git","clone_url":"https://github.com/mulesoft/mule.git","svn_url":"https://github.com/mulesoft/mule","homepage":null,"size":434545,"stargazers_count":185,"watchers_count":185,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":250,"mirror_url":null,"open_issues_count":16,"forks":250,"open_issues":16,"watchers":185,"default_branch":"mule-3.x"}},"base":{"label":"mulesoft:mule-3.x","ref":"mule-3.x","sha":"675b6464a45d97d609195e300f9ece9e4fecd4c6","user":{"login":"mulesoft","id":185740,"avatar_url":"https://avatars.githubusercontent.com/u/185740?v=3","gravatar_id":"","url":"https://api.github.com/users/mulesoft","html_url":"https://github.com/mulesoft","followers_url":"https://api.github.com/users/mulesoft/followers","following_url":"https://api.github.com/users/mulesoft/following{/other_user}","gists_url":"https://api.github.com/users/mulesoft/gists{/gist_id}","starred_url":"https://api.github.com/users/mulesoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mulesoft/subscriptions","organizations_url":"https://api.github.com/users/mulesoft/orgs","repos_url":"https://api.github.com/users/mulesoft/repos","events_url":"https://api.github.com/users/mulesoft/events{/privacy}","received_events_url":"https://api.github.com/users/mulesoft/received_events","type":"Organization","site_admin":false},"repo":{"id":7058562,"name":"mule","full_name":"mulesoft/mule","owner":{"login":"mulesoft","id":185740,"avatar_url":"https://avatars.githubusercontent.com/u/185740?v=3","gravatar_id":"","url":"https://api.github.com/users/mulesoft","html_url":"https://github.com/mulesoft","followers_url":"https://api.github.com/users/mulesoft/followers","following_url":"https://api.github.com/users/mulesoft/following{/other_user}","gists_url":"https://api.github.com/users/mulesoft/gists{/gist_id}","starred_url":"https://api.github.com/users/mulesoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mulesoft/subscriptions","organizations_url":"https://api.github.com/users/mulesoft/orgs","repos_url":"https://api.github.com/users/mulesoft/repos","events_url":"https://api.github.com/users/mulesoft/events{/privacy}","received_events_url":"https://api.github.com/users/mulesoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mulesoft/mule","description":"Mule Community Edition","fork":false,"url":"https://api.github.com/repos/mulesoft/mule","forks_url":"https://api.github.com/repos/mulesoft/mule/forks","keys_url":"https://api.github.com/repos/mulesoft/mule/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mulesoft/mule/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mulesoft/mule/teams","hooks_url":"https://api.github.com/repos/mulesoft/mule/hooks","issue_events_url":"https://api.github.com/repos/mulesoft/mule/issues/events{/number}","events_url":"https://api.github.com/repos/mulesoft/mule/events","assignees_url":"https://api.github.com/repos/mulesoft/mule/assignees{/user}","branches_url":"https://api.github.com/repos/mulesoft/mule/branches{/branch}","tags_url":"https://api.github.com/repos/mulesoft/mule/tags","blobs_url":"https://api.github.com/repos/mulesoft/mule/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mulesoft/mule/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mulesoft/mule/git/refs{/sha}","trees_url":"https://api.github.com/repos/mulesoft/mule/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mulesoft/mule/statuses/{sha}","languages_url":"https://api.github.com/repos/mulesoft/mule/languages","stargazers_url":"https://api.github.com/repos/mulesoft/mule/stargazers","contributors_url":"https://api.github.com/repos/mulesoft/mule/contributors","subscribers_url":"https://api.github.com/repos/mulesoft/mule/subscribers","subscription_url":"https://api.github.com/repos/mulesoft/mule/subscription","commits_url":"https://api.github.com/repos/mulesoft/mule/commits{/sha}","git_commits_url":"https://api.github.com/repos/mulesoft/mule/git/commits{/sha}","comments_url":"https://api.github.com/repos/mulesoft/mule/comments{/number}","issue_comment_url":"https://api.github.com/repos/mulesoft/mule/issues/comments{/number}","contents_url":"https://api.github.com/repos/mulesoft/mule/contents/{+path}","compare_url":"https://api.github.com/repos/mulesoft/mule/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mulesoft/mule/merges","archive_url":"https://api.github.com/repos/mulesoft/mule/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mulesoft/mule/downloads","issues_url":"https://api.github.com/repos/mulesoft/mule/issues{/number}","pulls_url":"https://api.github.com/repos/mulesoft/mule/pulls{/number}","milestones_url":"https://api.github.com/repos/mulesoft/mule/milestones{/number}","notifications_url":"https://api.github.com/repos/mulesoft/mule/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mulesoft/mule/labels{/name}","releases_url":"https://api.github.com/repos/mulesoft/mule/releases{/id}","created_at":"2012-12-07T19:23:06Z","updated_at":"2015-05-04T22:21:08Z","pushed_at":"2015-05-05T15:27:41Z","git_url":"git://github.com/mulesoft/mule.git","ssh_url":"git@github.com:mulesoft/mule.git","clone_url":"https://github.com/mulesoft/mule.git","svn_url":"https://github.com/mulesoft/mule","homepage":null,"size":434545,"stargazers_count":185,"watchers_count":185,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":250,"mirror_url":null,"open_issues_count":16,"forks":250,"open_issues":16,"watchers":185,"default_branch":"mule-3.x"}},"_links":{"self":{"href":"https://api.github.com/repos/mulesoft/mule/pulls/1686"},"html":{"href":"https://github.com/mulesoft/mule/pull/1686"},"issue":{"href":"https://api.github.com/repos/mulesoft/mule/issues/1686"},"comments":{"href":"https://api.github.com/repos/mulesoft/mule/issues/1686/comments"},"review_comments":{"href":"https://api.github.com/repos/mulesoft/mule/pulls/1686/comments"},"review_comment":{"href":"https://api.github.com/repos/mulesoft/mule/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mulesoft/mule/pulls/1686/commits"},"statuses":{"href":"https://api.github.com/repos/mulesoft/mule/statuses/561d9e431999dd2b44b8003c9f6397c3aa512435"}}}}