how to know apache httpclient is using what version of SSL - ssl

we are using org.apache.httpcomponents.httpclient(v4.5.4) to connect to another service. However, the service has now disabled TLS1.0. How can I know what is default SSL/TLS version supported.
Here is how the code snippet where httpclient object is created :
private CloseableHttpClient getHttpClient() {
// always create new httpclient instance when factory is not available
// e.g. junit test suite
if (httpClientBuilderFactory == null
|| httpClientBuilderFactory.newBuilder() == null) {
sc = SocketConfig.custom()
.setSoTimeout(HTTP_SOCKET_TIMEOUT_SECONDS * 1000).build();
httpClient = HttpClients.custom().setDefaultSocketConfig(sc).build();
}
if (httpClient == null) {
clientConnectionManager = new PoolingHttpClientConnectionManager(210L,TimeUnit.SECONDS);
sc = SocketConfig.custom()
.setSoTimeout(HTTP_SOCKET_TIMEOUT_SECONDS * 1000).build();
clientConnectionManager.setDefaultMaxPerRoute(20);
HttpClientBuilder httpClientBuilder = httpClientBuilderFactory
.newBuilder();
httpClientBuilder.setDefaultSocketConfig(sc);
httpClientBuilder.setConnectionManager(clientConnectionManager);
httpClientBuilder.setConnectionManagerShared(true);
httpClient = httpClientBuilder.build();
}
return httpClient;
}

HttpClient 4.5.x
One would need a custom response interceptor to get access the underlying connection and pull the SSL session associated with it.
CloseableHttpClient httpclient = HttpClients.custom()
.addInterceptorLast(new HttpResponseInterceptor() {
#Override
public void process(HttpResponse response, HttpContext context) throws HttpException, IOException {
HttpClientContext clientContext = HttpClientContext.adapt(context);
ManagedHttpClientConnection connection = clientContext.getConnection(ManagedHttpClientConnection.class);
SSLSession sslSession = connection.getSSLSession();
if (sslSession != null) {
System.out.println("SSL protocol " + sslSession.getProtocol());
System.out.println("SSL cipher suite " + sslSession.getCipherSuite());
}
}
})
.build();
try {
HttpGet httpget = new HttpGet("https://httpbin.org/");
System.out.println("Executing request " + httpget.getRequestLine());
HttpClientContext clientContext = HttpClientContext.create();
CloseableHttpResponse response = httpclient.execute(httpget, clientContext);
try {
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
EntityUtils.consume(entity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
HttpClient 5.0
As of 5.0 one can pull the SSL session directly from the HTTP execution context.
try (CloseableHttpClient httpclient = HttpClients.custom().build()) {
final HttpGet httpget = new HttpGet("https://httpbin.org/");
System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri());
final HttpClientContext clientContext = HttpClientContext.create();
try (CloseableHttpResponse response = httpclient.execute(httpget, clientContext)) {
System.out.println("----------------------------------------");
System.out.println(response.getCode() + " " + response.getReasonPhrase());
EntityUtils.consume(response.getEntity());
final SSLSession sslSession = clientContext.getSSLSession();
if (sslSession != null) {
System.out.println("SSL protocol " + sslSession.getProtocol());
System.out.println("SSL cipher suite " + sslSession.getCipherSuite());
}
}
}

Related

How to connect to a url using broken ssl from the windows form using httpclient

I have implemented httpClientFactory but can't connect to the backend api using broken ssl.I tried a lot and i just got the task cancelled error -> HttpClient - A task was cancelled?
I have tried to set this
public static HttpClient getHttpClient()
{
if (_httpClient == null)
{
Uri baseUri = new Uri(Url.baseUrl);
if (baseUri.Scheme == "http")
{
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback =
(httpRequestMessage, cert, cetChain, policyErrors) =>
{
return true;
};
_httpClient = new HttpClient(handler);
}
else
{
_httpClient = new HttpClient();
}
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
_httpClient.BaseAddress = baseUri;
}
return _httpClient;
}

Can't get WCF WebCannelFactory BeforeSendRequest to work

The first code block returns a good request. The second returns a fault. Please advise.
The first code block returns information about a customer, and it uses OAuth2. The second block uses an interceptor. The problem is that when I use a WebChannelFactory and look at my request in trace, it shows (compared to a good request) that everything (the body of the request) is put into the message block. In a good request, the body of my request, is put into the soap message.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading.Tasks;
namespace Ahcccs.Isd.Aes.Breaz.Core.WCF.SOAP
{
public class ConsumeGetVendorLookup
{
public void Consume(string wso2token)
{
Header header = new Header();
header.Type = "?";
header.ReturnCode = "?";
header.Requestor = "?";
header.Recipient = "?";
header.Date = "?";
Requestor requestor = new Requestor();
requestor.UserID = "";
requestor.Password = "";
header.Subject = requestor;
Payload payload = new Payload();
GetVendorCustomerIn getVendorCustomer = new GetVendorCustomerIn();
getVendorCustomer.IncludeGeneralInfo = true;
getVendorCustomer.IncludeHeadquarters = true;
getVendorCustomer.IncludePrenote_EFT = true;
getVendorCustomer.IncludePrenote_EFTSpecified = true;
getVendorCustomer.Vendor_Customer = "{our customer number}";
payload.GetVendorCustomerIn = getVendorCustomer;
AdvMessage advMessage = new AdvMessage();
advMessage.Header = header;
advMessage.Payload = payload;
GetVendorCustomer customer = new GetVendorCustomer();
customer.AdvMessage = advMessage;
VendorServicesClient wcfClient = new VendorServicesClient();
var s = wcfClient.State;
wcfClient.Open();
using (new OperationContextScope(wcfClient.InnerChannel))
{
WebProxy wproxy = new WebProxy(new Uri("http://{our proxy server and port}"), true);
wproxy.BypassProxyOnLocal = true;
wproxy.UseDefaultCredentials = true;
WebRequest.DefaultWebProxy = wproxy;
// Add a HTTP Header to an outgoing request
HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
requestMessage.Headers["Authorization"] = " Bearer " + wso2token;
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
var result = wcfClient.getVendorCustomer(customer);
}
}
}
}
This one returns a fault:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
using System.Text;
using System.Threading.Tasks;
namespace Ahcccs.Isd.Aes.Breaz.Core.WCF.SOAP
{
public class ConsumeGetVendorLookup
{
public void Consume(string wso2token)
{
Header header = new Header();
header.Type = "?";
header.ReturnCode = "?";
header.Requestor = "?";
header.Recipient = "?";
header.Date = "?";
Requestor requestor = new Requestor();
requestor.UserID = "";
requestor.Password = "";
header.Subject = requestor;
Payload payload = new Payload();
GetVendorCustomerIn getVendorCustomer = new GetVendorCustomerIn();
getVendorCustomer.IncludeGeneralInfo = true;
getVendorCustomer.IncludeHeadquarters = true;
getVendorCustomer.IncludePrenote_EFT = true;
getVendorCustomer.IncludePrenote_EFTSpecified = true;
getVendorCustomer.Vendor_Customer = "{our customer number}";
payload.GetVendorCustomerIn = getVendorCustomer;
AdvMessage advMessage = new AdvMessage();
advMessage.Header = header;
advMessage.Payload = payload;
GetVendorCustomer customer = new GetVendorCustomer();
customer.AdvMessage = advMessage;
getVendorCustomerRequest customerReq = new getVendorCustomerRequest();
customerReq.getVendorCustomer = customer;
//VendorServicesClient wcfClient = new VendorServicesClient();
//var s = wcfClient.State;
//wcfClient.Open();
var wcfClient = new WebChannelFactory<VendorServicesChannel>(
new Uri("{the target uri}"));
//var s = wcfClient.State;
//wcfClient.Open();
wcfClient.Endpoint.EndpointBehaviors.Add(new AuthenticationHeaderBehavior("txtUser", "txtPass", wso2token));
//using (new OperationContextScope(wcfClient.InnerChannel))
//{
// WebProxy wproxy = new WebProxy(new Uri("our proxy server and port"), true);
// wproxy.BypassProxyOnLocal = true;
// wproxy.UseDefaultCredentials = true;
// WebRequest.DefaultWebProxy = wproxy;
// // Add a HTTP Header to an outgoing request
// HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
// requestMessage.Headers["Authorization"] = " Bearer " + wso2token;
// OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
// var result = wcfClient.getVendorCustomer(customer);
//}
var proxy = wcfClient.CreateChannel();
using ((IDisposable)proxy)
using (OperationContextScope c = new OperationContextScope((IContextChannel)proxy))
{
//WebProxy wproxy = new WebProxy(new Uri("our proxy server and port"), true);
//wproxy.BypassProxyOnLocal = true;
//wproxy.UseDefaultCredentials = true;
//WebRequest.DefaultWebProxy = wproxy;
//Add a HTTP Header to an outgoing request
//HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
//requestMessage.Headers["Authorization"] = " Bearer " + wso2token;
//OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
var result = proxy.getVendorCustomer(customerReq);
}
}
}
public class AuthenticationHeader : IClientMessageInspector
{
#region Implementation of IClientMessageInspector
string itsUser;
string itsPass;
string itsToken;
public AuthenticationHeader(string user, string pass, string token)
{
itsUser = user;
itsPass = pass;
itsToken = token;
}
public object BeforeSendRequest(ref Message request,
IClientChannel channel)
{
//HttpRequestMessageProperty hrmp = request.Properties["httpRequest"] as HttpRequestMessageProperty;
//string encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(itsUser + ":" + itsPass));
//hrmp.Headers.Add("Authorization", "Basic " + encoded);
//return request;
//HttpRequestMessageProperty hrmp = request.Properties["httpRequest"] as HttpRequestMessageProperty;
//hrmp.Headers.Add("Authorization", " Bearer " + itsToken);
//HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
//requestMessage.Headers["Authorization"] = " Bearer " + itsToken;
//OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
//return request;
WebProxy wproxy = new WebProxy(new Uri("our proxy server and port"), true);
wproxy.BypassProxyOnLocal = true;
wproxy.UseDefaultCredentials = true;
WebRequest.DefaultWebProxy = wproxy;
//// Add a HTTP Header to an outgoing request
HttpRequestMessageProperty hrmp = request.Properties["httpRequest"] as HttpRequestMessageProperty;
hrmp.Headers["Authorization"] = " Bearer " + itsToken;
return request;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
//Console.WriteLine("Received the following reply: '{0}'", reply.ToString());
}
#endregion
}
public class AuthenticationHeaderBehavior : IEndpointBehavior
{
#region Implementation of IEndpointBehavior
readonly string itsUser;
readonly string itsPass;
readonly string itsToken;
public AuthenticationHeaderBehavior(string user, string pass, string token)
: base()
{
itsUser = user;
itsPass = pass;
itsToken = token;
}
public void Validate(ServiceEndpoint endpoint) { }
public void AddBindingParameters(ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters) { }
public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
EndpointDispatcher endpointDispatcher) { }
public void ApplyClientBehavior(ServiceEndpoint endpoint,
ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new AuthenticationHeader(itsUser, itsPass, itsToken));
}
#endregion
}
}
I think the answer is that I forgot the binding for my channel.

HTTP Requests in Glass GDK

I am implementing a GDK application and need to do in my application some HTTP Post requests. Do I send the HTTP requests the same way as on android phone or there is some other way of doing it? (I have tried the code that I am using on my phone and it's not working for glass.)
thanks for your help in advance.
You can make any post request like in smartphones, but ensure you make the requests using an AsyncTask.
For example:
private class SendPostTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
// Make your request POST here. Example:
myRequestPost();
return null;
}
protected void onPostExecute(Void result) {
// Do something when finished.
}
}
And you can call that asynctask anywhere with:
new SendPostTask().execute();
And example of myRequestPost() may be:
private int myRequestPost() {
int resultCode = 0;
String url = "http://your-url-here";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
// add headers you want, example:
// post.setHeader("Authorization", "YOUR-TOKEN");
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id", "111111"));
nameValuePairs.add(new BasicNameValuePair("otherField", "your-other-data"));
try {
post.setEntity(new UrlEncodedFormEntity(urlParameters));
HttpResponse response = client.execute(post);
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + post.getEntity());
System.out.println("Response Code : " +
response.getStatusLine().getStatusCode());
resultCode = response.getStatusLine().getStatusCode();
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result.toString());
} catch (Exception e) {
Log.e("POST", e.getMessage());
}
return resultCode;
}

httpcomponents's ssl connection results in socket is closed

I am trying to get some data from webserver which works fine with http.
But when I try https(ssl connection), I get the exceptions like below.
I get the http status code 200 and response content length 2230 which is correct.
java.net.SocketException: Socket is closed
at sun.security.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1483)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:92)
at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:166)
at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:90)
at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:183)
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:144)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:121)
My code is like below with apache httpcomponents httpclient(4.2.5) library.
try {
HttpPost httppost = new HttpPost(uri);
HttpHost targetHost = new HttpHost(HOST_NAME, HOST_PORT, PROTOCOL);
InputStreamEntity reqEntity = new InputStreamEntity(new ByteArrayInputStream(request), -1);
String contentType = TSPConstants.CONST_TSA_CONTENT_TYPE_TSREQUEST;
reqEntity.setContentType(contentType);
reqEntity.setChunked(true);
// It may be more appropriate to use FileEntity class in this particular
// instance but we are using a more generic InputStreamEntity to demonstrate
// the capability to stream out data from any arbitrary source
//
// FileEntity entity = new FileEntity(file, "binary/octet-stream");
httppost.setEntity(reqEntity);
//Authentication
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
new UsernamePasswordCredentials(id, password));
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local
// auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext httpContext = new BasicHttpContext();
httpContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
//SSL
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { }
public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { }
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Scheme sch = new Scheme("https", HOST_PORT, ssf);
httpclient.getConnectionManager().getSchemeRegistry().register(sch);
System.out.println("executing request " + httppost.getRequestLine());
httpclient.execute(httppost, httpContext);
HttpResponse response = send(request);
HttpEntity resEntity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (resEntity != null) {
System.out.println("Response content length: " + resEntity.getContentLength());
System.out.println("Chunked?: " + resEntity.isChunked());
}
EntityUtils.consume(resEntity);
resEntity.getContent()
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
Basically the answer gave #Avner in the comment.
The problem (for me) was, that the response was closed before the entity was read.
I did something like this, which was wrong:
HttpEntity entity = null;
try (CloseableHttpResponse response = client.execute(request)) {
entity = response.getEntity();
}
read(entity);
The following worked:
try (CloseableHttpResponse response = client.execute(request)) {
HttpEntity entity = response.getEntity();
read(entity);
}
The maybe not so obvious part: The try-with-resources block in the first example closed the stream, before it was read.

How to use IHttpCookieContainerManager in WCF 4.5

Just wanted to know how can we use IHttpCookieContainerManager in WCF 4.5. Suggest any sample code please.
In .NET 4.5 you can access the cookie container by using the .GetProperty().CookieContainer method like below if AllowCoookies = true.
Uri serverUri = new Uri("http://localhost/WcfService/Service1.svc");
CookieContainer myCookieContainer = new CookieContainer();
myCookieContainer.Add(serverUri, new Cookie("cookie1", "cookie1Value"));
ChannelFactory<IService1> factory = new ChannelFactory<IService1>(new BasicHttpBinding() { AllowCookies = true }, new EndpointAddress(serverUri));
IService1 client = factory.CreateChannel();
factory.GetProperty<IHttpCookieContainerManager>().CookieContainer = myCookieContainer;
Console.WriteLine(client.GetData(123));
myCookieContainer = factory.GetProperty<IHttpCookieContainerManager>().CookieContainer;
foreach (Cookie receivedCookie in myCookieContainer.GetCookies(serverUri))
{
Console.WriteLine("Cookie name : " + receivedCookie.Name + " Cookie value : " + receivedCookie.Value);
}
((IChannel)client).Close();
factory.Close();
//Server side
public class Service1 : IService1
{
public string GetData(int value)
{
//Read the cookies
HttpRequestMessageProperty reqProperty = (HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name];
string cookies = reqProperty.Headers["Cookie"];
//Write a cookie
HttpResponseMessageProperty resProperty = new HttpResponseMessageProperty();
resProperty.Headers.Add("Set-Cookie", string.Format("Number={0}", value.ToString()));
OperationContext.Current.OutgoingMessageProperties.Add(HttpResponseMessageProperty.Name, resProperty);
return string.Format("You entered: {0}", value);
}
}