Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Conversation

@Priya91
Copy link
Contributor

@Priya91 Priya91 commented Feb 9, 2018

fixes #26375

@dotnet/ncl


// Read the authorization header from client.
AuthenticationProtocols protocol = AuthenticationProtocols.None;
string authorizationHeader = response.Contains("Proxy-Authenticate", StringComparison.OrdinalIgnoreCase) ? "Proxy-Authorization" : "Authorization";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be checking for 'Authorization' request headers from the client? 'Proxy-Authenticate' is not something a client would send to a server. And these changes here are for the Loopback test server. This server isn't a proxy server.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string I'm checking here is the response the server sends, not the client. The code below checks for Authorization header from client.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I should remove the Proxy stuff, doesn't make sense here. It's left from my first draft.

}

public sealed class ManagedHandler_Authentication_Test : HttpClientTestBase
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't we want these tests to be in HttpClientHandlerTest etc. so that they can be exercised by all the handlers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran these with winhttp handler, and there are a lot of test failures, for one, winhttp handler doesn't support Digest, and there were some failures due to non-conformance with RFC.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

winhttp handler doesn't support Digest

In general WinHttpHandler supports all the auth schemes that WinHTTP supports including Basic, Digest, Negotiate, NTLM. So, if there is a bug with Digest for WinHttpHandler, we should open an issue, etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran these with winhttp handler

What about CurlHandler? If they both don't work, maybe the issue is actually with the server implementation rather than the client?

if (data[currentIndex++] != ',')
{
parsedIndex = currentIndex;
return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any benefit to making our parsing more strict here? Looking at the spec I agree that it is probably correct not to generate key value pairs that end with spaces or tabs. But accepting them when we do see them might be good.

@Priya91 Priya91 force-pushed the newhttpauth branch 2 times, most recently from 5efbacc to ef7e59f Compare February 12, 2018 22:21
@davidsh
Copy link
Contributor

davidsh commented Feb 12, 2018

This PR will conflict with #27055 once that gets merged since #27055 is refactoring the Loopback server.

@Priya91
Copy link
Contributor Author

Priya91 commented Feb 12, 2018

Well, that has a no merge label, I hope to get this in before that.

await ReadWriteAcceptedAsync(s, reader, writer, response);

// Read the request method.
string line = await reader.ReadLineAsync().ConfigureAwait(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI, having it won't hurt anything, but we generally don't use ConfigureAwait in test code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not? Is this just for the ReadLineAsync() method or generally? Wouldn't we have the same deadlock problems in test code as in product code?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this just for the ReadLineAsync() method or generally?

Generally

Wouldn't we have the same deadlock problems in test code as in product code?

We shouldn't be writing tests that synchronously block on such helpers; if we do, that's a test bug. We use ConfigureAwait(false) in product code for perf but also because we can't control whether someone does synchronously wait on it.

Why not?

Three reasons:

  1. xunit has a synchronization context in place for a reason, and we generally want to respect that reason, which is to limit concurrency.
  2. ConfigureAwait(false) is partially for eeking out additional perf, which we don't care about in tests, and it adds clutter that's only worthwhile if it brings value.
  3. We shouldn't go out of our way in test code to enable other test code to block artificially and introduce deadlock potential.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really good information about testing and ConfigureAwait(). I don't think the rest of the CoreFx community knows this. It would be good to distribute this information more broadly.

cc: @Caesar1995 @rmkerr

// Read the authorization header from client.
AuthenticationProtocols protocol = AuthenticationProtocols.None;
string clientResponse = null;
while (!string.IsNullOrEmpty(line = await reader.ReadLineAsync().ConfigureAwait(false)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ok for now, but related to @geoffkizer's refactoring, we may just want to have a method "ReadHeaders" that returns the list of headers sent by the client. Then code like this can just process the array or dictionary of headers rather than interleaving request processing with test logic.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Username is a quoted string.
int startIndex = trimmedValue.IndexOf('"') + 1;

if (startIndex != -1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this logic. In what circumstance will startIndex ever be -1? For that to happen, IndexOf would need to be returning -2, which it will never do.

Same comment for all other occurrences of this below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh that's old code, I forgot to change this when i made startindex point to the valid char to be taken.

@stephentoub
Copy link
Member

@Priya91, where did we land with #26979 (comment)? It looks like these tests are still SocketsHttpHandler-specific. If SocketsHttpHandler is passing the tests but WinHttpHandler, CurlHandler, and desktop's handler are not, and for something as long-standing as digest auth, that makes me think that the problem is actually with the test and SocketsHttpHandler jointly doing the wrong thing rather than it being a bug in WinHttpHandler, CurlHandler, and desktop. I could be wrong, of course, but it's suspect.

@Priya91
Copy link
Contributor Author

Priya91 commented Feb 13, 2018

@stephentoub I ran the tests only against winhttphandler, with that all the basic test cases passed, but for digest, the winhttphandler threw exception saying unrecognized message from server. From working on auth stuff in NTAuthentication, I found that the NTAuthentication class supports only WDigest, and it is more likely that the win apis, dont support digest but only Wdigest. @davidsh Can confirm..

I'll enable these tests for CurlHandler, and check the results.

@davidsh
Copy link
Contributor

davidsh commented Feb 13, 2018

I found that the NTAuthentication class supports only WDigest, and it is more likely that the win apis, dont support digest but only Wdigest. @davidsh Can confirm..

"Wdigest" is digest auth. The name of the binary in Windows that supports the Digest auth scheme is called Wdigest.dll. There are not separate "Wdigest" vs. "digest" protocols.

https://technet.microsoft.com/en-us/library/cc778868(v=ws.10).aspx

Digest can be disabled on the Windows box. And it frequently is by default. That might be why it is not working in your tests.

See this for background on digest auth and why it might be disabled at times:
https://www.jimwilbur.com/2017/10/wdigest-clear-text-passwords/

@Priya91
Copy link
Contributor Author

Priya91 commented Feb 15, 2018

@stephentoub @geoffkizer Can you please take a look, i refactored code per the latest changes in Loopback server.

@Priya91
Copy link
Contributor Author

Priya91 commented Feb 15, 2018

@geoffkizer locally I get test failures in sockethttphandler with assertion fail with httpconnectionpool..

 Assertion Failed
  Assertion Failed
  Assertion Failed
  Assertion Failed
  23 != 21

     at System.Net.Http.HttpConnection.ReturnConnectionToPoolCore() in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 1256
     at System.Net.Http.HttpConnection.ReturnConnectionToPool() in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 1219
     at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 480
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 546
     at System.Threading.Tasks.Task.RunContinuations(Object continuationObject) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\Task.cs:line 3283
     at System.Threading.Tasks.Task`1.TrySetResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\future.cs:line 421
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 632
     at System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1.SetResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\shared\System\Runtime\CompilerServices\AsyncValueTaskMethodBuilder.cs:line 67
     at System.Net.Http.HttpConnection.ReadNextLineAsync() in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 1025
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 546
     at System.Threading.Tasks.Task.RunContinuations(Object continuationObject) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\Task.cs:line 3283
     at System.Threading.Tasks.Task`1.TrySetResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\future.cs:line 421
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 632
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 254
     at System.Net.Http.HttpConnection.FillAsync() in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 1072
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 546
     at System.Threading.Tasks.Task.RunContinuations(Object continuationObject) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\Task.cs:line 3283
     at System.Threading.Tasks.Task`1.TrySetResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\future.cs:line 421
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 632
     at System.Net.Sockets.Socket.CompleteSendReceive(Socket s, Int32TaskSocketAsyncEventArgs saea, Boolean isReceive) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\Socket.Tasks.cs:line 690
     at System.Net.Sockets.Socket.<>c.<.cctor>b__327_1(Object s, SocketAsyncEventArgs e) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\Socket.Tasks.cs:line 32
     at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\SocketAsyncEventArgs.cs:line 206
     at System.Net.Sockets.SocketAsyncEventArgs.ExecutionCallback(Object state) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\SocketAsyncEventArgs.cs:line 426
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncSuccess(Int32 bytesTransferred, SocketFlags flags) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\SocketAsyncEventArgs.cs:line 768
     at System.Net.Sockets.SocketAsyncEventArgs.<>c.<.cctor>b__174_0(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\SocketAsyncEventArgs.Windows.cs:line 1197
     at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Overlapped.cs:line 101
  37 != 35

     at System.Net.Http.HttpConnection.ReturnConnectionToPoolCore() in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 1256
     at System.Net.Http.HttpConnection.ReturnConnectionToPool() in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 1219
     at System.Net.Http.HttpConnection.ContentLengthReadStream.CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken) in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\ContentLengthReadStream.cs:line 130
     at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 922
     at System.Net.Http.HttpConnection.ContentLengthReadStream.CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
     at System.Net.Http.HttpConnection.HttpConnectionResponseContent.SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnectionResponseContent.cs:line 48
     at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 922
     at System.Net.Http.HttpConnection.HttpConnectionResponseContent.SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken)
     at System.Net.Http.HttpContent.LoadIntoBufferAsync(Int64 maxBufferSize, CancellationToken cancellationToken) in E:\corefx\src\System.Net.Http\src\System\Net\Http\HttpContent.cs:line 399
     at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) in E:\corefx\src\System.Net.Http\src\System\Net\Http\HttpClient.cs:line 478
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 546
     at System.Threading.Tasks.Task.RunContinuations(Object continuationObject) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\Task.cs:line 3283
     at System.Threading.Tasks.Task`1.TrySetResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\future.cs:line 421
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 632
     at System.Net.Http.AuthenticateAndRedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\AuthenticateAndRedirectHandler.cs:line 158
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 546
     at System.Threading.Tasks.Task.RunContinuations(Object continuationObject) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\Task.cs:line 3283
     at System.Threading.Tasks.Task`1.TrySetResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\future.cs:line 421
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 632
     at System.Net.Http.HttpConnectionPool.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnectionPool.cs:line 198
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 546
     at System.Threading.Tasks.Task.RunContinuations(Object continuationObject) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\Task.cs:line 3283
     at System.Threading.Tasks.Task`1.TrySetResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\future.cs:line 421
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 632
     at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 557
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 546
     at System.Threading.Tasks.Task.RunContinuations(Object continuationObject) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\Task.cs:line 3283
     at System.Threading.Tasks.Task`1.TrySetResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\future.cs:line 421
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 632
     at System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1.SetResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\shared\System\Runtime\CompilerServices\AsyncValueTaskMethodBuilder.cs:line 67
     at System.Net.Http.HttpConnection.ReadNextLineAsync() in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 1025
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 546
     at System.Threading.Tasks.Task.RunContinuations(Object continuationObject) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\Task.cs:line 3283
     at System.Threading.Tasks.Task`1.TrySetResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\future.cs:line 421
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 632
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 254
     at System.Net.Http.HttpConnection.FillAsync() in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 1072
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 546
     at System.Threading.Tasks.Task.RunContinuations(Object continuationObject) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\Task.cs:line 3283
     at System.Threading.Tasks.Task`1.TrySetResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Tasks\future.cs:line 421
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(TResult result) in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 632
     at System.Net.Sockets.Socket.CompleteSendReceive(Socket s, Int32TaskSocketAsyncEventArgs saea, Boolean isReceive) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\Socket.Tasks.cs:line 690
     at System.Net.Sockets.Socket.<>c.<.cctor>b__327_1(Object s, SocketAsyncEventArgs e) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\Socket.Tasks.cs:line 32
     at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\SocketAsyncEventArgs.cs:line 206
     at System.Net.Sockets.SocketAsyncEventArgs.ExecutionCallback(Object state) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\SocketAsyncEventArgs.cs:line 426
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncSuccess(Int32 bytesTransferred, SocketFlags flags) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\SocketAsyncEventArgs.cs:line 768
     at System.Net.Sockets.SocketAsyncEventArgs.<>c.<.cctor>b__174_0(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) in E:\corefx\src\System.Net.Sockets\src\System\Net\Sockets\SocketAsyncEventArgs.Windows.cs:line 1197
     at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) in E:\A\_work\2813\s\src\mscorlib\src\System\Threading\Overlapped.cs:line 101Assertion Failed

  Assertion Failed
  23 != 21

     at System.Net.Http.HttpConnection.ReturnConnectionToPoolCore() in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 1256
     at System.Net.Http.HttpConnection.ReturnConnectionToPool() in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 1219
     at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in E:\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnection.cs:line 480
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in E:\A\_work\2813\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs:line 166
     at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() in E:\A\_work\2813\s\src\mscorlib\src\System\Runtime\CompilerServices\AsyncMethodBuilder.cs:line 546
  Finished running tests.  End time=17:23:28.78, Exit code = -2146232797
     at System.Threading.Tasks.Task.RunContinuations(ObjecAssertion Failed

@geoffkizer
Copy link

Which tests are you seeing the assert with?

It probably means that the server is incorrectly sending an extra CRLF.

case 504: return "Gateway Timeout";
case 505: return "Http Version Not Supported";
case 507: return "Insufficient Storage";
case 100:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it was not, VS automatically formats it this way, it's a pain to fight against it everytime, and revert the formatting. Prefer to keep it to the default VS way.

content;
$"Content-Length: {(content == null ? 0 : content.Length)}\r\n" +
additionalHeaders + "\r\n" +
content + "\r\n";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"\r\n" after content is wrong. That's probably why you're seeing the asserts.

Also, I prefer seeing the "\r\n" after additionalHeaders on a separate line. This \r\n is actually the empty line to terminate the headers. When they are on the same line, it looks like its the line terminator for additonalHeaders, which is not right.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, i assumed the additionalheaders didn't have to specify \r\n. Will revert this part.

return lines;
}

public async Task<string> ReadRequestContentAsync()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not following this method. It looks like you find the Content-Length, skip the next line, and then read whatever is after this until you get a new line. Isn't this going to produce weird results in many cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed the stuff after content-length was content, seems like that is wrong. Will revert this.

await connection.ReadRequestHeaderAndSendResponseAsync(HttpStatusCode.Unauthorized, authenticateHeaders);

lines = await connection.ReadRequestHeaderAsync();
if (lines.Count == 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When would this be true?

return lines;
}

public async Task<List<string>> AcceptConnectionPerformAuthenticationAndCloseAsync(string authenticateHeaders)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this code, and the related code like Is*AuthTokenValid, somewhere other than LoopbackServer? Maybe AuthTestHelpers.cs or something like that?

I'd like to keep LoopbackServer itself minimal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

@geoffkizer
Copy link

Beyond the scope of this PR, but:

Can we largely reuse all of this for proxy auth as well? Seems like with a few tweaks to parameterize tests, we could reuse pretty much all of this.

@wfurt
Copy link
Member

wfurt commented Feb 20, 2018

yes, I was planing to do that @geoffkizer once this is in and stable. (so as moving proxy tests to loopback as you asked)

@geoffkizer
Copy link

Great, thanks @wfurt.

@geoffkizer
Copy link

I'm happy with this PR. Is it ready to merge? @stephentoub are you happy?

@Priya91
Copy link
Contributor Author

Priya91 commented Feb 20, 2018

Yes, it's ready to merge, there's the tracking linked issue #27113 to resolve the differences on handlers and within OSes..

@Priya91 Priya91 merged commit ff123e8 into dotnet:master Feb 20, 2018
@Priya91 Priya91 deleted the newhttpauth branch February 20, 2018 19:06
@karelz karelz added this to the 2.1.0 milestone Mar 10, 2018
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Add test infra for auth testing.

Commit migrated from dotnet/corefx@ff123e8
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add digest authentication functional tests.

7 participants