简体   繁体   中英

How can I get negotiated TLS version used in HttpClient POST requests

I am trying to get the TLS version information used in my HttpClient SendAsync calls. I have tried method from this link Detecting TLS Version used for HttpClient POST or GET calls but when I ran it in debug mode I have found that the object disposed exception comes while getting SslProtocol property. Is there any way that I can stop .net disposing the object properties until I read them.

Here is the code:

public bool ExecuteAsync()
{
    using (var client = new HttpClient())
    {
        using (var response = client.GetAsync("https://example.com/").Result)
        {
            if (response.Content is StreamContent)
            {
                var webExceptionWrapperStream = GetPrivateField(response.Content, "content");
                var connectStream = GetBasePrivateField(webExceptionWrapperStream, "innerStream");
                var connection = GetPrivateProperty(connectStream, "Connection");
                var tlsStream = GetPrivateProperty(connection, "NetworkStream");
                var state = GetPrivateField(tlsStream, "m_Worker");
                var protocol = (SslProtocols)GetPrivateProperty(state, "SslProtocol");
                Console.WriteLine(protocol);
            }
            else
            {
                // not sure if this is possible
            }
        }
    }
return true;
}

private static object GetPrivateProperty(object obj, string property)
{
    return obj.GetType().GetProperty(property, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj);
}

private static object GetPrivateField(object obj, string field)
{
    return obj.GetType().GetField(field, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj);
}

private static object GetBasePrivateField(object obj, string field)
{
    return obj.GetType().BaseType.GetField(field, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj);
}

Also, I have run the solution in the above link in some other code and it is working. The difference that I have found is that the other code is initiating new thread for doing SendAsync calls while I am doing all my work in main thread. Also I read somewhere that it is not good practice to use "using" statement for SendAsync method as was used in the above link.

Moreover, is there any other method to get the TLS version information. I have heard that it can be read from .net framework logs but I have no idea how to do that.

If I can get other information related to TLS stream like hash algorithm and cipher algorithm that will be great. Also, I am using .net framework 4.6.1 will that have any impact on the problem?

I found a method of reading System.Net traces in code with the help of the code given here System.Net (HttpWebRequest) tracing without using files or app.config? by @MarkoW.

I have to call

ExecuteWithEnabledSystemNetLogging(SourceLevels webTraceSourceLevel, Action actionToExecute, params TraceListener[] listener).

for my case the input variables were following.

webTraceSourceLevel is SourceLevels.Information

actionToExecute is my method which is sending HttpClient requests for which I need system.net tracing, assigned to Action object.

listener is TextWriterTraceListener myTextListener = new TextWriterTraceListener(stream)

// where stream is a stream object in which my system.net tracing related to the action that I passed will come and later I converted it to string.

With this I got the tls version and other cipher related information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM