Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Header Expect 100-continue with client certificate #3185

Closed
VincentDW opened this issue Sep 26, 2018 · 4 comments
Closed

Remove Header Expect 100-continue with client certificate #3185

VincentDW opened this issue Sep 26, 2018 · 4 comments
Assignees

Comments

@VincentDW
Copy link

Hi everyone,

I'm using a SOAP Client within a dotnetcore projet. I have to use a client certificate but the problem is that the soap server doesn't support the header "Except 100-Continue".

I tried this old solution

System.Net.ServicePointManager.Expect100Continue = false;

but it doesn't seem to work..

I found an internal property, but it doesn't allow to be override (or I didn't find a way out) :

internal override bool IsExpectContinueHeaderRequired => RequireClientCertificate || base.IsExpectContinueHeaderRequired;

I looked to add Interceptor or middleware, but I can't find something which allow me to remove the header.

Do you have any solution to remove this header ?

Thank you,

Vincent

@mconnew
Copy link
Member

mconnew commented Sep 27, 2018

I added a new feature (.NET Core only) for exactly this kind of scenario. We now allow modifying, replacing. or wrapping the HttpClientHandler. An example behavior which can be easily adapted to what you need can be found here. We turn on the Expect header by modifying HttpClient.DefaultRequestHeaders.ExpectContinue which you don't have access to. But HttpClient simply applies the DefaultRequestHeaders to the outgoing HttpRequestMessage for each request so you can disable the Expect header on the individual HttpRequestMessage. Your code would look something like this (I didn't compile this so possibly has errors but you should get the idea).

var factory = new ChannelFactory<IService>(binding, endpointAddress);
var handlerFactoryBehavior = new HttpMessageHandlerBehavior();
handlerFactoryBehavior.OnSending = (message, token) =>
            {
                message.Headers.ExpectContinue = false;
                return null;
            };
factory.Endpoint.Behaviors.Add(handlerFactoryBehavior);
serviceProxy = factory.CreateChannel();

This should work as-is but you might want to streamline the implementation a bit as this has logic in it to allow providing a response message without actually sending the request at all.

@VincentDW
Copy link
Author

Hi,

Thank you for your answer, it's working.

I tried the same soap server with the .net framework 461 (net461). I have exactly the same code for the client except I didn't remove the header "Except 100-Continue" and it's working. So I'm wondering if there is a reason that the .net framework doesn't throw an exception when the server response 200 with the full response message while the .netcore implementation throw the exception :

   at System.Net.Http.HttpConnection.ThrowInvalidHttpResponse()
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.AuthenticationHelper.SendWithNtAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, Boolean isProxyAuth, HttpConnection connection, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.AuthenticationHelper.SendWithAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, Boolean preAuthenticate, Boolean isProxyAuth, Boolean doRequestAuth, HttpConnectionPool pool, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DecompressionHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at System.ServiceModel.Channels.HttpChannelFactory`1.HttpClientRequestChannel.HttpClientChannelAsyncRequest.SendRequestAsync(Message message, TimeoutHelper timeoutHelper)
   --- End of inner exception stack trace ---
   at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.<>c__DisplayClass1_0.<CreateGenericTask>b__0(IAsyncResult asyncResult)
--- End of stack trace from previous location where exception was thrown ---...


@mconnew
Copy link
Member

mconnew commented Oct 3, 2018

It looks like you are hitting a different issue. HttpClientHandler in .NET Core 2.1 doesn't correctly implement Windows authentication with the Expect header. There's an issue tracking this at dotnet/corefx#30760.

@mconnew
Copy link
Member

mconnew commented Oct 3, 2018

As your specific request (disable the 100-Continue header) has been answered and you are unblocked, I'm going to close this issue. We're tracking the Windows auth with Expect header problem in issue #2923.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants