Jump to content

Making SNI-Requests with httpclient


This topic is 2251 days old. Please don't post here. Open a new topic instead.

Recommended Posts

  • Newbies

Hi there,

I need to make https requests to server with SNI-support. Therefore I'm using Apaches httpclient libray. Since version 4.3.2 the library does support requests to servers with SNI enabled. I added the needed jar libraries to Scriptmaster and I'm using following Script for testing purposes (can be found here):

 * ====================================================================
 * 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
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * ====================================================================
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.

package org.apache.http.examples.client;

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

 * This example demonstrates the use of the {@link ResponseHandler} to simplify
 * the process of processing the HTTP response and releasing associated resources.
public class ClientWithResponseHandler {

    public final static void main(String[] args) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpGet httpget = new HttpGet("https://sni.velox.ch/");

            System.out.println("Executing request " + httpget.getRequestLine());

            // Create a custom response handler
            ResponseHandler<String> responseHandler = new ResponseHandler<String>() {

                public String handleResponse(
                        final HttpResponse response) throws ClientProtocolException, IOException {
                    int status = response.getStatusLine().getStatusCode();
                    if (status >= 200 && status < 300) {
                        HttpEntity entity = response.getEntity();
                        return entity != null ? EntityUtils.toString(entity) : null;
                    } else {
                        throw new ClientProtocolException("Unexpected response status: " + status);

            String responseBody = httpclient.execute(httpget, responseHandler);
        } finally {


Outside of Scriptmaster, this script works as expected (using Groovy 2.4 and JRE 1.8). But running it within Scriptmaster it throws an SSLPeerUnverifiedException:

Caused by: javax.net.ssl.SSLPeerUnverifiedException: Host name 'sni.velox.ch' does not match the certificate subject provided by the peer (CN=alice.sni.velox.ch, O=Kaspar Brand, L=Zuerich, ST=Zuerich, C=CH)
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:465)
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:395)
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
	at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
	at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:220)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:164)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:139)
	at org.apache.http.client.HttpClient$execute.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
	at org.apache.http.examples.client.ClientWithResponseHandler.main(Script1.groovy:70)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)

I'm using Scriptmaster 4.42, httpclient 4.5.2

Can you give me any hint what's going on here?

Thanks, Timo

Link to comment
Share on other sites

This works...


import org.apache.http.HttpEntity
import org.apache.http.HttpResponse
import org.apache.http.client.ClientProtocolException
import org.apache.http.client.ResponseHandler
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
import org.apache.http.util.EntityUtils

httpclient = HttpClients.createDefault()
httpget = new HttpGet('https://alice.sni.velox.ch/')

ResponseHandler responseHandler = new ResponseHandler(){

	handleResponse (HttpResponse response){
	status = response.getStatusLine().getStatusCode()
		if (status >= 200 && status < 300) {
			entity = response.getEntity()
			return entity != null ? EntityUtils.toString(entity) : null
		} else {
			 throw new Exception("Unexpected response status: " + status)
		} //end if
	} //end handleResponse
} //end responseHandler

responseBody = httpclient.execute(httpget, responseHandler)
return responseBody


Link to comment
Share on other sites

  • Newbies

You called "https://alice.sni.velox.ch" and not https://sni.velox.ch. If you look in the response text you can see, that your client didn't send the required SNI extension. The host provides the SSL certificate for alice.sni.velox.ch by default. With SNI any call to https://bob.sni.velox.ch/ or https://sni.velox.ch/ should work too and the server could provide the correct certificate for each host. Without SNI the server can't do that.

More information to SNI can be found here: https://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI

I tested the whole behaviour with a new Scriptmaster.fm12 file, added the script and the jar libraries for httpclient 4.5.

Link to comment
Share on other sites

This topic is 2251 days old. Please don't post here. Open a new topic instead.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Create New...

Important Information

By using this site, you agree to our Terms of Use.