Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Initial commit to System.Net.HttpListener #13502

Merged
merged 16 commits into from
Nov 15, 2016
Merged

Conversation

Priya91
Copy link
Contributor

@Priya91 Priya91 commented Nov 8, 2016

This gets @ericeil PR #13287 in. Fixed merged conflicts.

cc @stephentoub @davidsh @CIPop @geoffkizer @karelz

{
internal unsafe static partial class HttpApi
{
internal static readonly HTTPAPI_VERSION Version = new HTTPAPI_VERSION() { HttpApiMajorVersion = 2, HttpApiMinorVersion = 0 };
Copy link
Member

Choose a reason for hiding this comment

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

Nit: s_version?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

{
internal static readonly HTTPAPI_VERSION Version = new HTTPAPI_VERSION() { HttpApiMajorVersion = 2, HttpApiMinorVersion = 0 };

internal static readonly bool Supported = InitHttpApi(Version);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: s_supported?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.


internal static partial class Interop
{
internal unsafe static partial class HttpApi
Copy link
Member

Choose a reason for hiding this comment

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

Can we scope the unsafe to be only where it's needed, rather than the whole class?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

internal struct HTTP_KNOWN_HEADER
{
internal ushort RawValueLength;
internal sbyte* pRawValue;
Copy link
Member

Choose a reason for hiding this comment

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

Why sbyte rather than byte? (Same question for the other occurrences 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.

Same as desktop code.

[DllImport(Libraries.HttpApi, SetLastError = true)]
internal static extern uint HttpCloseServerSession(ulong serverSessionId);

internal class SafeLocalFreeChannelBinding : ChannelBinding
Copy link
Member

Choose a reason for hiding this comment

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

Nit: sealed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

{
SafeLocalFreeChannelBinding result;

result = LocalAllocChannelBinding(LMEM_FIXED, (UIntPtr)cb);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: the declaration and initialization can be combined

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

internal class SafeLocalFreeChannelBinding : ChannelBinding
{
private const int LMEM_FIXED = 0;
private int _size;
Copy link
Member

Choose a reason for hiding this comment

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

This type needs a parameterless ctor in order to work with the P/Invoke. The compiler is providing one by default, but it's public... consider adding an explicit one that's private.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

}

[DllImport(Interop.Libraries.Heap, EntryPoint = "LocalAlloc", SetLastError = true)]
internal static extern SafeLocalFreeChannelBinding LocalAllocChannelBinding(int uFlags, UIntPtr sizetdwBytes);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Why not just call the method LocalAlloc rather than calling it LocalAllocChannelBinding and using EntryPoint to change its name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah makes sense, it was copied from Desktop code.

"WWW-Authenticate",
};

private static Dictionary<string, int> s_hashtable = CreateTable();
Copy link
Member

Choose a reason for hiding this comment

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

Nit: readonly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

//}

//NetEventSource.Exit(null);
//return endpoint;
Copy link
Member

Choose a reason for hiding this comment

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

What's the plan for all of this commented out code? Is there a TODO to follow-up on this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, am working on it.

//}

//NetEventSource.Exit(null);
//return endpoint;
Copy link
Member

Choose a reason for hiding this comment

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

Same comment/question


namespace System.Net.Security
{
//
Copy link
Member

Choose a reason for hiding this comment

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

How does this SafeDeleteContext differ from the one we already have in the repo?
https://github.com/dotnet/corefx/blob/master/src/Common/src/System/Net/Security/Unix/SafeDeleteContext.cs

Copy link
Member

Choose a reason for hiding this comment

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

Oh, I see, you just separated it out of SecuritySafeHandles.cs. Ok.


In reply to: 87213631 [](ancestors = 87213631)

@@ -43,7 +43,6 @@ private void Trace()

~DebugSafeHandle()
{
DebugThreadTracking.SetThreadSource(ThreadKinds.Finalization);
Copy link
Member

Choose a reason for hiding this comment

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

Why was this removed? I don't know what its purpose was, just wondering why it's going away.

Copy link
Contributor Author

Choose a reason for hiding this comment

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


namespace System.Net
{
internal unsafe class AsyncRequestContext : RequestContextBase
Copy link
Member

Choose a reason for hiding this comment

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

Nit: sealed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

{
private NativeOverlapped* _nativeOverlapped;
private ThreadPoolBoundHandle _boundHandle;
private ListenerAsyncResult _result;
Copy link
Member

Choose a reason for hiding this comment

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

Nit: readonly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

if (_nativeOverlapped != null)
{
Debug.Assert(!disposing, "AsyncRequestContext::Dispose()|Must call ReleasePins() before calling Dispose().");
if (!Environment.HasShutdownStarted || disposing)
Copy link
Member

Choose a reason for hiding this comment

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

!Environment.HasShutdownStarted || [](start = 20, length = 35)

Do we know why this check is here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@CIPop Any idea?


namespace System.Net
{
internal class CaseInsensitiveAsciiComparer : IEqualityComparer, IComparer
Copy link
Member

Choose a reason for hiding this comment

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

How does this differ from the CaseInsensitiveAscii comparer already in the repo?
https://github.com/dotnet/corefx/blob/master/src/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs#L496
If possible, we should combine them to avoid duplication.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, confirmed it's the same. Will reuse.

s_toServerStringFunc = (Func<Cookie, string>)typeof(Cookie).GetMethod("ToServerString").CreateDelegate(typeof(Func<Cookie, string>));
}
return s_toServerStringFunc(cookie);
}
Copy link
Member

Choose a reason for hiding this comment

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

@weshaggard, FYI on another reflection case to access internals in another assembly.

Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't we add a TODO here?
This can be solved in other ways (e.g. factoring then importing the relevant code or exposing a public API, etc.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Created issue #13607 to track.

//}
finally
{
//if (NetEventSource.IsEnabled) NetEventSource.Exit(NetEventSource.ComponentType.HttpListener, this, "Close", "");
Copy link
Member

Choose a reason for hiding this comment

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

All of this tracing should be fixed and uncommented.

namespace System.Net
{
public sealed unsafe partial class HttpListener
{
Copy link
Member

@stephentoub stephentoub Nov 9, 2016

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.


private static bool InitHttpApi(HTTPAPI_VERSION version)
{
uint statusCode = HttpInitialize(version, (uint)HTTP_FLAGS.HTTP_INITIALIZE_SERVER, null);
Copy link
Member

Choose a reason for hiding this comment

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

Are there any platforms we need to run on where this function isn't exported? I'm wondering if we need a try/catch here to return false if this fails for any reason.

Copy link
Member

Choose a reason for hiding this comment

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

In .Net Desktop we check for Win7+ for this call.

Copy link
Member

Choose a reason for hiding this comment

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

@Priya91 To clarify: this is good as written and no more changes are required. CoreFX will only run on Win7 and above which support the above initialization code.

private string _realm;
private SafeHandle _requestQueueHandle;
private ThreadPoolBoundHandle _requestQueueBoundHandle;
private volatile State _state; // m_State is set only within lock blocks, but often read outside locks.
Copy link
Member

Choose a reason for hiding this comment

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

Nit: wrong name

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

private HttpListenerTimeoutManager _timeoutManager;
private bool _V2Initialized;

private Hashtable _disconnectResults; // ulong -> DisconnectAsyncResult
Copy link
Member

Choose a reason for hiding this comment

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

Hashtable _disconnectResults; // ulong -> DisconnectAsyncResult [](start = 16, length = 71)

Should this be a Dictionary<ulong, DisconnectAsyncResult> then?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

private Hashtable _disconnectResults; // ulong -> DisconnectAsyncResult
private object _internalLock;

internal Hashtable m_UriPrefixes = new Hashtable();
Copy link
Member

Choose a reason for hiding this comment

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

m_UriPrefixes [](start = 27, length = 13)

Nit: _uriPrefixes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

private bool _V2Initialized;

private Hashtable _disconnectResults; // ulong -> DisconnectAsyncResult
private object _internalLock;
Copy link
Member

Choose a reason for hiding this comment

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

readonly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

CheckDisposed();
if (value == null)
{
throw new ArgumentNullException();
Copy link
Member

Choose a reason for hiding this comment

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

nameof(value)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

@danmoseley danmoseley modified the milestone: 1.2.0 Nov 11, 2016
@clrjunkie
Copy link

Big Plus for working on this!
Big Minus for "viewing this work as supporting mostly non-production web server scenarios."

HttpListener must be treated as a key infrastructure component for productions systems from day one.

It only stands to reason that this would ultimately be the underlying http server for ASP.Net Core (as in the case of Full FX ASP.NET self hosting ) and "Kestrel" would be a thing of the past...

@stephentoub
Copy link
Member

HttpListener must be treated as a key infrastructure component for productions systems from day one. It only stands to reason that this would ultimately be the underlying http server for ASP.Net Core (as in the case of Full FX ASP.NET self hosting ) and "Kestrel" would be a thing of the past

Thank you for the feedback, but no. The ASP.NET team (both at Microsoft and the community) has and continues to invest years and years of dev time into making that stack as efficient and programmable as possible, on both Windows and Unix, evolving it both in terms of implementation and API to do so. We do not plan to duplicate such efforts with HttpListener, nor are we able to take the API-level breaks necessary to bring it up to performance par. It is being exposed as part of corefx for compatibility, to enable code currently using it, but for production scenarios, I recommend using kestrel, ASP.NET, etc.

@clrjunkie
Copy link

@stephentoub The "ASP.NET" Stack has nothing to do with either HttpListener or "Kestrel" and if backward compatibility drives this effort then your duplicating efforts (and wasting time) as we speak... since nobody should care about the underlying HttpListener implementation (e.g Http.sys) but rather about the interface so for all intent and purposes "Kestrel" should expose HttpListener interface and get it over with. It's a simple interface and there is no reason it should not suit production scenarios regardless of the stack built on top of it.

@stephentoub
Copy link
Member

That is not the direction we are going. Thanks.

@Priya91
Copy link
Contributor Author

Priya91 commented Nov 15, 2016

@stephentoub @CIPop Addressed the PR feedback and filed issues on pending workitems. Plan to merge PR after CI passes, will continue watching the PR, and address additional comments in separate PR. This PR is getting too big to keep track of the work.

cc @karelz

@stephentoub
Copy link
Member

Thanks, @Priya91.

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.

7 participants