Create shared package folder for IIS Integration In-process. (#397)

This commit is contained in:
Justin Kotalik 2017-09-25 15:53:33 -07:00 коммит произвёл GitHub
Родитель 58f82c5b32
Коммит 231cbffe1a
51 изменённых файлов: 1557 добавлений и 1476 удалений

Просмотреть файл

@ -45,6 +45,41 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{85914BA9
build\Key.snk = build\Key.snk
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{AB6964C9-A7AF-4FAC-BEA1-C8A538EC989E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.AspNetCore.HttpSys.Sources", "Microsoft.AspNetCore.HttpSys.Sources", "{4AB1E069-2A8A-4D46-98AE-CC82E3497038}"
ProjectSection(SolutionItems) = preProject
shared\Microsoft.AspNetCore.HttpSys.Sources\Constants.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\Constants.cs
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NativeInterop", "NativeInterop", "{94AD33C9-1BDD-4385-A850-4B24FD5D5012}"
ProjectSection(SolutionItems) = preProject
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\CookedUrl.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\CookedUrl.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\HeapAllocHandle.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\HeapAllocHandle.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\HttpApiTypes.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\HttpApiTypes.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\HttpSysRequestHeader.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\HttpSysRequestHeader.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\HttpSysResponseHeader.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\HttpSysResponseHeader.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\NativeRequestInput.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\NativeRequestInput.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\NclUtilities.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\NclUtilities.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\SafeLocalFreeChannelBinding.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\SafeLocalFreeChannelBinding.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\SafeLocalMemHandle.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\SafeLocalMemHandle.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\SafeNativeOverlapped.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\SafeNativeOverlapped.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\SocketAddress.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\SocketAddress.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\UnsafeNativeMethods.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\NativeInterop\UnsafeNativeMethods.cs
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RequestProcessing", "RequestProcessing", "{AA8C91BD-D558-468B-9258-1E186884F78D}"
ProjectSection(SolutionItems) = preProject
shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\HeaderCollection.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\HeaderCollection.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\HeaderEncoding.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\HeaderEncoding.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\HeaderParser.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\HeaderParser.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\HttpKnownHeaderNames.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\HttpKnownHeaderNames.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\NativeRequestContext.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\NativeRequestContext.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\RequestHeaders.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\RequestHeaders.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\RequestHeaders.Generated.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\RequestHeaders.Generated.cs
shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\SslStatus.cs = shared\Microsoft.AspNetCore.HttpSys.Sources\RequestProcessing\SslStatus.cs
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -131,6 +166,9 @@ Global
{8BFA392A-8B67-4454-916B-67C545EDFAEF} = {3A1E31E3-2794-4CA3-B8E2-253E96BDE514}
{E837249E-E666-4DF2-AFC3-7A4D70234F9F} = {E183C826-1360-4DFF-9994-F33CED5C8525}
{85914BA9-4168-48C5-9C3F-E2E8B1479A6E} = {5E9B546C-17AC-4BDF-BCB3-5955D4755ED8}
{4AB1E069-2A8A-4D46-98AE-CC82E3497038} = {AB6964C9-A7AF-4FAC-BEA1-C8A538EC989E}
{94AD33C9-1BDD-4385-A850-4B24FD5D5012} = {4AB1E069-2A8A-4D46-98AE-CC82E3497038}
{AA8C91BD-D558-468B-9258-1E186884F78D} = {4AB1E069-2A8A-4D46-98AE-CC82E3497038}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {34B42B42-FA09-41AB-9216-14073990C504}

Просмотреть файл

@ -1,4 +1,10 @@
{
"adx-nonshipping": {
"rules": [],
"packages": {
"Microsoft.AspNetCore.HttpSys.Sources": {}
}
},
"Default": {
"rules": [
"DefaultCompositeRule"

Просмотреть файл

@ -3,7 +3,7 @@
using System;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal static class Constants
{

Просмотреть файл

@ -4,14 +4,14 @@
using System;
using System.Runtime.InteropServices;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
// Note this type should only be used while the request buffer remains pinned
internal class CookedUrl
{
private readonly HttpApi.HTTP_COOKED_URL _nativeCookedUrl;
private readonly HttpApiTypes.HTTP_COOKED_URL _nativeCookedUrl;
internal CookedUrl(HttpApi.HTTP_COOKED_URL nativeCookedUrl)
internal CookedUrl(HttpApiTypes.HTTP_COOKED_URL nativeCookedUrl)
{
_nativeCookedUrl = nativeCookedUrl;
}

Просмотреть файл

@ -4,7 +4,7 @@
using System;
using Microsoft.Win32.SafeHandles;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal sealed class HeapAllocHandle : SafeHandleZeroOrMinusOneIsInvalid
{

Просмотреть файл

@ -0,0 +1,694 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal static unsafe class HttpApiTypes
{
internal enum HTTP_API_VERSION
{
Invalid,
Version10,
Version20,
}
// see http.w for definitions
internal enum HTTP_SERVER_PROPERTY
{
HttpServerAuthenticationProperty,
HttpServerLoggingProperty,
HttpServerQosProperty,
HttpServerTimeoutsProperty,
HttpServerQueueLengthProperty,
HttpServerStateProperty,
HttpServer503VerbosityProperty,
HttpServerBindingProperty,
HttpServerExtendedAuthenticationProperty,
HttpServerListenEndpointProperty,
HttpServerChannelBindProperty,
HttpServerProtectionLevelProperty,
}
// Currently only one request info type is supported but the enum is for future extensibility.
internal enum HTTP_REQUEST_INFO_TYPE
{
HttpRequestInfoTypeAuth,
HttpRequestInfoTypeChannelBind,
HttpRequestInfoTypeSslProtocol,
HttpRequestInfoTypeSslTokenBinding
}
internal enum HTTP_RESPONSE_INFO_TYPE
{
HttpResponseInfoTypeMultipleKnownHeaders,
HttpResponseInfoTypeAuthenticationProperty,
HttpResponseInfoTypeQosProperty,
}
internal enum HTTP_TIMEOUT_TYPE
{
EntityBody,
DrainEntityBody,
RequestQueue,
IdleConnection,
HeaderWait,
MinSendRate,
}
internal const int MaxTimeout = 6;
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_VERSION
{
internal ushort MajorVersion;
internal ushort MinorVersion;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_KNOWN_HEADER
{
internal ushort RawValueLength;
internal byte* pRawValue;
}
[StructLayout(LayoutKind.Explicit)]
internal struct HTTP_DATA_CHUNK
{
[FieldOffset(0)]
internal HTTP_DATA_CHUNK_TYPE DataChunkType;
[FieldOffset(8)]
internal FromMemory fromMemory;
[FieldOffset(8)]
internal FromFileHandle fromFile;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FromMemory
{
// 4 bytes for 32bit, 8 bytes for 64bit
internal IntPtr pBuffer;
internal uint BufferLength;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FromFileHandle
{
internal ulong offset;
internal ulong count;
internal IntPtr fileHandle;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTPAPI_VERSION
{
internal ushort HttpApiMajorVersion;
internal ushort HttpApiMinorVersion;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_COOKED_URL
{
internal ushort FullUrlLength;
internal ushort HostLength;
internal ushort AbsPathLength;
internal ushort QueryStringLength;
internal ushort* pFullUrl;
internal ushort* pHost;
internal ushort* pAbsPath;
internal ushort* pQueryString;
}
// Only cache unauthorized GETs + HEADs.
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_CACHE_POLICY
{
internal HTTP_CACHE_POLICY_TYPE Policy;
internal uint SecondsToLive;
}
internal enum HTTP_CACHE_POLICY_TYPE : int
{
HttpCachePolicyNocache = 0,
HttpCachePolicyUserInvalidates = 1,
HttpCachePolicyTimeToLive = 2,
}
[StructLayout(LayoutKind.Sequential)]
internal struct SOCKADDR
{
internal ushort sa_family;
internal byte sa_data;
internal byte sa_data_02;
internal byte sa_data_03;
internal byte sa_data_04;
internal byte sa_data_05;
internal byte sa_data_06;
internal byte sa_data_07;
internal byte sa_data_08;
internal byte sa_data_09;
internal byte sa_data_10;
internal byte sa_data_11;
internal byte sa_data_12;
internal byte sa_data_13;
internal byte sa_data_14;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_TRANSPORT_ADDRESS
{
internal SOCKADDR* pRemoteAddress;
internal SOCKADDR* pLocalAddress;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SSL_CLIENT_CERT_INFO
{
internal uint CertFlags;
internal uint CertEncodedSize;
internal byte* pCertEncoded;
internal void* Token;
internal byte CertDeniedByMapper;
}
internal enum HTTP_SERVICE_BINDING_TYPE : uint
{
HttpServiceBindingTypeNone = 0,
HttpServiceBindingTypeW,
HttpServiceBindingTypeA
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SERVICE_BINDING_BASE
{
internal HTTP_SERVICE_BINDING_TYPE Type;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_CHANNEL_BIND_STATUS
{
internal IntPtr ServiceName;
internal IntPtr ChannelToken;
internal uint ChannelTokenSize;
internal uint Flags;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_UNKNOWN_HEADER
{
internal ushort NameLength;
internal ushort RawValueLength;
internal byte* pName;
internal byte* pRawValue;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SSL_INFO
{
internal ushort ServerCertKeySize;
internal ushort ConnectionKeySize;
internal uint ServerCertIssuerSize;
internal uint ServerCertSubjectSize;
internal byte* pServerCertIssuer;
internal byte* pServerCertSubject;
internal HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo;
internal uint SslClientCertNegotiated;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_RESPONSE_HEADERS
{
internal ushort UnknownHeaderCount;
internal HTTP_UNKNOWN_HEADER* pUnknownHeaders;
internal ushort TrailerCount;
internal HTTP_UNKNOWN_HEADER* pTrailers;
internal HTTP_KNOWN_HEADER KnownHeaders;
internal HTTP_KNOWN_HEADER KnownHeaders_02;
internal HTTP_KNOWN_HEADER KnownHeaders_03;
internal HTTP_KNOWN_HEADER KnownHeaders_04;
internal HTTP_KNOWN_HEADER KnownHeaders_05;
internal HTTP_KNOWN_HEADER KnownHeaders_06;
internal HTTP_KNOWN_HEADER KnownHeaders_07;
internal HTTP_KNOWN_HEADER KnownHeaders_08;
internal HTTP_KNOWN_HEADER KnownHeaders_09;
internal HTTP_KNOWN_HEADER KnownHeaders_10;
internal HTTP_KNOWN_HEADER KnownHeaders_11;
internal HTTP_KNOWN_HEADER KnownHeaders_12;
internal HTTP_KNOWN_HEADER KnownHeaders_13;
internal HTTP_KNOWN_HEADER KnownHeaders_14;
internal HTTP_KNOWN_HEADER KnownHeaders_15;
internal HTTP_KNOWN_HEADER KnownHeaders_16;
internal HTTP_KNOWN_HEADER KnownHeaders_17;
internal HTTP_KNOWN_HEADER KnownHeaders_18;
internal HTTP_KNOWN_HEADER KnownHeaders_19;
internal HTTP_KNOWN_HEADER KnownHeaders_20;
internal HTTP_KNOWN_HEADER KnownHeaders_21;
internal HTTP_KNOWN_HEADER KnownHeaders_22;
internal HTTP_KNOWN_HEADER KnownHeaders_23;
internal HTTP_KNOWN_HEADER KnownHeaders_24;
internal HTTP_KNOWN_HEADER KnownHeaders_25;
internal HTTP_KNOWN_HEADER KnownHeaders_26;
internal HTTP_KNOWN_HEADER KnownHeaders_27;
internal HTTP_KNOWN_HEADER KnownHeaders_28;
internal HTTP_KNOWN_HEADER KnownHeaders_29;
internal HTTP_KNOWN_HEADER KnownHeaders_30;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_HEADERS
{
internal ushort UnknownHeaderCount;
internal HTTP_UNKNOWN_HEADER* pUnknownHeaders;
internal ushort TrailerCount;
internal HTTP_UNKNOWN_HEADER* pTrailers;
internal HTTP_KNOWN_HEADER KnownHeaders;
internal HTTP_KNOWN_HEADER KnownHeaders_02;
internal HTTP_KNOWN_HEADER KnownHeaders_03;
internal HTTP_KNOWN_HEADER KnownHeaders_04;
internal HTTP_KNOWN_HEADER KnownHeaders_05;
internal HTTP_KNOWN_HEADER KnownHeaders_06;
internal HTTP_KNOWN_HEADER KnownHeaders_07;
internal HTTP_KNOWN_HEADER KnownHeaders_08;
internal HTTP_KNOWN_HEADER KnownHeaders_09;
internal HTTP_KNOWN_HEADER KnownHeaders_10;
internal HTTP_KNOWN_HEADER KnownHeaders_11;
internal HTTP_KNOWN_HEADER KnownHeaders_12;
internal HTTP_KNOWN_HEADER KnownHeaders_13;
internal HTTP_KNOWN_HEADER KnownHeaders_14;
internal HTTP_KNOWN_HEADER KnownHeaders_15;
internal HTTP_KNOWN_HEADER KnownHeaders_16;
internal HTTP_KNOWN_HEADER KnownHeaders_17;
internal HTTP_KNOWN_HEADER KnownHeaders_18;
internal HTTP_KNOWN_HEADER KnownHeaders_19;
internal HTTP_KNOWN_HEADER KnownHeaders_20;
internal HTTP_KNOWN_HEADER KnownHeaders_21;
internal HTTP_KNOWN_HEADER KnownHeaders_22;
internal HTTP_KNOWN_HEADER KnownHeaders_23;
internal HTTP_KNOWN_HEADER KnownHeaders_24;
internal HTTP_KNOWN_HEADER KnownHeaders_25;
internal HTTP_KNOWN_HEADER KnownHeaders_26;
internal HTTP_KNOWN_HEADER KnownHeaders_27;
internal HTTP_KNOWN_HEADER KnownHeaders_28;
internal HTTP_KNOWN_HEADER KnownHeaders_29;
internal HTTP_KNOWN_HEADER KnownHeaders_30;
internal HTTP_KNOWN_HEADER KnownHeaders_31;
internal HTTP_KNOWN_HEADER KnownHeaders_32;
internal HTTP_KNOWN_HEADER KnownHeaders_33;
internal HTTP_KNOWN_HEADER KnownHeaders_34;
internal HTTP_KNOWN_HEADER KnownHeaders_35;
internal HTTP_KNOWN_HEADER KnownHeaders_36;
internal HTTP_KNOWN_HEADER KnownHeaders_37;
internal HTTP_KNOWN_HEADER KnownHeaders_38;
internal HTTP_KNOWN_HEADER KnownHeaders_39;
internal HTTP_KNOWN_HEADER KnownHeaders_40;
internal HTTP_KNOWN_HEADER KnownHeaders_41;
}
internal enum HTTP_VERB : int
{
HttpVerbUnparsed = 0,
HttpVerbUnknown = 1,
HttpVerbInvalid = 2,
HttpVerbOPTIONS = 3,
HttpVerbGET = 4,
HttpVerbHEAD = 5,
HttpVerbPOST = 6,
HttpVerbPUT = 7,
HttpVerbDELETE = 8,
HttpVerbTRACE = 9,
HttpVerbCONNECT = 10,
HttpVerbTRACK = 11,
HttpVerbMOVE = 12,
HttpVerbCOPY = 13,
HttpVerbPROPFIND = 14,
HttpVerbPROPPATCH = 15,
HttpVerbMKCOL = 16,
HttpVerbLOCK = 17,
HttpVerbUNLOCK = 18,
HttpVerbSEARCH = 19,
HttpVerbMaximum = 20,
}
internal static readonly string[] HttpVerbs = new string[]
{
null,
"Unknown",
"Invalid",
"OPTIONS",
"GET",
"HEAD",
"POST",
"PUT",
"DELETE",
"TRACE",
"CONNECT",
"TRACK",
"MOVE",
"COPY",
"PROPFIND",
"PROPPATCH",
"MKCOL",
"LOCK",
"UNLOCK",
"SEARCH",
};
internal enum HTTP_DATA_CHUNK_TYPE : int
{
HttpDataChunkFromMemory = 0,
HttpDataChunkFromFileHandle = 1,
HttpDataChunkFromFragmentCache = 2,
HttpDataChunkMaximum = 3,
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_RESPONSE_INFO
{
internal HTTP_RESPONSE_INFO_TYPE Type;
internal uint Length;
internal HTTP_MULTIPLE_KNOWN_HEADERS* pInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_RESPONSE
{
internal uint Flags;
internal HTTP_VERSION Version;
internal ushort StatusCode;
internal ushort ReasonLength;
internal byte* pReason;
internal HTTP_RESPONSE_HEADERS Headers;
internal ushort EntityChunkCount;
internal HTTP_DATA_CHUNK* pEntityChunks;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_RESPONSE_V2
{
internal HTTP_RESPONSE Response_V1;
internal ushort ResponseInfoCount;
internal HTTP_RESPONSE_INFO* pResponseInfo;
}
internal enum HTTP_RESPONSE_INFO_FLAGS : uint
{
None = 0,
PreserveOrder = 1,
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_MULTIPLE_KNOWN_HEADERS
{
internal HTTP_RESPONSE_HEADER_ID.Enum HeaderId;
internal HTTP_RESPONSE_INFO_FLAGS Flags;
internal ushort KnownHeaderCount;
internal HTTP_KNOWN_HEADER* KnownHeaders;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_AUTH_INFO
{
internal HTTP_AUTH_STATUS AuthStatus;
internal uint SecStatus;
internal uint Flags;
internal HTTP_REQUEST_AUTH_TYPE AuthType;
internal IntPtr AccessToken;
internal uint ContextAttributes;
internal uint PackedContextLength;
internal uint PackedContextType;
internal IntPtr PackedContext;
internal uint MutualAuthDataLength;
internal char* pMutualAuthData;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_INFO
{
internal HTTP_REQUEST_INFO_TYPE InfoType;
internal uint InfoLength;
internal HTTP_REQUEST_AUTH_INFO* pInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST
{
internal uint Flags;
internal ulong ConnectionId;
internal ulong RequestId;
internal ulong UrlContext;
internal HTTP_VERSION Version;
internal HTTP_VERB Verb;
internal ushort UnknownVerbLength;
internal ushort RawUrlLength;
internal byte* pUnknownVerb;
internal byte* pRawUrl;
internal HTTP_COOKED_URL CookedUrl;
internal HTTP_TRANSPORT_ADDRESS Address;
internal HTTP_REQUEST_HEADERS Headers;
internal ulong BytesReceived;
internal ushort EntityChunkCount;
internal HTTP_DATA_CHUNK* pEntityChunks;
internal ulong RawConnectionId;
internal HTTP_SSL_INFO* pSslInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_V2
{
internal HTTP_REQUEST Request;
internal ushort RequestInfoCount;
internal HTTP_REQUEST_INFO* pRequestInfo;
}
internal enum HTTP_AUTH_STATUS
{
HttpAuthStatusSuccess,
HttpAuthStatusNotAuthenticated,
HttpAuthStatusFailure,
}
internal enum HTTP_REQUEST_AUTH_TYPE
{
HttpRequestAuthTypeNone = 0,
HttpRequestAuthTypeBasic,
HttpRequestAuthTypeDigest,
HttpRequestAuthTypeNTLM,
HttpRequestAuthTypeNegotiate,
HttpRequestAuthTypeKerberos
}
internal enum HTTP_QOS_SETTING_TYPE
{
HttpQosSettingTypeBandwidth,
HttpQosSettingTypeConnectionLimit,
HttpQosSettingTypeFlowRate
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SERVER_AUTHENTICATION_INFO
{
internal HTTP_FLAGS Flags;
internal HTTP_AUTH_TYPES AuthSchemes;
internal bool ReceiveMutualAuth;
internal bool ReceiveContextHandle;
internal bool DisableNTLMCredentialCaching;
internal ulong ExFlags;
HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS DigestParams;
HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS BasicParams;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS
{
internal ushort DomainNameLength;
internal char* DomainName;
internal ushort RealmLength;
internal char* Realm;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS
{
ushort RealmLength;
char* Realm;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_TOKEN_BINDING_INFO
{
public byte* TokenBinding;
public uint TokenBindingSize;
public byte* TlsUnique;
public uint TlsUniqueSize;
public char* KeyType;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_TIMEOUT_LIMIT_INFO
{
internal HTTP_FLAGS Flags;
internal ushort EntityBody;
internal ushort DrainEntityBody;
internal ushort RequestQueue;
internal ushort IdleConnection;
internal ushort HeaderWait;
internal uint MinSendRate;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_BINDING_INFO
{
internal HTTP_FLAGS Flags;
internal IntPtr RequestQueueHandle;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_CONNECTION_LIMIT_INFO
{
internal HTTP_FLAGS Flags;
internal uint MaxConnections;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_QOS_SETTING_INFO
{
internal HTTP_QOS_SETTING_TYPE QosType;
internal IntPtr QosSetting;
}
// see http.w for definitions
[Flags]
internal enum HTTP_FLAGS : uint
{
NONE = 0x00000000,
HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY = 0x00000001,
HTTP_RECEIVE_SECURE_CHANNEL_TOKEN = 0x00000001,
HTTP_SEND_RESPONSE_FLAG_DISCONNECT = 0x00000001,
HTTP_SEND_RESPONSE_FLAG_MORE_DATA = 0x00000002,
HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA = 0x00000004,
HTTP_SEND_RESPONSE_FLAG_RAW_HEADER = 0x00000004,
HTTP_SEND_REQUEST_FLAG_MORE_DATA = 0x00000001,
HTTP_PROPERTY_FLAG_PRESENT = 0x00000001,
HTTP_INITIALIZE_SERVER = 0x00000001,
HTTP_INITIALIZE_CBT = 0x00000004,
HTTP_SEND_RESPONSE_FLAG_OPAQUE = 0x00000040,
}
[Flags]
internal enum HTTP_AUTH_TYPES : uint
{
NONE = 0x00000000,
HTTP_AUTH_ENABLE_BASIC = 0x00000001,
HTTP_AUTH_ENABLE_DIGEST = 0x00000002,
HTTP_AUTH_ENABLE_NTLM = 0x00000004,
HTTP_AUTH_ENABLE_NEGOTIATE = 0x00000008,
HTTP_AUTH_ENABLE_KERBEROS = 0x00000010,
}
internal static class HTTP_RESPONSE_HEADER_ID
{
private static string[] _strings =
{
"Cache-Control",
"Connection",
"Date",
"Keep-Alive",
"Pragma",
"Trailer",
"Transfer-Encoding",
"Upgrade",
"Via",
"Warning",
"Allow",
"Content-Length",
"Content-Type",
"Content-Encoding",
"Content-Language",
"Content-Location",
"Content-MD5",
"Content-Range",
"Expires",
"Last-Modified",
"Accept-Ranges",
"Age",
"ETag",
"Location",
"Proxy-Authenticate",
"Retry-After",
"Server",
"Set-Cookie",
"Vary",
"WWW-Authenticate",
};
private static Dictionary<string, int> _lookupTable = CreateLookupTable();
private static Dictionary<string, int> CreateLookupTable()
{
Dictionary<string, int> lookupTable = new Dictionary<string, int>((int)Enum.HttpHeaderResponseMaximum, StringComparer.OrdinalIgnoreCase);
for (int i = 0; i < (int)Enum.HttpHeaderResponseMaximum; i++)
{
lookupTable.Add(_strings[i], i);
}
return lookupTable;
}
internal static int IndexOfKnownHeader(string HeaderName)
{
int index;
return _lookupTable.TryGetValue(HeaderName, out index) ? index : -1;
}
internal enum Enum
{
HttpHeaderCacheControl = 0, // general-header [section 4.5]
HttpHeaderConnection = 1, // general-header [section 4.5]
HttpHeaderDate = 2, // general-header [section 4.5]
HttpHeaderKeepAlive = 3, // general-header [not in rfc]
HttpHeaderPragma = 4, // general-header [section 4.5]
HttpHeaderTrailer = 5, // general-header [section 4.5]
HttpHeaderTransferEncoding = 6, // general-header [section 4.5]
HttpHeaderUpgrade = 7, // general-header [section 4.5]
HttpHeaderVia = 8, // general-header [section 4.5]
HttpHeaderWarning = 9, // general-header [section 4.5]
HttpHeaderAllow = 10, // entity-header [section 7.1]
HttpHeaderContentLength = 11, // entity-header [section 7.1]
HttpHeaderContentType = 12, // entity-header [section 7.1]
HttpHeaderContentEncoding = 13, // entity-header [section 7.1]
HttpHeaderContentLanguage = 14, // entity-header [section 7.1]
HttpHeaderContentLocation = 15, // entity-header [section 7.1]
HttpHeaderContentMd5 = 16, // entity-header [section 7.1]
HttpHeaderContentRange = 17, // entity-header [section 7.1]
HttpHeaderExpires = 18, // entity-header [section 7.1]
HttpHeaderLastModified = 19, // entity-header [section 7.1]
// Response Headers
HttpHeaderAcceptRanges = 20, // response-header [section 6.2]
HttpHeaderAge = 21, // response-header [section 6.2]
HttpHeaderEtag = 22, // response-header [section 6.2]
HttpHeaderLocation = 23, // response-header [section 6.2]
HttpHeaderProxyAuthenticate = 24, // response-header [section 6.2]
HttpHeaderRetryAfter = 25, // response-header [section 6.2]
HttpHeaderServer = 26, // response-header [section 6.2]
HttpHeaderSetCookie = 27, // response-header [not in rfc]
HttpHeaderVary = 28, // response-header [section 6.2]
HttpHeaderWwwAuthenticate = 29, // response-header [section 6.2]
HttpHeaderResponseMaximum = 30,
HttpHeaderMaximum = 41
}
}
}
}

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal enum HttpSysRequestHeader
{

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal enum HttpSysResponseHeader
{

Просмотреть файл

@ -3,7 +3,7 @@
using System;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal static class NclUtilities
{

Просмотреть файл

@ -4,7 +4,7 @@
using System;
using System.Security.Authentication.ExtendedProtection;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal class SafeLocalFreeChannelBinding : ChannelBinding
{

Просмотреть файл

@ -4,7 +4,7 @@
using System;
using Microsoft.Win32.SafeHandles;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal sealed class SafeLocalMemHandle : SafeHandleZeroOrMinusOneIsInvalid
{

Просмотреть файл

@ -5,7 +5,7 @@ using System;
using System.Runtime.InteropServices;
using System.Threading;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal class SafeNativeOverlapped : SafeHandle
{

Просмотреть файл

@ -6,9 +6,10 @@ using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
// a little perf app measured these times when comparing the internal
// buffer implemented as a managed byte[] or unmanaged memory IntPtr

Просмотреть файл

@ -5,7 +5,7 @@ using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal static unsafe class UnsafeNclNativeMethods
{

Просмотреть файл

@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal class HeaderCollection : IHeaderDictionary
{

Просмотреть файл

@ -3,7 +3,7 @@
using System.Text;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal static class HeaderEncoding
{
@ -12,15 +12,15 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// (e.g. IE and HttpWebRequest on intranets).
private static Encoding Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: false);
internal static unsafe string GetString(sbyte* pBytes, int byteCount)
internal static unsafe string GetString(byte* pBytes, int byteCount)
{
// net451: return new string(pBytes, 0, byteCount, Encoding);
var charCount = Encoding.GetCharCount((byte*)pBytes, byteCount);
var charCount = Encoding.GetCharCount(pBytes, byteCount);
var chars = new char[charCount];
fixed (char* pChars = chars)
{
var count = Encoding.GetChars((byte*)pBytes, byteCount, pChars, charCount);
var count = Encoding.GetChars(pBytes, byteCount, pChars, charCount);
System.Diagnostics.Debug.Assert(count == charCount);
}
return new string(chars);

Просмотреть файл

@ -1,11 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal static class HeaderParser
{

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal static class HttpKnownHeaderNames
{

Просмотреть файл

@ -0,0 +1,455 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Principal;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal unsafe class NativeRequestContext : IDisposable
{
private const int AlignmentPadding = 8;
private IntPtr _originalBufferAddress;
private HttpApiTypes.HTTP_REQUEST* _nativeRequest;
private byte[] _backingBuffer;
private int _bufferAlignment;
private SafeNativeOverlapped _nativeOverlapped;
private bool _permanentlyPinned;
// To be used by HttpSys
internal NativeRequestContext(SafeNativeOverlapped nativeOverlapped,
int bufferAlignment,
HttpApiTypes.HTTP_REQUEST* nativeRequest,
byte[] backingBuffer,
ulong requestId)
{
_nativeOverlapped = nativeOverlapped;
_bufferAlignment = bufferAlignment;
_nativeRequest = nativeRequest;
_backingBuffer = backingBuffer;
RequestId = requestId;
}
// To be used by IIS Integration.
internal NativeRequestContext(HttpApiTypes.HTTP_REQUEST* request)
{
_nativeRequest = request;
_bufferAlignment = 0;
_permanentlyPinned = true;
}
internal SafeNativeOverlapped NativeOverlapped => _nativeOverlapped;
internal HttpApiTypes.HTTP_REQUEST* NativeRequest
{
get
{
Debug.Assert(_nativeRequest != null || _backingBuffer == null, "native request accessed after ReleasePins().");
return _nativeRequest;
}
}
internal HttpApiTypes.HTTP_REQUEST_V2* NativeRequestV2
{
get
{
Debug.Assert(_nativeRequest != null || _backingBuffer == null, "native request accessed after ReleasePins().");
return (HttpApiTypes.HTTP_REQUEST_V2*)_nativeRequest;
}
}
internal ulong RequestId
{
get { return NativeRequest->RequestId; }
set { NativeRequest->RequestId = value; }
}
internal ulong ConnectionId => NativeRequest->ConnectionId;
internal HttpApiTypes.HTTP_VERB VerbId => NativeRequest->Verb;
internal ulong UrlContext => NativeRequest->UrlContext;
internal ushort UnknownHeaderCount => NativeRequest->Headers.UnknownHeaderCount;
internal SslStatus SslStatus
{
get
{
return NativeRequest->pSslInfo == null ? SslStatus.Insecure :
NativeRequest->pSslInfo->SslClientCertNegotiated == 0 ? SslStatus.NoClientCert :
SslStatus.ClientCert;
}
}
internal uint Size
{
get { return (uint)_backingBuffer.Length - AlignmentPadding; }
}
// ReleasePins() should be called exactly once. It must be called before Dispose() is called, which means it must be called
// before an object (Request) which closes the RequestContext on demand is returned to the application.
internal void ReleasePins()
{
Debug.Assert(_nativeRequest != null || _backingBuffer == null, "RequestContextBase::ReleasePins()|ReleasePins() called twice.");
_originalBufferAddress = (IntPtr)_nativeRequest;
_nativeRequest = null;
_nativeOverlapped?.Dispose();
_nativeOverlapped = null;
}
public virtual void Dispose()
{
Debug.Assert(_nativeRequest == null, "RequestContextBase::Dispose()|Dispose() called before ReleasePins().");
_nativeOverlapped?.Dispose();
}
// These methods require the HTTP_REQUEST to still be pinned in its original location.
internal string GetVerb()
{
var verb = NativeRequest->Verb;
if (verb > HttpApiTypes.HTTP_VERB.HttpVerbUnknown && verb < HttpApiTypes.HTTP_VERB.HttpVerbMaximum)
{
return HttpApiTypes.HttpVerbs[(int)verb];
}
else if (verb == HttpApiTypes.HTTP_VERB.HttpVerbUnknown && NativeRequest->pUnknownVerb != null)
{
return HeaderEncoding.GetString(NativeRequest->pUnknownVerb, NativeRequest->UnknownVerbLength);
}
return null;
}
internal string GetRawUrl()
{
if (NativeRequest->pRawUrl != null && NativeRequest->RawUrlLength > 0)
{
return Marshal.PtrToStringAnsi((IntPtr)NativeRequest->pRawUrl, NativeRequest->RawUrlLength);
}
return null;
}
internal byte[] GetRawUrlInBytes()
{
if (NativeRequest->pRawUrl != null && NativeRequest->RawUrlLength > 0)
{
var result = new byte[NativeRequest->RawUrlLength];
Marshal.Copy((IntPtr)NativeRequest->pRawUrl, result, 0, NativeRequest->RawUrlLength);
return result;
}
return null;
}
internal CookedUrl GetCookedUrl()
{
return new CookedUrl(NativeRequest->CookedUrl);
}
internal Version GetVersion()
{
var major = NativeRequest->Version.MajorVersion;
var minor = NativeRequest->Version.MinorVersion;
if (major == 1 && minor == 1)
{
return Constants.V1_1;
}
else if (major == 1 && minor == 0)
{
return Constants.V1_0;
}
return new Version(major, minor);
}
internal bool CheckAuthenticated()
{
var requestInfo = NativeRequestV2->pRequestInfo;
var infoCount = NativeRequestV2->RequestInfoCount;
for (int i = 0; i < infoCount; i++)
{
var info = &requestInfo[i];
if (info != null
&& info->InfoType == HttpApiTypes.HTTP_REQUEST_INFO_TYPE.HttpRequestInfoTypeAuth
&& info->pInfo->AuthStatus == HttpApiTypes.HTTP_AUTH_STATUS.HttpAuthStatusSuccess)
{
return true;
}
}
return false;
}
internal WindowsPrincipal GetUser()
{
var requestInfo = NativeRequestV2->pRequestInfo;
var infoCount = NativeRequestV2->RequestInfoCount;
for (int i = 0; i < infoCount; i++)
{
var info = &requestInfo[i];
if (info != null
&& info->InfoType == HttpApiTypes.HTTP_REQUEST_INFO_TYPE.HttpRequestInfoTypeAuth
&& info->pInfo->AuthStatus == HttpApiTypes.HTTP_AUTH_STATUS.HttpAuthStatusSuccess)
{
// Duplicates AccessToken
var identity = new WindowsIdentity(info->pInfo->AccessToken, GetAuthTypeFromRequest(info->pInfo->AuthType));
// Close the original
UnsafeNclNativeMethods.SafeNetHandles.CloseHandle(info->pInfo->AccessToken);
return new WindowsPrincipal(identity);
}
}
return new WindowsPrincipal(WindowsIdentity.GetAnonymous()); // Anonymous / !IsAuthenticated
}
private static string GetAuthTypeFromRequest(HttpApiTypes.HTTP_REQUEST_AUTH_TYPE input)
{
switch (input)
{
case HttpApiTypes.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeBasic:
return "Basic";
case HttpApiTypes.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeNTLM:
return "NTLM";
// case HttpApi.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeDigest:
// return "Digest";
case HttpApiTypes.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeNegotiate:
return "Negotiate";
case HttpApiTypes.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeKerberos:
return "Kerberos";
default:
throw new NotImplementedException(input.ToString());
}
}
// These methods are for accessing the request structure after it has been unpinned. They need to adjust addresses
// in case GC has moved the original object.
internal string GetKnownHeader(HttpSysRequestHeader header)
{
if (_permanentlyPinned)
{
return GetKnowHeaderHelper(header, 0, _nativeRequest);
}
else
{
fixed (byte* pMemoryBlob = _backingBuffer)
{
var request = (HttpApiTypes.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment);
long fixup = pMemoryBlob - (byte*)_originalBufferAddress;
return GetKnowHeaderHelper(header, fixup, request);
}
}
}
private string GetKnowHeaderHelper(HttpSysRequestHeader header, long fixup, HttpApiTypes.HTTP_REQUEST* request)
{
int headerIndex = (int)header;
string value = null;
HttpApiTypes.HTTP_KNOWN_HEADER* pKnownHeader = (&request->Headers.KnownHeaders) + headerIndex;
// For known headers, when header value is empty, RawValueLength will be 0 and
// pRawValue will point to empty string ("\0")
if (pKnownHeader->pRawValue != null)
{
value = HeaderEncoding.GetString(pKnownHeader->pRawValue + fixup, pKnownHeader->RawValueLength);
}
return value;
}
internal void GetUnknownHeaders(IDictionary<string, StringValues> unknownHeaders)
{
if (_permanentlyPinned)
{
GetUnknownHeadersHelper(unknownHeaders, 0, _nativeRequest);
}
else
{
// Return value.
fixed (byte* pMemoryBlob = _backingBuffer)
{
var request = (HttpApiTypes.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment);
long fixup = pMemoryBlob - (byte*)_originalBufferAddress;
GetUnknownHeadersHelper(unknownHeaders, fixup, request);
}
}
}
private void GetUnknownHeadersHelper(IDictionary<string, StringValues> unknownHeaders, long fixup, HttpApiTypes.HTTP_REQUEST* request)
{
int index;
// unknown headers
if (request->Headers.UnknownHeaderCount != 0)
{
var pUnknownHeader = (HttpApiTypes.HTTP_UNKNOWN_HEADER*)(fixup + (byte*)request->Headers.pUnknownHeaders);
for (index = 0; index < request->Headers.UnknownHeaderCount; index++)
{
// For unknown headers, when header value is empty, RawValueLength will be 0 and
// pRawValue will be null.
if (pUnknownHeader->pName != null && pUnknownHeader->NameLength > 0)
{
var headerName = HeaderEncoding.GetString(pUnknownHeader->pName + fixup, pUnknownHeader->NameLength);
string headerValue;
if (pUnknownHeader->pRawValue != null && pUnknownHeader->RawValueLength > 0)
{
headerValue = HeaderEncoding.GetString(pUnknownHeader->pRawValue + fixup, pUnknownHeader->RawValueLength);
}
else
{
headerValue = string.Empty;
}
// Note that Http.Sys currently collapses all headers of the same name to a single coma separated string,
// so we can just call Set.
unknownHeaders[headerName] = headerValue;
}
pUnknownHeader++;
}
}
}
internal SocketAddress GetRemoteEndPoint()
{
return GetEndPoint(localEndpoint: false);
}
internal SocketAddress GetLocalEndPoint()
{
return GetEndPoint(localEndpoint: true);
}
private SocketAddress GetEndPoint(bool localEndpoint)
{
if (_permanentlyPinned)
{
return GetEndPointHelper(localEndpoint, _nativeRequest, (byte *)0);
}
else
{
fixed (byte* pMemoryBlob = _backingBuffer)
{
var request = (HttpApiTypes.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment);
return GetEndPointHelper(localEndpoint, request, pMemoryBlob);
}
}
}
private SocketAddress GetEndPointHelper(bool localEndpoint, HttpApiTypes.HTTP_REQUEST* request, byte* pMemoryBlob)
{
var source = localEndpoint ? (byte*)request->Address.pLocalAddress : (byte*)request->Address.pRemoteAddress;
if (source == null)
{
return null;
}
var address = (IntPtr)(pMemoryBlob + _bufferAlignment - (byte*)_originalBufferAddress + source);
return CopyOutAddress(address);
}
private static SocketAddress CopyOutAddress(IntPtr address)
{
ushort addressFamily = *((ushort*)address);
if (addressFamily == (ushort)AddressFamily.InterNetwork)
{
var v4address = new SocketAddress(AddressFamily.InterNetwork, SocketAddress.IPv4AddressSize);
fixed (byte* pBuffer = v4address.Buffer)
{
for (int index = 2; index < SocketAddress.IPv4AddressSize; index++)
{
pBuffer[index] = ((byte*)address)[index];
}
}
return v4address;
}
if (addressFamily == (ushort)AddressFamily.InterNetworkV6)
{
var v6address = new SocketAddress(AddressFamily.InterNetworkV6, SocketAddress.IPv6AddressSize);
fixed (byte* pBuffer = v6address.Buffer)
{
for (int index = 2; index < SocketAddress.IPv6AddressSize; index++)
{
pBuffer[index] = ((byte*)address)[index];
}
}
return v6address;
}
return null;
}
internal uint GetChunks(ref int dataChunkIndex, ref uint dataChunkOffset, byte[] buffer, int offset, int size)
{
// Return value.
if (_permanentlyPinned)
{
return GetChunksHelper(ref dataChunkIndex, ref dataChunkOffset, buffer, offset, size, 0, _nativeRequest);
}
else
{
fixed (byte* pMemoryBlob = _backingBuffer)
{
var request = (HttpApiTypes.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment);
long fixup = pMemoryBlob - (byte*)_originalBufferAddress;
return GetChunksHelper(ref dataChunkIndex, ref dataChunkOffset, buffer, offset, size, fixup, request);
}
}
}
private uint GetChunksHelper(ref int dataChunkIndex, ref uint dataChunkOffset, byte[] buffer, int offset, int size, long fixup, HttpApiTypes.HTTP_REQUEST* request)
{
uint dataRead = 0;
if (request->EntityChunkCount > 0 && dataChunkIndex < request->EntityChunkCount && dataChunkIndex != -1)
{
var pDataChunk = (HttpApiTypes.HTTP_DATA_CHUNK*)(fixup + (byte*)&request->pEntityChunks[dataChunkIndex]);
fixed (byte* pReadBuffer = buffer)
{
byte* pTo = &pReadBuffer[offset];
while (dataChunkIndex < request->EntityChunkCount && dataRead < size)
{
if (dataChunkOffset >= pDataChunk->fromMemory.BufferLength)
{
dataChunkOffset = 0;
dataChunkIndex++;
pDataChunk++;
}
else
{
byte* pFrom = (byte*)pDataChunk->fromMemory.pBuffer + dataChunkOffset + fixup;
uint bytesToRead = pDataChunk->fromMemory.BufferLength - (uint)dataChunkOffset;
if (bytesToRead > (uint)size)
{
bytesToRead = (uint)size;
}
for (uint i = 0; i < bytesToRead; i++)
{
*(pTo++) = *(pFrom++);
}
dataRead += bytesToRead;
dataChunkOffset += bytesToRead;
}
}
}
}
// we're finished.
if (dataChunkIndex == request->EntityChunkCount)
{
dataChunkIndex = -1;
}
return dataRead;
}
}
}

Просмотреть файл

@ -3,7 +3,7 @@
using System;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal static class RawUrlHelper
{

Просмотреть файл

@ -11,7 +11,7 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
[GeneratedCode("TextTemplatingFileGenerator", "")]
internal partial class RequestHeaders

Просмотреть файл

@ -6,20 +6,26 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal partial class RequestHeaders : IDictionary<string, StringValues>
internal partial class RequestHeaders : IHeaderDictionary
{
private IDictionary<string, StringValues> _extra;
private NativeRequestContext _requestMemoryBlob;
private long? _contentLength;
private StringValues _contentLengthText;
internal RequestHeaders(NativeRequestContext requestMemoryBlob)
{
_requestMemoryBlob = requestMemoryBlob;
}
public bool IsReadOnly { get; internal set; }
private IDictionary<string, StringValues> Extra
{
get
@ -43,6 +49,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
set
{
ThrowIfReadOnly();
if (!PropertiesTrySetValue(key, value))
{
Extra[key] = value;
@ -131,6 +138,96 @@ namespace Microsoft.AspNetCore.Server.HttpSys
get { return false; }
}
long? IHeaderDictionary.ContentLength
{
get
{
long value;
var rawValue = this[HttpKnownHeaderNames.ContentLength];
if (_contentLengthText.Equals(rawValue))
{
return _contentLength;
}
if (rawValue.Count == 1 &&
!string.IsNullOrWhiteSpace(rawValue[0]) &&
HeaderUtilities.TryParseNonNegativeInt64(new StringSegment(rawValue[0]).Trim(), out value))
{
_contentLengthText = rawValue;
_contentLength = value;
return value;
}
return null;
}
set
{
ThrowIfReadOnly();
if (value.HasValue)
{
if (value.Value < 0)
{
throw new ArgumentOutOfRangeException("value", value.Value, "Cannot be negative.");
}
_contentLengthText = HeaderUtilities.FormatNonNegativeInt64(value.Value);
this[HttpKnownHeaderNames.ContentLength] = _contentLengthText;
_contentLength = value;
}
else
{
Remove(HttpKnownHeaderNames.ContentLength);
_contentLengthText = StringValues.Empty;
_contentLength = null;
}
}
}
public StringValues this[string key]
{
get
{
StringValues values;
return TryGetValue(key, out values) ? values : StringValues.Empty;
}
set
{
if (StringValues.IsNullOrEmpty(value))
{
Remove(key);
}
else
{
Extra[key] = value;
}
}
}
StringValues IHeaderDictionary.this[string key]
{
get
{
if (PropertiesTryGetValue(key, out var value))
{
return value;
}
if (Extra.TryGetValue(key, out value))
{
return value;
}
return StringValues.Empty;
}
set
{
if (!PropertiesTrySetValue(key, value))
{
Extra[key] = value;
}
}
}
bool ICollection<KeyValuePair<string, StringValues>>.Remove(KeyValuePair<string, StringValues> item)
{
return ((IDictionary<string, StringValues>)this).Contains(item) &&
@ -146,5 +243,23 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
return ((IDictionary<string, StringValues>)this).GetEnumerator();
}
private void ThrowIfReadOnly()
{
if (IsReadOnly)
{
throw new InvalidOperationException("The response headers cannot be modified because the response has already started.");
}
}
public IEnumerable<string> GetValues(string key)
{
StringValues values;
if (TryGetValue(key, out values))
{
return HeaderParser.SplitValues(values);
}
return HeaderParser.Empty;
}
}
}

Просмотреть файл

@ -4,7 +4,7 @@
using System;
using System.Text;
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
// We don't use the cooked URL because http.sys unescapes all percent-encoded values. However,
// we also can't just use the raw Uri, since http.sys supports not only UTF-8, but also ANSI/DBCS and

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Server.HttpSys
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal enum SslStatus : byte
{

Просмотреть файл

@ -3,9 +3,10 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.HttpSys.Internal;
namespace Microsoft.AspNetCore.Server.HttpSys
{
@ -16,12 +17,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private TaskCompletionSource<RequestContext> _tcs;
private HttpSysListener _server;
private NativeRequestContext _nativeRequestContext;
private const int DefaultBufferSize = 4096;
private const int AlignmentPadding = 8;
internal AsyncAcceptContext(HttpSysListener server)
{
_server = server;
_tcs = new TaskCompletionSource<RequestContext>();
_nativeRequestContext = new NativeRequestContext(this);
AllocateNativeRequest();
}
internal Task<RequestContext> Task
@ -68,12 +71,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
// at this point we have received an unmanaged HTTP_REQUEST and memoryBlob
// points to it we need to hook up our authentication handling code here.
bool stoleBlob = false;
try
{
if (server.ValidateRequest(asyncResult._nativeRequestContext) && server.ValidateAuth(asyncResult._nativeRequestContext))
{
stoleBlob = true;
RequestContext requestContext = new RequestContext(server, asyncResult._nativeRequestContext);
asyncResult.Tcs.TrySetResult(requestContext);
complete = true;
@ -81,20 +82,21 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
finally
{
if (stoleBlob)
// The request has been handed to the user, which means this code can't reuse the blob. Reset it here.
if (complete)
{
// The request has been handed to the user, which means this code can't reuse the blob. Reset it here.
asyncResult._nativeRequestContext = complete ? null : new NativeRequestContext(asyncResult);
asyncResult._nativeRequestContext = null;
}
else
{
asyncResult._nativeRequestContext.Reset();
asyncResult.AllocateNativeRequest(size: asyncResult._nativeRequestContext.Size);
}
}
}
else
{
asyncResult._nativeRequestContext.Reset(asyncResult._nativeRequestContext.RequestId, numBytes);
// (uint)backingBuffer.Length - AlignmentPadding
asyncResult.AllocateNativeRequest(numBytes, asyncResult._nativeRequestContext.RequestId);
}
// We need to issue a new request, either because auth failed, or because our buffer was too small the first time.
@ -147,7 +149,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
statusCode = HttpApi.HttpReceiveHttpRequest(
Server.RequestQueue.Handle,
_nativeRequestContext.RequestId,
(uint)HttpApi.HTTP_FLAGS.HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY,
(uint)HttpApiTypes.HTTP_FLAGS.HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY,
_nativeRequestContext.NativeRequest,
_nativeRequestContext.Size,
&bytesTransferred,
@ -165,7 +167,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
// the buffer was not big enough to fit the headers, we need
// to read the RequestId returned, allocate a new buffer of the required size
_nativeRequestContext.Reset(_nativeRequestContext.RequestId, bytesTransferred);
// (uint)backingBuffer.Length - AlignmentPadding
AllocateNativeRequest(bytesTransferred);
retry = true;
}
else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS
@ -179,6 +182,36 @@ namespace Microsoft.AspNetCore.Server.HttpSys
return statusCode;
}
internal void AllocateNativeRequest(uint? size = null, ulong requestId = 0)
{
//Debug.Assert(size != 0, "unexpected size");
// We can't reuse overlapped objects
uint newSize = size.HasValue ? size.Value : DefaultBufferSize;
var backingBuffer = new byte[newSize + AlignmentPadding];
var boundHandle = Server.RequestQueue.BoundHandle;
var nativeOverlapped = new SafeNativeOverlapped(boundHandle,
boundHandle.AllocateNativeOverlapped(IOCallback, this, backingBuffer));
var requestAddress = Marshal.UnsafeAddrOfPinnedArrayElement(backingBuffer, 0);
// TODO:
// Apparently the HttpReceiveHttpRequest memory alignment requirements for non - ARM processors
// are different than for ARM processors. We have seen 4 - byte - aligned buffers allocated on
// virtual x64/x86 machines which were accepted by HttpReceiveHttpRequest without errors. In
// these cases the buffer alignment may cause reading values at invalid offset. Setting buffer
// alignment to 0 for now.
//
// _bufferAlignment = (int)(requestAddress.ToInt64() & 0x07);
var bufferAlignment = 0;
var nativeRequest = (HttpApiTypes.HTTP_REQUEST*)(requestAddress + bufferAlignment);
// nativeRequest
_nativeRequestContext = new NativeRequestContext(nativeOverlapped, bufferAlignment, nativeRequest, backingBuffer, requestId);
}
public object AsyncState
{
get { return _tcs.Task.AsyncState; }

Просмотреть файл

@ -8,6 +8,7 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Claims;
using System.Security.Principal;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Server.HttpSys
@ -21,7 +22,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
public sealed class AuthenticationManager
{
private static readonly int AuthInfoSize =
Marshal.SizeOf<HttpApi.HTTP_SERVER_AUTHENTICATION_INFO>();
Marshal.SizeOf<HttpApiTypes.HTTP_SERVER_AUTHENTICATION_INFO>();
private UrlGroup _urlGroup;
private AuthenticationSchemes _authSchemes;
@ -62,12 +63,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
return;
}
HttpApi.HTTP_SERVER_AUTHENTICATION_INFO authInfo =
new HttpApi.HTTP_SERVER_AUTHENTICATION_INFO();
HttpApiTypes.HTTP_SERVER_AUTHENTICATION_INFO authInfo =
new HttpApiTypes.HTTP_SERVER_AUTHENTICATION_INFO();
authInfo.Flags = HttpApi.HTTP_FLAGS.HTTP_PROPERTY_FLAG_PRESENT;
var authSchemes = (HttpApi.HTTP_AUTH_TYPES)_authSchemes;
if (authSchemes != HttpApi.HTTP_AUTH_TYPES.NONE)
authInfo.Flags = HttpApiTypes.HTTP_FLAGS.HTTP_PROPERTY_FLAG_PRESENT;
var authSchemes = (HttpApiTypes.HTTP_AUTH_TYPES)_authSchemes;
if (authSchemes != HttpApiTypes.HTTP_AUTH_TYPES.NONE)
{
authInfo.AuthSchemes = authSchemes;
@ -81,7 +82,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
IntPtr infoptr = new IntPtr(&authInfo);
_urlGroup.SetProperty(
HttpApi.HTTP_SERVER_PROPERTY.HttpServerAuthenticationProperty,
HttpApiTypes.HTTP_SERVER_PROPERTY.HttpServerAuthenticationProperty,
infoptr, (uint)AuthInfoSize);
}
}

Просмотреть файл

@ -7,6 +7,7 @@ using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.HttpSys
@ -56,7 +57,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
throw new PlatformNotSupportedException();
}
Debug.Assert(HttpApi.ApiVersion == HttpApi.HTTP_API_VERSION.Version20, "Invalid Http api version");
Debug.Assert(HttpApi.ApiVersion == HttpApiTypes.HTTP_API_VERSION.Version20, "Invalid Http api version");
Options = options;
@ -317,8 +318,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private unsafe void SendError(ulong requestId, int httpStatusCode, IList<string> authChallenges)
{
HttpApi.HTTP_RESPONSE_V2 httpResponse = new HttpApi.HTTP_RESPONSE_V2();
httpResponse.Response_V1.Version = new HttpApi.HTTP_VERSION();
HttpApiTypes.HTTP_RESPONSE_V2 httpResponse = new HttpApiTypes.HTTP_RESPONSE_V2();
httpResponse.Response_V1.Version = new HttpApiTypes.HTTP_VERSION();
httpResponse.Response_V1.Version.MajorVersion = (ushort)1;
httpResponse.Response_V1.Version.MinorVersion = (ushort)1;
@ -331,25 +332,25 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
pinnedHeaders = new List<GCHandle>();
HttpApi.HTTP_RESPONSE_INFO[] knownHeaderInfo = null;
knownHeaderInfo = new HttpApi.HTTP_RESPONSE_INFO[1];
HttpApiTypes.HTTP_RESPONSE_INFO[] knownHeaderInfo = null;
knownHeaderInfo = new HttpApiTypes.HTTP_RESPONSE_INFO[1];
gcHandle = GCHandle.Alloc(knownHeaderInfo, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
httpResponse.pResponseInfo = (HttpApi.HTTP_RESPONSE_INFO*)gcHandle.AddrOfPinnedObject();
httpResponse.pResponseInfo = (HttpApiTypes.HTTP_RESPONSE_INFO*)gcHandle.AddrOfPinnedObject();
knownHeaderInfo[httpResponse.ResponseInfoCount].Type = HttpApi.HTTP_RESPONSE_INFO_TYPE.HttpResponseInfoTypeMultipleKnownHeaders;
knownHeaderInfo[httpResponse.ResponseInfoCount].Type = HttpApiTypes.HTTP_RESPONSE_INFO_TYPE.HttpResponseInfoTypeMultipleKnownHeaders;
knownHeaderInfo[httpResponse.ResponseInfoCount].Length =
(uint)Marshal.SizeOf<HttpApi.HTTP_MULTIPLE_KNOWN_HEADERS>();
(uint)Marshal.SizeOf<HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS>();
HttpApi.HTTP_MULTIPLE_KNOWN_HEADERS header = new HttpApi.HTTP_MULTIPLE_KNOWN_HEADERS();
HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS header = new HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS();
header.HeaderId = HttpApi.HTTP_RESPONSE_HEADER_ID.Enum.HttpHeaderWwwAuthenticate;
header.Flags = HttpApi.HTTP_RESPONSE_INFO_FLAGS.PreserveOrder; // The docs say this is for www-auth only.
header.HeaderId = HttpApiTypes.HTTP_RESPONSE_HEADER_ID.Enum.HttpHeaderWwwAuthenticate;
header.Flags = HttpApiTypes.HTTP_RESPONSE_INFO_FLAGS.PreserveOrder; // The docs say this is for www-auth only.
HttpApi.HTTP_KNOWN_HEADER[] nativeHeaderValues = new HttpApi.HTTP_KNOWN_HEADER[authChallenges.Count];
HttpApiTypes.HTTP_KNOWN_HEADER[] nativeHeaderValues = new HttpApiTypes.HTTP_KNOWN_HEADER[authChallenges.Count];
gcHandle = GCHandle.Alloc(nativeHeaderValues, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
header.KnownHeaders = (HttpApi.HTTP_KNOWN_HEADER*)gcHandle.AddrOfPinnedObject();
header.KnownHeaders = (HttpApiTypes.HTTP_KNOWN_HEADER*)gcHandle.AddrOfPinnedObject();
for (int headerValueIndex = 0; headerValueIndex < authChallenges.Count; headerValueIndex++)
{
@ -359,14 +360,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys
nativeHeaderValues[header.KnownHeaderCount].RawValueLength = (ushort)bytes.Length;
gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
nativeHeaderValues[header.KnownHeaderCount].pRawValue = (sbyte*)gcHandle.AddrOfPinnedObject();
nativeHeaderValues[header.KnownHeaderCount].pRawValue = (byte*)gcHandle.AddrOfPinnedObject();
header.KnownHeaderCount++;
}
// This type is a struct, not an object, so pinning it causes a boxed copy to be created. We can't do that until after all the fields are set.
gcHandle = GCHandle.Alloc(header, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
knownHeaderInfo[0].pInfo = (HttpApi.HTTP_MULTIPLE_KNOWN_HEADERS*)gcHandle.AddrOfPinnedObject();
knownHeaderInfo[0].pInfo = (HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS*)gcHandle.AddrOfPinnedObject();
httpResponse.ResponseInfoCount = 1;
}
@ -378,13 +379,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys
byte[] byteReason = HeaderEncoding.GetBytes(statusDescription);
fixed (byte* pReason = byteReason)
{
httpResponse.Response_V1.pReason = (sbyte*)pReason;
httpResponse.Response_V1.pReason = (byte*)pReason;
httpResponse.Response_V1.ReasonLength = (ushort)byteReason.Length;
byte[] byteContentLength = new byte[] { (byte)'0' };
fixed (byte* pContentLength = byteContentLength)
{
(&httpResponse.Response_V1.Headers.KnownHeaders)[(int)HttpSysResponseHeader.ContentLength].pRawValue = (sbyte*)pContentLength;
(&httpResponse.Response_V1.Headers.KnownHeaders)[(int)HttpSysResponseHeader.ContentLength].pRawValue = (byte*)pContentLength;
(&httpResponse.Response_V1.Headers.KnownHeaders)[(int)HttpSysResponseHeader.ContentLength].RawValueLength = (ushort)byteContentLength.Length;
httpResponse.Response_V1.Headers.UnknownHeaderCount = 0;

Просмотреть файл

@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.HttpSys.Internal;
namespace Microsoft.AspNetCore.Server.HttpSys
{

Просмотреть файл

@ -9,6 +9,10 @@
<PackageTags>aspnetcore;weblistener;httpsys</PackageTags>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\shared\Microsoft.AspNetCore.HttpSys.Sources\**\*.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Core" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" />

Просмотреть файл

@ -1,168 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Server.HttpSys
{
/// <devdoc>
/// <para>
/// Specifies the address families.
/// </para>
/// </devdoc>
internal enum AddressFamily
{
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Unknown = -1, // Unknown
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Unspecified = 0, // unspecified
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Unix = 1, // local to host (pipes, portals)
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
InterNetwork = 2, // internetwork: UDP, TCP, etc.
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
ImpLink = 3, // arpanet imp addresses
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Pup = 4, // pup protocols: e.g. BSP
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Chaos = 5, // mit CHAOS protocols
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
NS = 6, // XEROX NS protocols
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Ipx = NS, // IPX and SPX
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Iso = 7, // ISO protocols
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Osi = Iso, // OSI is ISO
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Ecma = 8, // european computer manufacturers
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
DataKit = 9, // datakit protocols
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Ccitt = 10, // CCITT protocols, X.25 etc
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Sna = 11, // IBM SNA
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
DecNet = 12, // DECnet
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
DataLink = 13, // Direct data link interface
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Lat = 14, // LAT
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
HyperChannel = 15, // NSC Hyperchannel
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
AppleTalk = 16, // AppleTalk
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
NetBios = 17, // NetBios-style addresses
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
VoiceView = 18, // VoiceView
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
FireFox = 19, // FireFox
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Banyan = 21, // Banyan
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Atm = 22, // Native ATM Services
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
InterNetworkV6 = 23, // Internetwork Version 6
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Cluster = 24, // Microsoft Wolfpack
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Ieee12844 = 25, // IEEE 1284.4 WG AF
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Irda = 26, // IrDA
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
NetworkDesigners = 28, // Network Designers OSI & gateway enabled protocols
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
Max = 29, // Max
}; // enum AddressFamily
}

Просмотреть файл

@ -6,6 +6,7 @@ using System.Collections.Concurrent;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.HttpSys

Просмотреть файл

@ -2,9 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Primitives;
using Microsoft.AspNetCore.HttpSys.Internal;
using static Microsoft.AspNetCore.HttpSys.Internal.HttpApiTypes;
namespace Microsoft.AspNetCore.Server.HttpSys
{
@ -70,688 +70,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys
[DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
internal static extern unsafe uint HttpCloseRequestQueue(IntPtr pReqQueueHandle);
internal enum HTTP_API_VERSION
{
Invalid,
Version10,
Version20,
}
// see http.w for definitions
internal enum HTTP_SERVER_PROPERTY
{
HttpServerAuthenticationProperty,
HttpServerLoggingProperty,
HttpServerQosProperty,
HttpServerTimeoutsProperty,
HttpServerQueueLengthProperty,
HttpServerStateProperty,
HttpServer503VerbosityProperty,
HttpServerBindingProperty,
HttpServerExtendedAuthenticationProperty,
HttpServerListenEndpointProperty,
HttpServerChannelBindProperty,
HttpServerProtectionLevelProperty,
}
// Currently only one request info type is supported but the enum is for future extensibility.
internal enum HTTP_REQUEST_INFO_TYPE
{
HttpRequestInfoTypeAuth,
HttpRequestInfoTypeChannelBind,
HttpRequestInfoTypeSslProtocol,
HttpRequestInfoTypeSslTokenBinding
}
internal enum HTTP_RESPONSE_INFO_TYPE
{
HttpResponseInfoTypeMultipleKnownHeaders,
HttpResponseInfoTypeAuthenticationProperty,
HttpResponseInfoTypeQosProperty,
}
internal enum HTTP_TIMEOUT_TYPE
{
EntityBody,
DrainEntityBody,
RequestQueue,
IdleConnection,
HeaderWait,
MinSendRate,
}
internal const int MaxTimeout = 6;
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_VERSION
{
internal ushort MajorVersion;
internal ushort MinorVersion;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_KNOWN_HEADER
{
internal ushort RawValueLength;
internal sbyte* pRawValue;
}
[StructLayout(LayoutKind.Explicit)]
internal struct HTTP_DATA_CHUNK
{
[FieldOffset(0)]
internal HTTP_DATA_CHUNK_TYPE DataChunkType;
[FieldOffset(8)]
internal FromMemory fromMemory;
[FieldOffset(8)]
internal FromFileHandle fromFile;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FromMemory
{
// 4 bytes for 32bit, 8 bytes for 64bit
internal IntPtr pBuffer;
internal uint BufferLength;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FromFileHandle
{
internal ulong offset;
internal ulong count;
internal IntPtr fileHandle;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTPAPI_VERSION
{
internal ushort HttpApiMajorVersion;
internal ushort HttpApiMinorVersion;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_COOKED_URL
{
internal ushort FullUrlLength;
internal ushort HostLength;
internal ushort AbsPathLength;
internal ushort QueryStringLength;
internal ushort* pFullUrl;
internal ushort* pHost;
internal ushort* pAbsPath;
internal ushort* pQueryString;
}
// Only cache unauthorized GETs + HEADs.
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_CACHE_POLICY
{
internal HTTP_CACHE_POLICY_TYPE Policy;
internal uint SecondsToLive;
}
internal enum HTTP_CACHE_POLICY_TYPE : int
{
HttpCachePolicyNocache = 0,
HttpCachePolicyUserInvalidates = 1,
HttpCachePolicyTimeToLive = 2,
}
[StructLayout(LayoutKind.Sequential)]
internal struct SOCKADDR
{
internal ushort sa_family;
internal byte sa_data;
internal byte sa_data_02;
internal byte sa_data_03;
internal byte sa_data_04;
internal byte sa_data_05;
internal byte sa_data_06;
internal byte sa_data_07;
internal byte sa_data_08;
internal byte sa_data_09;
internal byte sa_data_10;
internal byte sa_data_11;
internal byte sa_data_12;
internal byte sa_data_13;
internal byte sa_data_14;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_TRANSPORT_ADDRESS
{
internal SOCKADDR* pRemoteAddress;
internal SOCKADDR* pLocalAddress;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SSL_CLIENT_CERT_INFO
{
internal uint CertFlags;
internal uint CertEncodedSize;
internal byte* pCertEncoded;
internal void* Token;
internal byte CertDeniedByMapper;
}
internal enum HTTP_SERVICE_BINDING_TYPE : uint
{
HttpServiceBindingTypeNone = 0,
HttpServiceBindingTypeW,
HttpServiceBindingTypeA
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SERVICE_BINDING_BASE
{
internal HTTP_SERVICE_BINDING_TYPE Type;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_CHANNEL_BIND_STATUS
{
internal IntPtr ServiceName;
internal IntPtr ChannelToken;
internal uint ChannelTokenSize;
internal uint Flags;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_UNKNOWN_HEADER
{
internal ushort NameLength;
internal ushort RawValueLength;
internal sbyte* pName;
internal sbyte* pRawValue;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SSL_INFO
{
internal ushort ServerCertKeySize;
internal ushort ConnectionKeySize;
internal uint ServerCertIssuerSize;
internal uint ServerCertSubjectSize;
internal sbyte* pServerCertIssuer;
internal sbyte* pServerCertSubject;
internal HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo;
internal uint SslClientCertNegotiated;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_RESPONSE_HEADERS
{
internal ushort UnknownHeaderCount;
internal HTTP_UNKNOWN_HEADER* pUnknownHeaders;
internal ushort TrailerCount;
internal HTTP_UNKNOWN_HEADER* pTrailers;
internal HTTP_KNOWN_HEADER KnownHeaders;
internal HTTP_KNOWN_HEADER KnownHeaders_02;
internal HTTP_KNOWN_HEADER KnownHeaders_03;
internal HTTP_KNOWN_HEADER KnownHeaders_04;
internal HTTP_KNOWN_HEADER KnownHeaders_05;
internal HTTP_KNOWN_HEADER KnownHeaders_06;
internal HTTP_KNOWN_HEADER KnownHeaders_07;
internal HTTP_KNOWN_HEADER KnownHeaders_08;
internal HTTP_KNOWN_HEADER KnownHeaders_09;
internal HTTP_KNOWN_HEADER KnownHeaders_10;
internal HTTP_KNOWN_HEADER KnownHeaders_11;
internal HTTP_KNOWN_HEADER KnownHeaders_12;
internal HTTP_KNOWN_HEADER KnownHeaders_13;
internal HTTP_KNOWN_HEADER KnownHeaders_14;
internal HTTP_KNOWN_HEADER KnownHeaders_15;
internal HTTP_KNOWN_HEADER KnownHeaders_16;
internal HTTP_KNOWN_HEADER KnownHeaders_17;
internal HTTP_KNOWN_HEADER KnownHeaders_18;
internal HTTP_KNOWN_HEADER KnownHeaders_19;
internal HTTP_KNOWN_HEADER KnownHeaders_20;
internal HTTP_KNOWN_HEADER KnownHeaders_21;
internal HTTP_KNOWN_HEADER KnownHeaders_22;
internal HTTP_KNOWN_HEADER KnownHeaders_23;
internal HTTP_KNOWN_HEADER KnownHeaders_24;
internal HTTP_KNOWN_HEADER KnownHeaders_25;
internal HTTP_KNOWN_HEADER KnownHeaders_26;
internal HTTP_KNOWN_HEADER KnownHeaders_27;
internal HTTP_KNOWN_HEADER KnownHeaders_28;
internal HTTP_KNOWN_HEADER KnownHeaders_29;
internal HTTP_KNOWN_HEADER KnownHeaders_30;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_HEADERS
{
internal ushort UnknownHeaderCount;
internal HTTP_UNKNOWN_HEADER* pUnknownHeaders;
internal ushort TrailerCount;
internal HTTP_UNKNOWN_HEADER* pTrailers;
internal HTTP_KNOWN_HEADER KnownHeaders;
internal HTTP_KNOWN_HEADER KnownHeaders_02;
internal HTTP_KNOWN_HEADER KnownHeaders_03;
internal HTTP_KNOWN_HEADER KnownHeaders_04;
internal HTTP_KNOWN_HEADER KnownHeaders_05;
internal HTTP_KNOWN_HEADER KnownHeaders_06;
internal HTTP_KNOWN_HEADER KnownHeaders_07;
internal HTTP_KNOWN_HEADER KnownHeaders_08;
internal HTTP_KNOWN_HEADER KnownHeaders_09;
internal HTTP_KNOWN_HEADER KnownHeaders_10;
internal HTTP_KNOWN_HEADER KnownHeaders_11;
internal HTTP_KNOWN_HEADER KnownHeaders_12;
internal HTTP_KNOWN_HEADER KnownHeaders_13;
internal HTTP_KNOWN_HEADER KnownHeaders_14;
internal HTTP_KNOWN_HEADER KnownHeaders_15;
internal HTTP_KNOWN_HEADER KnownHeaders_16;
internal HTTP_KNOWN_HEADER KnownHeaders_17;
internal HTTP_KNOWN_HEADER KnownHeaders_18;
internal HTTP_KNOWN_HEADER KnownHeaders_19;
internal HTTP_KNOWN_HEADER KnownHeaders_20;
internal HTTP_KNOWN_HEADER KnownHeaders_21;
internal HTTP_KNOWN_HEADER KnownHeaders_22;
internal HTTP_KNOWN_HEADER KnownHeaders_23;
internal HTTP_KNOWN_HEADER KnownHeaders_24;
internal HTTP_KNOWN_HEADER KnownHeaders_25;
internal HTTP_KNOWN_HEADER KnownHeaders_26;
internal HTTP_KNOWN_HEADER KnownHeaders_27;
internal HTTP_KNOWN_HEADER KnownHeaders_28;
internal HTTP_KNOWN_HEADER KnownHeaders_29;
internal HTTP_KNOWN_HEADER KnownHeaders_30;
internal HTTP_KNOWN_HEADER KnownHeaders_31;
internal HTTP_KNOWN_HEADER KnownHeaders_32;
internal HTTP_KNOWN_HEADER KnownHeaders_33;
internal HTTP_KNOWN_HEADER KnownHeaders_34;
internal HTTP_KNOWN_HEADER KnownHeaders_35;
internal HTTP_KNOWN_HEADER KnownHeaders_36;
internal HTTP_KNOWN_HEADER KnownHeaders_37;
internal HTTP_KNOWN_HEADER KnownHeaders_38;
internal HTTP_KNOWN_HEADER KnownHeaders_39;
internal HTTP_KNOWN_HEADER KnownHeaders_40;
internal HTTP_KNOWN_HEADER KnownHeaders_41;
}
internal enum HTTP_VERB : int
{
HttpVerbUnparsed = 0,
HttpVerbUnknown = 1,
HttpVerbInvalid = 2,
HttpVerbOPTIONS = 3,
HttpVerbGET = 4,
HttpVerbHEAD = 5,
HttpVerbPOST = 6,
HttpVerbPUT = 7,
HttpVerbDELETE = 8,
HttpVerbTRACE = 9,
HttpVerbCONNECT = 10,
HttpVerbTRACK = 11,
HttpVerbMOVE = 12,
HttpVerbCOPY = 13,
HttpVerbPROPFIND = 14,
HttpVerbPROPPATCH = 15,
HttpVerbMKCOL = 16,
HttpVerbLOCK = 17,
HttpVerbUNLOCK = 18,
HttpVerbSEARCH = 19,
HttpVerbMaximum = 20,
}
internal static readonly string[] HttpVerbs = new string[]
{
null,
"Unknown",
"Invalid",
"OPTIONS",
"GET",
"HEAD",
"POST",
"PUT",
"DELETE",
"TRACE",
"CONNECT",
"TRACK",
"MOVE",
"COPY",
"PROPFIND",
"PROPPATCH",
"MKCOL",
"LOCK",
"UNLOCK",
"SEARCH",
};
internal enum HTTP_DATA_CHUNK_TYPE : int
{
HttpDataChunkFromMemory = 0,
HttpDataChunkFromFileHandle = 1,
HttpDataChunkFromFragmentCache = 2,
HttpDataChunkMaximum = 3,
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_RESPONSE_INFO
{
internal HTTP_RESPONSE_INFO_TYPE Type;
internal uint Length;
internal HTTP_MULTIPLE_KNOWN_HEADERS* pInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_RESPONSE
{
internal uint Flags;
internal HTTP_VERSION Version;
internal ushort StatusCode;
internal ushort ReasonLength;
internal sbyte* pReason;
internal HTTP_RESPONSE_HEADERS Headers;
internal ushort EntityChunkCount;
internal HTTP_DATA_CHUNK* pEntityChunks;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_RESPONSE_V2
{
internal HTTP_RESPONSE Response_V1;
internal ushort ResponseInfoCount;
internal HTTP_RESPONSE_INFO* pResponseInfo;
}
internal enum HTTP_RESPONSE_INFO_FLAGS : uint
{
None = 0,
PreserveOrder = 1,
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_MULTIPLE_KNOWN_HEADERS
{
internal HTTP_RESPONSE_HEADER_ID.Enum HeaderId;
internal HTTP_RESPONSE_INFO_FLAGS Flags;
internal ushort KnownHeaderCount;
internal HTTP_KNOWN_HEADER* KnownHeaders;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_AUTH_INFO
{
internal HTTP_AUTH_STATUS AuthStatus;
internal uint SecStatus;
internal uint Flags;
internal HTTP_REQUEST_AUTH_TYPE AuthType;
internal IntPtr AccessToken;
internal uint ContextAttributes;
internal uint PackedContextLength;
internal uint PackedContextType;
internal IntPtr PackedContext;
internal uint MutualAuthDataLength;
internal char* pMutualAuthData;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_INFO
{
internal HTTP_REQUEST_INFO_TYPE InfoType;
internal uint InfoLength;
internal HTTP_REQUEST_AUTH_INFO* pInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST
{
internal uint Flags;
internal ulong ConnectionId;
internal ulong RequestId;
internal ulong UrlContext;
internal HTTP_VERSION Version;
internal HTTP_VERB Verb;
internal ushort UnknownVerbLength;
internal ushort RawUrlLength;
internal sbyte* pUnknownVerb;
internal sbyte* pRawUrl;
internal HTTP_COOKED_URL CookedUrl;
internal HTTP_TRANSPORT_ADDRESS Address;
internal HTTP_REQUEST_HEADERS Headers;
internal ulong BytesReceived;
internal ushort EntityChunkCount;
internal HTTP_DATA_CHUNK* pEntityChunks;
internal ulong RawConnectionId;
internal HTTP_SSL_INFO* pSslInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_V2
{
internal HTTP_REQUEST Request;
internal ushort RequestInfoCount;
internal HTTP_REQUEST_INFO* pRequestInfo;
}
internal enum HTTP_AUTH_STATUS
{
HttpAuthStatusSuccess,
HttpAuthStatusNotAuthenticated,
HttpAuthStatusFailure,
}
internal enum HTTP_REQUEST_AUTH_TYPE
{
HttpRequestAuthTypeNone = 0,
HttpRequestAuthTypeBasic,
HttpRequestAuthTypeDigest,
HttpRequestAuthTypeNTLM,
HttpRequestAuthTypeNegotiate,
HttpRequestAuthTypeKerberos
}
internal enum HTTP_QOS_SETTING_TYPE
{
HttpQosSettingTypeBandwidth,
HttpQosSettingTypeConnectionLimit,
HttpQosSettingTypeFlowRate
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SERVER_AUTHENTICATION_INFO
{
internal HTTP_FLAGS Flags;
internal HTTP_AUTH_TYPES AuthSchemes;
internal bool ReceiveMutualAuth;
internal bool ReceiveContextHandle;
internal bool DisableNTLMCredentialCaching;
internal ulong ExFlags;
HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS DigestParams;
HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS BasicParams;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS
{
internal ushort DomainNameLength;
internal char* DomainName;
internal ushort RealmLength;
internal char* Realm;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS
{
ushort RealmLength;
char* Realm;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_REQUEST_TOKEN_BINDING_INFO
{
public byte* TokenBinding;
public uint TokenBindingSize;
public byte* TlsUnique;
public uint TlsUniqueSize;
public char* KeyType;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_TIMEOUT_LIMIT_INFO
{
internal HTTP_FLAGS Flags;
internal ushort EntityBody;
internal ushort DrainEntityBody;
internal ushort RequestQueue;
internal ushort IdleConnection;
internal ushort HeaderWait;
internal uint MinSendRate;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_BINDING_INFO
{
internal HTTP_FLAGS Flags;
internal IntPtr RequestQueueHandle;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_CONNECTION_LIMIT_INFO
{
internal HTTP_FLAGS Flags;
internal uint MaxConnections;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HTTP_QOS_SETTING_INFO
{
internal HTTP_QOS_SETTING_TYPE QosType;
internal IntPtr QosSetting;
}
// see http.w for definitions
[Flags]
internal enum HTTP_FLAGS : uint
{
NONE = 0x00000000,
HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY = 0x00000001,
HTTP_RECEIVE_SECURE_CHANNEL_TOKEN = 0x00000001,
HTTP_SEND_RESPONSE_FLAG_DISCONNECT = 0x00000001,
HTTP_SEND_RESPONSE_FLAG_MORE_DATA = 0x00000002,
HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA = 0x00000004,
HTTP_SEND_RESPONSE_FLAG_RAW_HEADER = 0x00000004,
HTTP_SEND_REQUEST_FLAG_MORE_DATA = 0x00000001,
HTTP_PROPERTY_FLAG_PRESENT = 0x00000001,
HTTP_INITIALIZE_SERVER = 0x00000001,
HTTP_INITIALIZE_CBT = 0x00000004,
HTTP_SEND_RESPONSE_FLAG_OPAQUE = 0x00000040,
}
[Flags]
internal enum HTTP_AUTH_TYPES : uint
{
NONE = 0x00000000,
HTTP_AUTH_ENABLE_BASIC = 0x00000001,
HTTP_AUTH_ENABLE_DIGEST = 0x00000002,
HTTP_AUTH_ENABLE_NTLM = 0x00000004,
HTTP_AUTH_ENABLE_NEGOTIATE = 0x00000008,
HTTP_AUTH_ENABLE_KERBEROS = 0x00000010,
}
internal static class HTTP_RESPONSE_HEADER_ID
{
private static string[] _strings =
{
"Cache-Control",
"Connection",
"Date",
"Keep-Alive",
"Pragma",
"Trailer",
"Transfer-Encoding",
"Upgrade",
"Via",
"Warning",
"Allow",
"Content-Length",
"Content-Type",
"Content-Encoding",
"Content-Language",
"Content-Location",
"Content-MD5",
"Content-Range",
"Expires",
"Last-Modified",
"Accept-Ranges",
"Age",
"ETag",
"Location",
"Proxy-Authenticate",
"Retry-After",
"Server",
"Set-Cookie",
"Vary",
"WWW-Authenticate",
};
private static Dictionary<string, int> _lookupTable = CreateLookupTable();
private static Dictionary<string, int> CreateLookupTable()
{
Dictionary<string, int> lookupTable = new Dictionary<string, int>((int)Enum.HttpHeaderResponseMaximum, StringComparer.OrdinalIgnoreCase);
for (int i = 0; i < (int)Enum.HttpHeaderResponseMaximum; i++)
{
lookupTable.Add(_strings[i], i);
}
return lookupTable;
}
internal static int IndexOfKnownHeader(string HeaderName)
{
int index;
return _lookupTable.TryGetValue(HeaderName, out index) ? index : -1;
}
internal enum Enum
{
HttpHeaderCacheControl = 0, // general-header [section 4.5]
HttpHeaderConnection = 1, // general-header [section 4.5]
HttpHeaderDate = 2, // general-header [section 4.5]
HttpHeaderKeepAlive = 3, // general-header [not in rfc]
HttpHeaderPragma = 4, // general-header [section 4.5]
HttpHeaderTrailer = 5, // general-header [section 4.5]
HttpHeaderTransferEncoding = 6, // general-header [section 4.5]
HttpHeaderUpgrade = 7, // general-header [section 4.5]
HttpHeaderVia = 8, // general-header [section 4.5]
HttpHeaderWarning = 9, // general-header [section 4.5]
HttpHeaderAllow = 10, // entity-header [section 7.1]
HttpHeaderContentLength = 11, // entity-header [section 7.1]
HttpHeaderContentType = 12, // entity-header [section 7.1]
HttpHeaderContentEncoding = 13, // entity-header [section 7.1]
HttpHeaderContentLanguage = 14, // entity-header [section 7.1]
HttpHeaderContentLocation = 15, // entity-header [section 7.1]
HttpHeaderContentMd5 = 16, // entity-header [section 7.1]
HttpHeaderContentRange = 17, // entity-header [section 7.1]
HttpHeaderExpires = 18, // entity-header [section 7.1]
HttpHeaderLastModified = 19, // entity-header [section 7.1]
// Response Headers
HttpHeaderAcceptRanges = 20, // response-header [section 6.2]
HttpHeaderAge = 21, // response-header [section 6.2]
HttpHeaderEtag = 22, // response-header [section 6.2]
HttpHeaderLocation = 23, // response-header [section 6.2]
HttpHeaderProxyAuthenticate = 24, // response-header [section 6.2]
HttpHeaderRetryAfter = 25, // response-header [section 6.2]
HttpHeaderServer = 26, // response-header [section 6.2]
HttpHeaderSetCookie = 27, // response-header [not in rfc]
HttpHeaderVary = 28, // response-header [section 6.2]
HttpHeaderWwwAuthenticate = 29, // response-header [section 6.2]
HttpHeaderResponseMaximum = 30,
HttpHeaderMaximum = 41
}
}
private static HTTPAPI_VERSION version;

Просмотреть файл

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Win32.SafeHandles;
namespace Microsoft.AspNetCore.Server.HttpSys

Просмотреть файл

@ -3,6 +3,7 @@
using System;
using System.Threading;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Win32.SafeHandles;
namespace Microsoft.AspNetCore.Server.HttpSys
@ -17,7 +18,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
serverSessionId = id;
// This class uses no real handle so we need to set a dummy handle. Otherwise, IsInvalid always remains
// This class uses no real handle so we need to set a dummy handle. Otherwise, IsInvalid always remains
// true.
SetHandle(new IntPtr(1));

Просмотреть файл

@ -4,6 +4,7 @@
using System;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.HttpSys
@ -11,7 +12,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
internal class RequestQueue
{
private static readonly int BindingInfoSize =
Marshal.SizeOf<HttpApi.HTTP_BINDING_INFO>();
Marshal.SizeOf<HttpApiTypes.HTTP_BINDING_INFO>();
private readonly UrlGroup _urlGroup;
private readonly ILogger _logger;
@ -54,13 +55,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// Set the association between request queue and url group. After this, requests for registered urls will
// get delivered to this request queue.
var info = new HttpApi.HTTP_BINDING_INFO();
info.Flags = HttpApi.HTTP_FLAGS.HTTP_PROPERTY_FLAG_PRESENT;
var info = new HttpApiTypes.HTTP_BINDING_INFO();
info.Flags = HttpApiTypes.HTTP_FLAGS.HTTP_PROPERTY_FLAG_PRESENT;
info.RequestQueueHandle = Handle.DangerousGetHandle();
var infoptr = new IntPtr(&info);
_urlGroup.SetProperty(HttpApi.HTTP_SERVER_PROPERTY.HttpServerBindingProperty,
_urlGroup.SetProperty(HttpApiTypes.HTTP_SERVER_PROPERTY.HttpServerBindingProperty,
infoptr, (uint)BindingInfoSize);
}
@ -73,13 +74,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// is fine since http.sys allows to set HttpServerBindingProperty multiple times for valid
// Url groups.
var info = new HttpApi.HTTP_BINDING_INFO();
info.Flags = HttpApi.HTTP_FLAGS.NONE;
var info = new HttpApiTypes.HTTP_BINDING_INFO();
info.Flags = HttpApiTypes.HTTP_FLAGS.NONE;
info.RequestQueueHandle = IntPtr.Zero;
var infoptr = new IntPtr(&info);
_urlGroup.SetProperty(HttpApi.HTTP_SERVER_PROPERTY.HttpServerBindingProperty,
_urlGroup.SetProperty(HttpApiTypes.HTTP_SERVER_PROPERTY.HttpServerBindingProperty,
infoptr, (uint)BindingInfoSize, throwOnError: false);
}
@ -89,7 +90,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
CheckDisposed();
var result = HttpApi.HttpSetRequestQueueProperty(Handle,
HttpApi.HTTP_SERVER_PROPERTY.HttpServerQueueLengthProperty,
HttpApiTypes.HTTP_SERVER_PROPERTY.HttpServerQueueLengthProperty,
new IntPtr((void*)&length), (uint)Marshal.SizeOf<long>(), 0, IntPtr.Zero);
if (result != 0)

Просмотреть файл

@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
using Microsoft.AspNetCore.HttpSys.Internal;
namespace Microsoft.AspNetCore.Server.HttpSys
{

Просмотреть файл

@ -3,8 +3,9 @@
using System;
using System.Runtime.InteropServices;
using static Microsoft.AspNetCore.Server.HttpSys.HttpApi;
using static Microsoft.AspNetCore.Server.HttpSys.UnsafeNclNativeMethods.TokenBinding;
using Microsoft.AspNetCore.HttpSys.Internal;
using static Microsoft.AspNetCore.HttpSys.Internal.HttpApiTypes;
using static Microsoft.AspNetCore.HttpSys.Internal.UnsafeNclNativeMethods.TokenBinding;
namespace Microsoft.AspNetCore.Server.HttpSys
{

Просмотреть файл

@ -4,6 +4,7 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.HttpSys
@ -11,7 +12,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
internal class UrlGroup : IDisposable
{
private static readonly int QosInfoSize =
Marshal.SizeOf<HttpApi.HTTP_QOS_SETTING_INFO>();
Marshal.SizeOf<HttpApiTypes.HTTP_QOS_SETTING_INFO>();
private ServerSession _serverSession;
private ILogger _logger;
@ -39,18 +40,18 @@ namespace Microsoft.AspNetCore.Server.HttpSys
internal unsafe void SetMaxConnections(long maxConnections)
{
var connectionLimit = new HttpApi.HTTP_CONNECTION_LIMIT_INFO();
connectionLimit.Flags = HttpApi.HTTP_FLAGS.HTTP_PROPERTY_FLAG_PRESENT;
var connectionLimit = new HttpApiTypes.HTTP_CONNECTION_LIMIT_INFO();
connectionLimit.Flags = HttpApiTypes.HTTP_FLAGS.HTTP_PROPERTY_FLAG_PRESENT;
connectionLimit.MaxConnections = (uint)maxConnections;
var qosSettings = new HttpApi.HTTP_QOS_SETTING_INFO();
qosSettings.QosType = HttpApi.HTTP_QOS_SETTING_TYPE.HttpQosSettingTypeConnectionLimit;
var qosSettings = new HttpApiTypes.HTTP_QOS_SETTING_INFO();
qosSettings.QosType = HttpApiTypes.HTTP_QOS_SETTING_TYPE.HttpQosSettingTypeConnectionLimit;
qosSettings.QosSetting = new IntPtr(&connectionLimit);
SetProperty(HttpApi.HTTP_SERVER_PROPERTY.HttpServerQosProperty, new IntPtr(&qosSettings), (uint)QosInfoSize);
SetProperty(HttpApiTypes.HTTP_SERVER_PROPERTY.HttpServerQosProperty, new IntPtr(&qosSettings), (uint)QosInfoSize);
}
internal void SetProperty(HttpApi.HTTP_SERVER_PROPERTY property, IntPtr info, uint infosize, bool throwOnError = true)
internal void SetProperty(HttpApiTypes.HTTP_SERVER_PROPERTY property, IntPtr info, uint infosize, bool throwOnError = true)
{
Debug.Assert(info != IntPtr.Zero, "SetUrlGroupProperty called with invalid pointer");
CheckDisposed();

Просмотреть файл

@ -12,6 +12,7 @@ using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.HttpSys
@ -23,11 +24,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private const uint CertBoblSize = 1500;
private static readonly IOCompletionCallback IOCallback = new IOCompletionCallback(WaitCallback);
private static readonly int RequestChannelBindStatusSize =
Marshal.SizeOf<HttpApi.HTTP_REQUEST_CHANNEL_BIND_STATUS>();
Marshal.SizeOf<HttpApiTypes.HTTP_REQUEST_CHANNEL_BIND_STATUS>();
private SafeNativeOverlapped _overlapped;
private byte[] _backingBuffer;
private HttpApi.HTTP_SSL_CLIENT_CERT_INFO* _memoryBlob;
private HttpApiTypes.HTTP_SSL_CLIENT_CERT_INFO* _memoryBlob;
private uint _size;
private TaskCompletionSource<object> _tcs;
private RequestContext _requestContext;
@ -104,7 +105,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
private HttpApi.HTTP_SSL_CLIENT_CERT_INFO* RequestBlob
private HttpApiTypes.HTTP_SSL_CLIENT_CERT_INFO* RequestBlob
{
get
{
@ -134,7 +135,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
var boundHandle = RequestContext.Server.RequestQueue.BoundHandle;
_overlapped = new SafeNativeOverlapped(boundHandle,
boundHandle.AllocateNativeOverlapped(IOCallback, this, _backingBuffer));
_memoryBlob = (HttpApi.HTTP_SSL_CLIENT_CERT_INFO*)Marshal.UnsafeAddrOfPinnedArrayElement(_backingBuffer, 0);
_memoryBlob = (HttpApiTypes.HTTP_SSL_CLIENT_CERT_INFO*)Marshal.UnsafeAddrOfPinnedArrayElement(_backingBuffer, 0);
}
// When you use netsh to configure HTTP.SYS with clientcertnegotiation = enable
@ -168,7 +169,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
HttpApi.HttpReceiveClientCertificate(
RequestQueueHandle,
RequestContext.Request.UConnectionId,
(uint)HttpApi.HTTP_FLAGS.NONE,
(uint)HttpApiTypes.HTTP_FLAGS.NONE,
RequestBlob,
size,
&bytesReceived,
@ -176,7 +177,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA)
{
HttpApi.HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo = RequestBlob;
HttpApiTypes.HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo = RequestBlob;
size = bytesReceived + pClientCertInfo->CertEncodedSize;
Reset(size);
retry = true;
@ -239,7 +240,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// return the size of the initial cert structure. To get the full size,
// we need to add the certificate encoding size as well.
HttpApi.HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo = asyncResult.RequestBlob;
HttpApiTypes.HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo = asyncResult.RequestBlob;
asyncResult.Reset(numBytes + pClientCertInfo->CertEncodedSize);
uint bytesReceived = 0;
@ -247,7 +248,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
HttpApi.HttpReceiveClientCertificate(
requestContext.Server.RequestQueue.Handle,
requestContext.Request.UConnectionId,
(uint)HttpApi.HTTP_FLAGS.NONE,
(uint)HttpApiTypes.HTTP_FLAGS.NONE,
asyncResult._memoryBlob,
asyncResult._size,
&bytesReceived,
@ -271,7 +272,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
else
{
HttpApi.HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo = asyncResult._memoryBlob;
HttpApiTypes.HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo = asyncResult._memoryBlob;
if (pClientCertInfo == null)
{
asyncResult.Complete(0, null);
@ -374,7 +375,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
statusCode = HttpApi.HttpReceiveClientCertificate(
requestQueue.Handle,
connectionId,
(uint)HttpApi.HTTP_FLAGS.HTTP_RECEIVE_SECURE_CHANNEL_TOKEN,
(uint)HttpApiTypes.HTTP_FLAGS.HTTP_RECEIVE_SECURE_CHANNEL_TOKEN,
blobPtr,
(uint)size,
&bytesReceived,
@ -418,7 +419,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private static int GetTokenOffsetFromBlob(IntPtr blob)
{
Debug.Assert(blob != IntPtr.Zero);
IntPtr tokenPointer = Marshal.ReadIntPtr(blob, (int)Marshal.OffsetOf<HttpApi.HTTP_REQUEST_CHANNEL_BIND_STATUS>("ChannelToken"));
IntPtr tokenPointer = Marshal.ReadIntPtr(blob, (int)Marshal.OffsetOf<HttpApiTypes.HTTP_REQUEST_CHANNEL_BIND_STATUS>("ChannelToken"));
Debug.Assert(tokenPointer != IntPtr.Zero);
return (int)IntPtrHelper.Subtract(tokenPointer, blob);
}
@ -426,7 +427,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private static int GetTokenSizeFromBlob(IntPtr blob)
{
Debug.Assert(blob != IntPtr.Zero);
return Marshal.ReadInt32(blob, (int)Marshal.OffsetOf<HttpApi.HTTP_REQUEST_CHANNEL_BIND_STATUS>("ChannelTokenSize"));
return Marshal.ReadInt32(blob, (int)Marshal.OffsetOf<HttpApiTypes.HTTP_REQUEST_CHANNEL_BIND_STATUS>("ChannelTokenSize"));
}
}
}

Просмотреть файл

@ -1,434 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Claims;
using System.Security.Principal;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Server.HttpSys
{
internal unsafe class NativeRequestContext : IDisposable
{
private const int DefaultBufferSize = 4096;
private const int AlignmentPadding = 8;
private HttpApi.HTTP_REQUEST* _nativeRequest;
private IntPtr _originalBufferAddress;
private byte[] _backingBuffer;
private int _bufferAlignment;
private SafeNativeOverlapped _nativeOverlapped;
private AsyncAcceptContext _acceptResult;
internal NativeRequestContext(AsyncAcceptContext result)
{
_acceptResult = result;
AllocateNativeRequest();
}
internal SafeNativeOverlapped NativeOverlapped => _nativeOverlapped;
internal HttpApi.HTTP_REQUEST* NativeRequest
{
get
{
Debug.Assert(_nativeRequest != null || _backingBuffer == null, "native request accessed after ReleasePins().");
return _nativeRequest;
}
}
private HttpApi.HTTP_REQUEST_V2* NativeRequestV2
{
get
{
Debug.Assert(_nativeRequest != null || _backingBuffer == null, "native request accessed after ReleasePins().");
return (HttpApi.HTTP_REQUEST_V2*)_nativeRequest;
}
}
internal ulong RequestId
{
get { return NativeRequest->RequestId; }
set { NativeRequest->RequestId = value; }
}
internal ulong ConnectionId => NativeRequest->ConnectionId;
internal HttpApi.HTTP_VERB VerbId => NativeRequest->Verb;
internal ulong UrlContext => NativeRequest->UrlContext;
internal ushort UnknownHeaderCount => NativeRequest->Headers.UnknownHeaderCount;
internal SslStatus SslStatus
{
get
{
return NativeRequest->pSslInfo == null ? SslStatus.Insecure :
NativeRequest->pSslInfo->SslClientCertNegotiated == 0 ? SslStatus.NoClientCert :
SslStatus.ClientCert;
}
}
internal uint Size
{
get { return (uint)_backingBuffer.Length - AlignmentPadding; }
}
// ReleasePins() should be called exactly once. It must be called before Dispose() is called, which means it must be called
// before an object (Request) which closes the RequestContext on demand is returned to the application.
internal void ReleasePins()
{
Debug.Assert(_nativeRequest != null || _backingBuffer == null, "RequestContextBase::ReleasePins()|ReleasePins() called twice.");
_originalBufferAddress = (IntPtr)_nativeRequest;
_nativeRequest = null;
_nativeOverlapped?.Dispose();
_nativeOverlapped = null;
}
public void Dispose()
{
Debug.Assert(_nativeRequest == null, "RequestContextBase::Dispose()|Dispose() called before ReleasePins().");
_nativeOverlapped?.Dispose();
}
private void SetBuffer(int size)
{
Debug.Assert(size != 0, "unexpected size");
_backingBuffer = new byte[size + AlignmentPadding];
}
private void AllocateNativeRequest(uint? size = null)
{
// We can't reuse overlapped objects
_nativeOverlapped?.Dispose();
uint newSize = size.HasValue ? size.Value : _backingBuffer == null ? DefaultBufferSize : Size;
SetBuffer(checked((int)newSize));
var boundHandle = _acceptResult.Server.RequestQueue.BoundHandle;
_nativeOverlapped = new SafeNativeOverlapped(boundHandle,
boundHandle.AllocateNativeOverlapped(AsyncAcceptContext.IOCallback, _acceptResult, _backingBuffer));
var requestAddress = Marshal.UnsafeAddrOfPinnedArrayElement(_backingBuffer, 0);
// TODO:
// Apparently the HttpReceiveHttpRequest memory alignment requirements for non - ARM processors
// are different than for ARM processors. We have seen 4 - byte - aligned buffers allocated on
// virtual x64/x86 machines which were accepted by HttpReceiveHttpRequest without errors. In
// these cases the buffer alignment may cause reading values at invalid offset. Setting buffer
// alignment to 0 for now.
//
// _bufferAlignment = (int)(requestAddress.ToInt64() & 0x07);
_bufferAlignment = 0;
_nativeRequest = (HttpApi.HTTP_REQUEST*)(requestAddress + _bufferAlignment);
}
internal void Reset(ulong requestId = 0, uint? size = null)
{
Debug.Assert(_nativeRequest != null || _backingBuffer == null, "RequestContextBase::Dispose()|SetNativeRequest() called after ReleasePins().");
AllocateNativeRequest(size);
RequestId = requestId;
}
// These methods require the HTTP_REQUEST to still be pinned in its original location.
internal string GetVerb()
{
var verb = NativeRequest->Verb;
if (verb > HttpApi.HTTP_VERB.HttpVerbUnknown && verb < HttpApi.HTTP_VERB.HttpVerbMaximum)
{
return HttpApi.HttpVerbs[(int)verb];
}
else if (verb == HttpApi.HTTP_VERB.HttpVerbUnknown && NativeRequest->pUnknownVerb != null)
{
return HeaderEncoding.GetString(NativeRequest->pUnknownVerb, NativeRequest->UnknownVerbLength);
}
return null;
}
internal string GetRawUrl()
{
if (NativeRequest->pRawUrl != null && NativeRequest->RawUrlLength > 0)
{
return Marshal.PtrToStringAnsi((IntPtr)NativeRequest->pRawUrl, NativeRequest->RawUrlLength);
}
return null;
}
internal byte[] GetRawUrlInBytes()
{
if (NativeRequest->pRawUrl != null && NativeRequest->RawUrlLength > 0)
{
var result = new byte[NativeRequest->RawUrlLength];
Marshal.Copy((IntPtr)NativeRequest->pRawUrl, result, 0, NativeRequest->RawUrlLength);
return result;
}
return null;
}
internal CookedUrl GetCookedUrl()
{
return new CookedUrl(NativeRequest->CookedUrl);
}
internal Version GetVersion()
{
var major = NativeRequest->Version.MajorVersion;
var minor = NativeRequest->Version.MinorVersion;
if (major == 1 && minor == 1)
{
return Constants.V1_1;
}
else if (major == 1 && minor == 0)
{
return Constants.V1_0;
}
return new Version(major, minor);
}
internal bool CheckAuthenticated()
{
var requestInfo = NativeRequestV2->pRequestInfo;
var infoCount = NativeRequestV2->RequestInfoCount;
for (int i = 0; i < infoCount; i++)
{
var info = &requestInfo[i];
if (info != null
&& info->InfoType == HttpApi.HTTP_REQUEST_INFO_TYPE.HttpRequestInfoTypeAuth
&& info->pInfo->AuthStatus == HttpApi.HTTP_AUTH_STATUS.HttpAuthStatusSuccess)
{
return true;
}
}
return false;
}
internal WindowsPrincipal GetUser()
{
var requestInfo = NativeRequestV2->pRequestInfo;
var infoCount = NativeRequestV2->RequestInfoCount;
for (int i = 0; i < infoCount; i++)
{
var info = &requestInfo[i];
if (info != null
&& info->InfoType == HttpApi.HTTP_REQUEST_INFO_TYPE.HttpRequestInfoTypeAuth
&& info->pInfo->AuthStatus == HttpApi.HTTP_AUTH_STATUS.HttpAuthStatusSuccess)
{
// Duplicates AccessToken
var identity = new WindowsIdentity(info->pInfo->AccessToken,
GetAuthTypeFromRequest(info->pInfo->AuthType).ToString());
// Close the original
UnsafeNclNativeMethods.SafeNetHandles.CloseHandle(info->pInfo->AccessToken);
return new WindowsPrincipal(identity);
}
}
return new WindowsPrincipal(WindowsIdentity.GetAnonymous()); // Anonymous / !IsAuthenticated
}
private static AuthenticationSchemes GetAuthTypeFromRequest(HttpApi.HTTP_REQUEST_AUTH_TYPE input)
{
switch (input)
{
case HttpApi.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeBasic:
return AuthenticationSchemes.Basic;
// case HttpApi.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeDigest:
// return AuthenticationSchemes.Digest;
case HttpApi.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeNTLM:
return AuthenticationSchemes.NTLM;
case HttpApi.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeNegotiate:
return AuthenticationSchemes.Negotiate;
case HttpApi.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeKerberos:
return AuthenticationSchemes.Kerberos;
default:
throw new NotImplementedException(input.ToString());
}
}
// These methods are for accessing the request structure after it has been unpinned. They need to adjust addresses
// in case GC has moved the original object.
internal string GetKnownHeader(HttpSysRequestHeader header)
{
fixed (byte* pMemoryBlob = _backingBuffer)
{
var request = (HttpApi.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment);
long fixup = pMemoryBlob - (byte*)_originalBufferAddress;
int headerIndex = (int)header;
string value = null;
HttpApi.HTTP_KNOWN_HEADER* pKnownHeader = (&request->Headers.KnownHeaders) + headerIndex;
// For known headers, when header value is empty, RawValueLength will be 0 and
// pRawValue will point to empty string ("\0")
if (pKnownHeader->pRawValue != null)
{
value = HeaderEncoding.GetString(pKnownHeader->pRawValue + fixup, pKnownHeader->RawValueLength);
}
return value;
}
}
internal void GetUnknownHeaders(IDictionary<string, StringValues> unknownHeaders)
{
// Return value.
fixed (byte* pMemoryBlob = _backingBuffer)
{
var request = (HttpApi.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment);
long fixup = pMemoryBlob - (byte*)_originalBufferAddress;
int index;
// unknown headers
if (request->Headers.UnknownHeaderCount != 0)
{
var pUnknownHeader = (HttpApi.HTTP_UNKNOWN_HEADER*)(fixup + (byte*)request->Headers.pUnknownHeaders);
for (index = 0; index < request->Headers.UnknownHeaderCount; index++)
{
// For unknown headers, when header value is empty, RawValueLength will be 0 and
// pRawValue will be null.
if (pUnknownHeader->pName != null && pUnknownHeader->NameLength > 0)
{
var headerName = HeaderEncoding.GetString(pUnknownHeader->pName + fixup, pUnknownHeader->NameLength);
string headerValue;
if (pUnknownHeader->pRawValue != null && pUnknownHeader->RawValueLength > 0)
{
headerValue = HeaderEncoding.GetString(pUnknownHeader->pRawValue + fixup, pUnknownHeader->RawValueLength);
}
else
{
headerValue = string.Empty;
}
// Note that Http.Sys currently collapses all headers of the same name to a single coma separated string,
// so we can just call Set.
unknownHeaders[headerName] = headerValue;
}
pUnknownHeader++;
}
}
}
}
internal SocketAddress GetRemoteEndPoint()
{
return GetEndPoint(localEndpoint: false);
}
internal SocketAddress GetLocalEndPoint()
{
return GetEndPoint(localEndpoint: true);
}
private SocketAddress GetEndPoint(bool localEndpoint)
{
fixed (byte* pMemoryBlob = _backingBuffer)
{
var request = (HttpApi.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment);
var source = localEndpoint ? (byte*)request->Address.pLocalAddress : (byte*)request->Address.pRemoteAddress;
if (source == null)
{
return null;
}
var address = (IntPtr)(pMemoryBlob + _bufferAlignment - (byte*)_originalBufferAddress + source);
return CopyOutAddress(address);
}
}
private static SocketAddress CopyOutAddress(IntPtr address)
{
ushort addressFamily = *((ushort*)address);
if (addressFamily == (ushort)AddressFamily.InterNetwork)
{
var v4address = new SocketAddress(AddressFamily.InterNetwork, SocketAddress.IPv4AddressSize);
fixed (byte* pBuffer = v4address.Buffer)
{
for (int index = 2; index < SocketAddress.IPv4AddressSize; index++)
{
pBuffer[index] = ((byte*)address)[index];
}
}
return v4address;
}
if (addressFamily == (ushort)AddressFamily.InterNetworkV6)
{
var v6address = new SocketAddress(AddressFamily.InterNetworkV6, SocketAddress.IPv6AddressSize);
fixed (byte* pBuffer = v6address.Buffer)
{
for (int index = 2; index < SocketAddress.IPv6AddressSize; index++)
{
pBuffer[index] = ((byte*)address)[index];
}
}
return v6address;
}
return null;
}
internal uint GetChunks(ref int dataChunkIndex, ref uint dataChunkOffset, byte[] buffer, int offset, int size)
{
// Return value.
uint dataRead = 0;
fixed (byte* pMemoryBlob = _backingBuffer)
{
var request = (HttpApi.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment);
long fixup = pMemoryBlob - (byte*)_originalBufferAddress;
if (request->EntityChunkCount > 0 && dataChunkIndex < request->EntityChunkCount && dataChunkIndex != -1)
{
var pDataChunk = (HttpApi.HTTP_DATA_CHUNK*)(fixup + (byte*)&request->pEntityChunks[dataChunkIndex]);
fixed (byte* pReadBuffer = buffer)
{
byte* pTo = &pReadBuffer[offset];
while (dataChunkIndex < request->EntityChunkCount && dataRead < size)
{
if (dataChunkOffset >= pDataChunk->fromMemory.BufferLength)
{
dataChunkOffset = 0;
dataChunkIndex++;
pDataChunk++;
}
else
{
byte* pFrom = (byte*)pDataChunk->fromMemory.pBuffer + dataChunkOffset + fixup;
uint bytesToRead = pDataChunk->fromMemory.BufferLength - (uint)dataChunkOffset;
if (bytesToRead > (uint)size)
{
bytesToRead = (uint)size;
}
for (uint i = 0; i < bytesToRead; i++)
{
*(pTo++) = *(pFrom++);
}
dataRead += bytesToRead;
dataChunkOffset += bytesToRead;
}
}
}
}
// we're finished.
if (dataChunkIndex == request->EntityChunkCount)
{
dataChunkIndex = -1;
}
}
return dataRead;
}
}
}

Просмотреть файл

@ -5,11 +5,11 @@ using System;
using System.Globalization;
using System.IO;
using System.Net;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.HttpSys.Internal;
namespace Microsoft.AspNetCore.Server.HttpSys
{
@ -27,8 +27,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private long? _contentLength;
private RequestStream _nativeStream;
private SocketAddress _localEndPoint;
private SocketAddress _remoteEndPoint;
private AspNetCore.HttpSys.Internal.SocketAddress _localEndPoint;
private AspNetCore.HttpSys.Internal.SocketAddress _remoteEndPoint;
private bool _isDisposed = false;
@ -57,7 +57,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
var originalPath = RequestUriBuilder.DecodeAndUnescapePath(rawUrlInBytes);
// 'OPTIONS * HTTP/1.1'
if (KnownMethod == HttpApi.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawUrl, "*", StringComparison.Ordinal))
if (KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawUrl, "*", StringComparison.Ordinal))
{
PathBase = string.Empty;
Path = string.Empty;
@ -79,9 +79,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
ProtocolVersion = _nativeRequestContext.GetVersion();
Headers = new HeaderCollection(new RequestHeaders(_nativeRequestContext));
Headers = new RequestHeaders(_nativeRequestContext);
User = nativeRequestContext.GetUser();
User = _nativeRequestContext.GetUser();
// GetTlsTokenBindingInfo(); TODO: https://github.com/aspnet/HttpSysServer/issues/231
@ -136,11 +136,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
public HeaderCollection Headers { get; }
public RequestHeaders Headers { get; }
internal HttpApi.HTTP_VERB KnownMethod { get; }
internal HttpApiTypes.HTTP_VERB KnownMethod { get; }
internal bool IsHeadMethod => KnownMethod == HttpApi.HTTP_VERB.HttpVerbHEAD;
internal bool IsHeadMethod => KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbHEAD;
public string Method { get; }
@ -190,7 +190,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
private SocketAddress RemoteEndPoint
private AspNetCore.HttpSys.Internal.SocketAddress RemoteEndPoint
{
get
{
@ -203,7 +203,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
private SocketAddress LocalEndPoint
private AspNetCore.HttpSys.Internal.SocketAddress LocalEndPoint
{
get
{

Просмотреть файл

@ -10,6 +10,7 @@ using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.HttpSys

Просмотреть файл

@ -7,6 +7,7 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.HttpSys

Просмотреть файл

@ -7,6 +7,7 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.HttpSys.Internal;
namespace Microsoft.AspNetCore.Server.HttpSys
{

Просмотреть файл

@ -10,8 +10,9 @@ using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Primitives;
using static Microsoft.AspNetCore.Server.HttpSys.UnsafeNclNativeMethods;
using static Microsoft.AspNetCore.HttpSys.Internal.UnsafeNclNativeMethods;
namespace Microsoft.AspNetCore.Server.HttpSys
{
@ -24,7 +25,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private TimeSpan? _cacheTtl;
private long _expectedBodyLength;
private BoundaryType _boundaryType;
private HttpApi.HTTP_RESPONSE_V2 _nativeResponse;
private HttpApiTypes.HTTP_RESPONSE_V2 _nativeResponse;
internal Response(RequestContext requestContext)
{
@ -33,7 +34,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
Headers = new HeaderCollection();
// We haven't started yet, or we're just buffered, we can clear any data, headers, and state so
// that we can start over (e.g. to write an error message).
_nativeResponse = new HttpApi.HTTP_RESPONSE_V2();
_nativeResponse = new HttpApiTypes.HTTP_RESPONSE_V2();
Headers.IsReadOnly = false;
Headers.Clear();
_reasonPhrase = null;
@ -249,9 +250,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// What would we loose by bypassing HttpSendHttpResponse?
//
// TODO: Consider using the HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA flag for most/all responses rather than just Opaque.
internal unsafe uint SendHeaders(HttpApi.HTTP_DATA_CHUNK[] dataChunks,
internal unsafe uint SendHeaders(HttpApiTypes.HTTP_DATA_CHUNK[] dataChunks,
ResponseStreamAsyncResult asyncResult,
HttpApi.HTTP_FLAGS flags,
HttpApiTypes.HTTP_FLAGS flags,
bool isOpaqueUpgrade)
{
Debug.Assert(!HasStarted, "HttpListenerResponse::SendHeaders()|SentHeaders is true.");
@ -273,7 +274,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
var handle = GCHandle.Alloc(dataChunks, GCHandleType.Pinned);
pinnedHeaders.Add(handle);
_nativeResponse.Response_V1.EntityChunkCount = (ushort)dataChunks.Length;
_nativeResponse.Response_V1.pEntityChunks = (HttpApi.HTTP_DATA_CHUNK*)handle.AddrOfPinnedObject();
_nativeResponse.Response_V1.pEntityChunks = (HttpApiTypes.HTTP_DATA_CHUNK*)handle.AddrOfPinnedObject();
}
else if (asyncResult != null && asyncResult.DataChunks != null)
{
@ -286,10 +287,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys
_nativeResponse.Response_V1.pEntityChunks = null;
}
var cachePolicy = new HttpApi.HTTP_CACHE_POLICY();
var cachePolicy = new HttpApiTypes.HTTP_CACHE_POLICY();
if (_cacheTtl.HasValue && _cacheTtl.Value > TimeSpan.Zero)
{
cachePolicy.Policy = HttpApi.HTTP_CACHE_POLICY_TYPE.HttpCachePolicyTimeToLive;
cachePolicy.Policy = HttpApiTypes.HTTP_CACHE_POLICY_TYPE.HttpCachePolicyTimeToLive;
cachePolicy.SecondsToLive = (uint)Math.Min(_cacheTtl.Value.Ticks / TimeSpan.TicksPerSecond, Int32.MaxValue);
}
@ -297,8 +298,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
fixed (byte* pReasonPhrase = reasonPhraseBytes)
{
_nativeResponse.Response_V1.ReasonLength = (ushort)reasonPhraseBytes.Length;
_nativeResponse.Response_V1.pReason = (sbyte*)pReasonPhrase;
fixed (HttpApi.HTTP_RESPONSE_V2* pResponse = &_nativeResponse)
_nativeResponse.Response_V1.pReason = (byte*)pReasonPhrase;
fixed (HttpApiTypes.HTTP_RESPONSE_V2* pResponse = &_nativeResponse)
{
statusCode =
HttpApi.HttpSendHttpResponse(
@ -330,14 +331,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys
return statusCode;
}
internal HttpApi.HTTP_FLAGS ComputeHeaders(long writeCount, bool endOfRequest = false)
internal HttpApiTypes.HTTP_FLAGS ComputeHeaders(long writeCount, bool endOfRequest = false)
{
if (StatusCode == (ushort)StatusCodes.Status401Unauthorized)
{
RequestContext.Server.Options.Authentication.SetAuthenticationChallenge(RequestContext);
}
var flags = HttpApi.HTTP_FLAGS.NONE;
var flags = HttpApiTypes.HTTP_FLAGS.NONE;
Debug.Assert(!HasComputedHeaders, nameof(HasComputedHeaders) + " is true.");
_responseState = ResponseState.ComputedHeaders;
@ -414,7 +415,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
Headers.Append(HttpKnownHeaderNames.Connection, Constants.Close);
}
flags = HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_DISCONNECT;
flags = HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_DISCONNECT;
}
return flags;
@ -428,8 +429,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private unsafe List<GCHandle> SerializeHeaders(bool isOpaqueUpgrade)
{
Headers.IsReadOnly = true; // Prohibit further modifications.
HttpApi.HTTP_UNKNOWN_HEADER[] unknownHeaders = null;
HttpApi.HTTP_RESPONSE_INFO[] knownHeaderInfo = null;
HttpApiTypes.HTTP_UNKNOWN_HEADER[] unknownHeaders = null;
HttpApiTypes.HTTP_RESPONSE_INFO[] knownHeaderInfo = null;
List<GCHandle> pinnedHeaders;
GCHandle gcHandle;
@ -452,11 +453,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
continue;
}
// See if this is an unknown header
lookup = HttpApi.HTTP_RESPONSE_HEADER_ID.IndexOfKnownHeader(headerPair.Key);
lookup = HttpApiTypes.HTTP_RESPONSE_HEADER_ID.IndexOfKnownHeader(headerPair.Key);
// Http.Sys doesn't let us send the Connection: Upgrade header as a Known header.
if (lookup == -1 ||
(isOpaqueUpgrade && lookup == (int)HttpApi.HTTP_RESPONSE_HEADER_ID.Enum.HttpHeaderConnection))
(isOpaqueUpgrade && lookup == (int)HttpApiTypes.HTTP_RESPONSE_HEADER_ID.Enum.HttpHeaderConnection))
{
numUnknownHeaders += headerPair.Value.Count;
}
@ -469,7 +470,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
try
{
fixed (HttpApi.HTTP_KNOWN_HEADER* pKnownHeaders = &_nativeResponse.Response_V1.Headers.KnownHeaders)
fixed (HttpApiTypes.HTTP_KNOWN_HEADER* pKnownHeaders = &_nativeResponse.Response_V1.Headers.KnownHeaders)
{
foreach (var headerPair in Headers)
{
@ -479,18 +480,18 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
headerName = headerPair.Key;
StringValues headerValues = headerPair.Value;
lookup = HttpApi.HTTP_RESPONSE_HEADER_ID.IndexOfKnownHeader(headerName);
lookup = HttpApiTypes.HTTP_RESPONSE_HEADER_ID.IndexOfKnownHeader(headerName);
// Http.Sys doesn't let us send the Connection: Upgrade header as a Known header.
if (lookup == -1 ||
(isOpaqueUpgrade && lookup == (int)HttpApi.HTTP_RESPONSE_HEADER_ID.Enum.HttpHeaderConnection))
(isOpaqueUpgrade && lookup == (int)HttpApiTypes.HTTP_RESPONSE_HEADER_ID.Enum.HttpHeaderConnection))
{
if (unknownHeaders == null)
{
unknownHeaders = new HttpApi.HTTP_UNKNOWN_HEADER[numUnknownHeaders];
unknownHeaders = new HttpApiTypes.HTTP_UNKNOWN_HEADER[numUnknownHeaders];
gcHandle = GCHandle.Alloc(unknownHeaders, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
_nativeResponse.Response_V1.Headers.pUnknownHeaders = (HttpApi.HTTP_UNKNOWN_HEADER*)gcHandle.AddrOfPinnedObject();
_nativeResponse.Response_V1.Headers.pUnknownHeaders = (HttpApiTypes.HTTP_UNKNOWN_HEADER*)gcHandle.AddrOfPinnedObject();
}
for (int headerValueIndex = 0; headerValueIndex < headerValues.Count; headerValueIndex++)
@ -500,7 +501,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
unknownHeaders[_nativeResponse.Response_V1.Headers.UnknownHeaderCount].NameLength = (ushort)bytes.Length;
gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
unknownHeaders[_nativeResponse.Response_V1.Headers.UnknownHeaderCount].pName = (sbyte*)gcHandle.AddrOfPinnedObject();
unknownHeaders[_nativeResponse.Response_V1.Headers.UnknownHeaderCount].pName = (byte*)gcHandle.AddrOfPinnedObject();
// Add Value
headerValue = headerValues[headerValueIndex] ?? string.Empty;
@ -508,7 +509,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
unknownHeaders[_nativeResponse.Response_V1.Headers.UnknownHeaderCount].RawValueLength = (ushort)bytes.Length;
gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
unknownHeaders[_nativeResponse.Response_V1.Headers.UnknownHeaderCount].pRawValue = (sbyte*)gcHandle.AddrOfPinnedObject();
unknownHeaders[_nativeResponse.Response_V1.Headers.UnknownHeaderCount].pRawValue = (byte*)gcHandle.AddrOfPinnedObject();
_nativeResponse.Response_V1.Headers.UnknownHeaderCount++;
}
}
@ -519,30 +520,30 @@ namespace Microsoft.AspNetCore.Server.HttpSys
pKnownHeaders[lookup].RawValueLength = (ushort)bytes.Length;
gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
pKnownHeaders[lookup].pRawValue = (sbyte*)gcHandle.AddrOfPinnedObject();
pKnownHeaders[lookup].pRawValue = (byte*)gcHandle.AddrOfPinnedObject();
}
else
{
if (knownHeaderInfo == null)
{
knownHeaderInfo = new HttpApi.HTTP_RESPONSE_INFO[numKnownMultiHeaders];
knownHeaderInfo = new HttpApiTypes.HTTP_RESPONSE_INFO[numKnownMultiHeaders];
gcHandle = GCHandle.Alloc(knownHeaderInfo, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
_nativeResponse.pResponseInfo = (HttpApi.HTTP_RESPONSE_INFO*)gcHandle.AddrOfPinnedObject();
_nativeResponse.pResponseInfo = (HttpApiTypes.HTTP_RESPONSE_INFO*)gcHandle.AddrOfPinnedObject();
}
knownHeaderInfo[_nativeResponse.ResponseInfoCount].Type = HttpApi.HTTP_RESPONSE_INFO_TYPE.HttpResponseInfoTypeMultipleKnownHeaders;
knownHeaderInfo[_nativeResponse.ResponseInfoCount].Length = (uint)Marshal.SizeOf<HttpApi.HTTP_MULTIPLE_KNOWN_HEADERS>();
knownHeaderInfo[_nativeResponse.ResponseInfoCount].Type = HttpApiTypes.HTTP_RESPONSE_INFO_TYPE.HttpResponseInfoTypeMultipleKnownHeaders;
knownHeaderInfo[_nativeResponse.ResponseInfoCount].Length = (uint)Marshal.SizeOf<HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS>();
HttpApi.HTTP_MULTIPLE_KNOWN_HEADERS header = new HttpApi.HTTP_MULTIPLE_KNOWN_HEADERS();
HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS header = new HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS();
header.HeaderId = (HttpApi.HTTP_RESPONSE_HEADER_ID.Enum)lookup;
header.Flags = HttpApi.HTTP_RESPONSE_INFO_FLAGS.PreserveOrder; // TODO: The docs say this is for www-auth only.
header.HeaderId = (HttpApiTypes.HTTP_RESPONSE_HEADER_ID.Enum)lookup;
header.Flags = HttpApiTypes.HTTP_RESPONSE_INFO_FLAGS.PreserveOrder; // TODO: The docs say this is for www-auth only.
HttpApi.HTTP_KNOWN_HEADER[] nativeHeaderValues = new HttpApi.HTTP_KNOWN_HEADER[headerValues.Count];
HttpApiTypes.HTTP_KNOWN_HEADER[] nativeHeaderValues = new HttpApiTypes.HTTP_KNOWN_HEADER[headerValues.Count];
gcHandle = GCHandle.Alloc(nativeHeaderValues, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
header.KnownHeaders = (HttpApi.HTTP_KNOWN_HEADER*)gcHandle.AddrOfPinnedObject();
header.KnownHeaders = (HttpApiTypes.HTTP_KNOWN_HEADER*)gcHandle.AddrOfPinnedObject();
for (int headerValueIndex = 0; headerValueIndex < headerValues.Count; headerValueIndex++)
{
@ -552,14 +553,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys
nativeHeaderValues[header.KnownHeaderCount].RawValueLength = (ushort)bytes.Length;
gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
nativeHeaderValues[header.KnownHeaderCount].pRawValue = (sbyte*)gcHandle.AddrOfPinnedObject();
nativeHeaderValues[header.KnownHeaderCount].pRawValue = (byte*)gcHandle.AddrOfPinnedObject();
header.KnownHeaderCount++;
}
// This type is a struct, not an object, so pinning it causes a boxed copy to be created. We can't do that until after all the fields are set.
gcHandle = GCHandle.Alloc(header, GCHandleType.Pinned);
pinnedHeaders.Add(gcHandle);
knownHeaderInfo[_nativeResponse.ResponseInfoCount].pInfo = (HttpApi.HTTP_MULTIPLE_KNOWN_HEADERS*)gcHandle.AddrOfPinnedObject();
knownHeaderInfo[_nativeResponse.ResponseInfoCount].pInfo = (HttpApiTypes.HTTP_MULTIPLE_KNOWN_HEADERS*)gcHandle.AddrOfPinnedObject();
_nativeResponse.ResponseInfoCount++;
}
@ -595,9 +596,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// TODO: Send headers async?
ulong errorCode = SendHeaders(null, null,
HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_OPAQUE |
HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA |
HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA,
HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_OPAQUE |
HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA |
HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA,
true);
if (errorCode != ErrorCodes.ERROR_SUCCESS)

Просмотреть файл

@ -9,8 +9,9 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Logging;
using static Microsoft.AspNetCore.Server.HttpSys.UnsafeNclNativeMethods;
using static Microsoft.AspNetCore.HttpSys.Internal.UnsafeNclNativeMethods;
namespace Microsoft.AspNetCore.Server.HttpSys
{
@ -132,7 +133,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
uint statusCode = 0;
HttpApi.HTTP_DATA_CHUNK[] dataChunks;
HttpApiTypes.HTTP_DATA_CHUNK[] dataChunks;
var pinnedBuffers = PinDataBuffers(endOfRequest, data, out dataChunks);
try
{
@ -142,7 +143,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
else
{
fixed (HttpApi.HTTP_DATA_CHUNK* pDataChunks = dataChunks)
fixed (HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks = dataChunks)
{
statusCode = HttpApi.HttpSendResponseEntityBody(
RequestQueueHandle,
@ -183,7 +184,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
private List<GCHandle> PinDataBuffers(bool endOfRequest, ArraySegment<byte> data, out HttpApi.HTTP_DATA_CHUNK[] dataChunks)
private List<GCHandle> PinDataBuffers(bool endOfRequest, ArraySegment<byte> data, out HttpApiTypes.HTTP_DATA_CHUNK[] dataChunks)
{
var pins = new List<GCHandle>();
var chunked = _requestContext.Response.BoundaryType == BoundaryType.Chunked;
@ -192,14 +193,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// Figure out how many data chunks
if (chunked && data.Count == 0 && endOfRequest)
{
dataChunks = new HttpApi.HTTP_DATA_CHUNK[1];
dataChunks = new HttpApiTypes.HTTP_DATA_CHUNK[1];
SetDataChunk(dataChunks, ref currentChunk, pins, new ArraySegment<byte>(Helpers.ChunkTerminator));
return pins;
}
else if (data.Count == 0)
{
// No data
dataChunks = new HttpApi.HTTP_DATA_CHUNK[0];
dataChunks = new HttpApiTypes.HTTP_DATA_CHUNK[0];
return pins;
}
@ -215,7 +216,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
chunkCount += 1;
}
}
dataChunks = new HttpApi.HTTP_DATA_CHUNK[chunkCount];
dataChunks = new HttpApiTypes.HTTP_DATA_CHUNK[chunkCount];
if (chunked)
{
@ -238,11 +239,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
return pins;
}
private static void SetDataChunk(HttpApi.HTTP_DATA_CHUNK[] chunks, ref int chunkIndex, List<GCHandle> pins, ArraySegment<byte> buffer)
private static void SetDataChunk(HttpApiTypes.HTTP_DATA_CHUNK[] chunks, ref int chunkIndex, List<GCHandle> pins, ArraySegment<byte> buffer)
{
var handle = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned);
pins.Add(handle);
chunks[chunkIndex].DataChunkType = HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
chunks[chunkIndex].DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
chunks[chunkIndex].fromMemory.pBuffer = handle.AddrOfPinnedObject() + buffer.Offset;
chunks[chunkIndex].fromMemory.BufferLength = (uint)buffer.Count;
chunkIndex++;
@ -355,7 +356,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
// Last write, cache it for special cancellation handling.
if ((flags & HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA) == 0)
if ((flags & HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA) == 0)
{
_lastWrite = asyncResult;
}
@ -405,9 +406,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
_requestContext.Abort();
}
private HttpApi.HTTP_FLAGS ComputeLeftToWrite(long writeCount, bool endOfRequest = false)
private HttpApiTypes.HTTP_FLAGS ComputeLeftToWrite(long writeCount, bool endOfRequest = false)
{
var flags = HttpApi.HTTP_FLAGS.NONE;
var flags = HttpApiTypes.HTTP_FLAGS.NONE;
if (!_requestContext.Response.HasComputedHeaders)
{
flags = _requestContext.Response.ComputeHeaders(writeCount, endOfRequest);
@ -430,11 +431,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (endOfRequest && _requestContext.Response.BoundaryType == BoundaryType.Close)
{
flags |= HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_DISCONNECT;
flags |= HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_DISCONNECT;
}
else if (!endOfRequest && _leftToWrite != writeCount)
{
flags |= HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA;
flags |= HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA;
}
// Update _leftToWrite now so we can queue up additional async writes.
@ -647,7 +648,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
// Last write, cache it for special cancellation handling.
if ((flags & HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA) == 0)
if ((flags & HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA) == 0)
{
_lastWrite = asyncResult;
}

Просмотреть файл

@ -7,7 +7,7 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using static Microsoft.AspNetCore.Server.HttpSys.UnsafeNclNativeMethods;
using Microsoft.AspNetCore.HttpSys.Internal;
namespace Microsoft.AspNetCore.Server.HttpSys
{
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private static readonly IOCompletionCallback IOCallback = new IOCompletionCallback(Callback);
private SafeNativeOverlapped _overlapped;
private HttpApi.HTTP_DATA_CHUNK[] _dataChunks;
private HttpApiTypes.HTTP_DATA_CHUNK[] _dataChunks;
private FileStream _fileStream;
private ResponseBody _responseStream;
private TaskCompletionSource<object> _tcs;
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
return;
}
_dataChunks = new HttpApi.HTTP_DATA_CHUNK[1 + (chunked ? 2 : 0)];
_dataChunks = new HttpApiTypes.HTTP_DATA_CHUNK[1 + (chunked ? 2 : 0)];
objectsToPin = new object[_dataChunks.Length + 1];
objectsToPin[0] = _dataChunks;
var currentChunk = 0;
@ -110,7 +110,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
else
{
_dataChunks = new HttpApi.HTTP_DATA_CHUNK[chunked ? 3 : 1];
_dataChunks = new HttpApiTypes.HTTP_DATA_CHUNK[chunked ? 3 : 1];
object[] objectsToPin = new object[_dataChunks.Length];
objectsToPin[_dataChunks.Length - 1] = _dataChunks;
@ -119,23 +119,23 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (chunked)
{
chunkHeaderBuffer = Helpers.GetChunkHeader(count);
_dataChunks[0].DataChunkType = HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
_dataChunks[0].DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
_dataChunks[0].fromMemory.BufferLength = (uint)chunkHeaderBuffer.Count;
objectsToPin[0] = chunkHeaderBuffer.Array;
_dataChunks[1].DataChunkType = HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFileHandle;
_dataChunks[1].DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFileHandle;
_dataChunks[1].fromFile.offset = (ulong)offset;
_dataChunks[1].fromFile.count = (ulong)count;
_dataChunks[1].fromFile.fileHandle = _fileStream.SafeFileHandle.DangerousGetHandle();
// Nothing to pin for the file handle.
_dataChunks[2].DataChunkType = HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
_dataChunks[2].DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
_dataChunks[2].fromMemory.BufferLength = (uint)Helpers.CRLF.Length;
objectsToPin[1] = Helpers.CRLF;
}
else
{
_dataChunks[0].DataChunkType = HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFileHandle;
_dataChunks[0].DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFileHandle;
_dataChunks[0].fromFile.offset = (ulong)offset;
_dataChunks[0].fromFile.count = (ulong)count;
_dataChunks[0].fromFile.fileHandle = _fileStream.SafeFileHandle.DangerousGetHandle();
@ -154,11 +154,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
private static void SetDataChunk(HttpApi.HTTP_DATA_CHUNK[] chunks, ref int chunkIndex, object[] objectsToPin, ref int pinIndex, ArraySegment<byte> segment)
private static void SetDataChunk(HttpApiTypes.HTTP_DATA_CHUNK[] chunks, ref int chunkIndex, object[] objectsToPin, ref int pinIndex, ArraySegment<byte> segment)
{
objectsToPin[pinIndex] = segment.Array;
pinIndex++;
chunks[chunkIndex].DataChunkType = HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
chunks[chunkIndex].DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
// The address is not set until after we pin it with Overlapped
chunks[chunkIndex].fromMemory.BufferLength = (uint)segment.Count;
chunkIndex++;
@ -195,7 +195,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
internal HttpApi.HTTP_DATA_CHUNK* DataChunks
internal HttpApiTypes.HTTP_DATA_CHUNK* DataChunks
{
get
{
@ -205,7 +205,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
else
{
return (HttpApi.HTTP_DATA_CHUNK*)(Marshal.UnsafeAddrOfPinnedArrayElement(_dataChunks, 0));
return (HttpApiTypes.HTTP_DATA_CHUNK*)(Marshal.UnsafeAddrOfPinnedArrayElement(_dataChunks, 0));
}
}
}

Просмотреть файл

@ -3,6 +3,7 @@
using System;
using System.Runtime.InteropServices;
using Microsoft.AspNetCore.HttpSys.Internal;
namespace Microsoft.AspNetCore.Server.HttpSys
{
@ -15,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
public sealed class TimeoutManager
{
private static readonly int TimeoutLimitSize =
Marshal.SizeOf<HttpApi.HTTP_TIMEOUT_LIMIT_INFO>();
Marshal.SizeOf<HttpApiTypes.HTTP_TIMEOUT_LIMIT_INFO>();
private UrlGroup _urlGroup;
private int[] _timeouts;
@ -47,11 +48,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
get
{
return GetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE.EntityBody);
return GetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE.EntityBody);
}
set
{
SetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE.EntityBody, value);
SetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE.EntityBody, value);
}
}
@ -70,11 +71,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
get
{
return GetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE.DrainEntityBody);
return GetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE.DrainEntityBody);
}
set
{
SetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE.DrainEntityBody, value);
SetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE.DrainEntityBody, value);
}
}
@ -88,11 +89,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
get
{
return GetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE.RequestQueue);
return GetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE.RequestQueue);
}
set
{
SetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE.RequestQueue, value);
SetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE.RequestQueue, value);
}
}
@ -107,11 +108,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
get
{
return GetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE.IdleConnection);
return GetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE.IdleConnection);
}
set
{
SetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE.IdleConnection, value);
SetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE.IdleConnection, value);
}
}
@ -127,11 +128,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
get
{
return GetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait);
return GetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE.HeaderWait);
}
set
{
SetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait, value);
SetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE.HeaderWait, value);
}
}
@ -167,13 +168,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys
#region Helpers
private TimeSpan GetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE type)
private TimeSpan GetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE type)
{
// Since we maintain local state, GET is local.
return new TimeSpan(0, 0, (int)_timeouts[(int)type]);
}
private void SetTimeSpanTimeout(HttpApi.HTTP_TIMEOUT_TYPE type, TimeSpan value)
private void SetTimeSpanTimeout(HttpApiTypes.HTTP_TIMEOUT_TYPE type, TimeSpan value)
{
// All timeouts are defined as USHORT in native layer (except MinSendRate, which is ULONG). Make sure that
// timeout value is within range.
@ -207,25 +208,25 @@ namespace Microsoft.AspNetCore.Server.HttpSys
return;
}
var timeoutinfo = new HttpApi.HTTP_TIMEOUT_LIMIT_INFO();
var timeoutinfo = new HttpApiTypes.HTTP_TIMEOUT_LIMIT_INFO();
timeoutinfo.Flags = HttpApi.HTTP_FLAGS.HTTP_PROPERTY_FLAG_PRESENT;
timeoutinfo.Flags = HttpApiTypes.HTTP_FLAGS.HTTP_PROPERTY_FLAG_PRESENT;
timeoutinfo.DrainEntityBody =
(ushort)timeouts[(int)HttpApi.HTTP_TIMEOUT_TYPE.DrainEntityBody];
(ushort)timeouts[(int)HttpApiTypes.HTTP_TIMEOUT_TYPE.DrainEntityBody];
timeoutinfo.EntityBody =
(ushort)timeouts[(int)HttpApi.HTTP_TIMEOUT_TYPE.EntityBody];
(ushort)timeouts[(int)HttpApiTypes.HTTP_TIMEOUT_TYPE.EntityBody];
timeoutinfo.RequestQueue =
(ushort)timeouts[(int)HttpApi.HTTP_TIMEOUT_TYPE.RequestQueue];
(ushort)timeouts[(int)HttpApiTypes.HTTP_TIMEOUT_TYPE.RequestQueue];
timeoutinfo.IdleConnection =
(ushort)timeouts[(int)HttpApi.HTTP_TIMEOUT_TYPE.IdleConnection];
(ushort)timeouts[(int)HttpApiTypes.HTTP_TIMEOUT_TYPE.IdleConnection];
timeoutinfo.HeaderWait =
(ushort)timeouts[(int)HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait];
(ushort)timeouts[(int)HttpApiTypes.HTTP_TIMEOUT_TYPE.HeaderWait];
timeoutinfo.MinSendRate = minSendBytesPerSecond;
var infoptr = new IntPtr(&timeoutinfo);
_urlGroup.SetProperty(
HttpApi.HTTP_SERVER_PROPERTY.HttpServerTimeoutsProperty,
HttpApiTypes.HTTP_SERVER_PROPERTY.HttpServerTimeoutsProperty,
infoptr, (uint)TimeoutLimitSize);
}

Просмотреть файл

@ -3,6 +3,7 @@
using System;
using System.Globalization;
using Microsoft.AspNetCore.HttpSys.Internal;
namespace Microsoft.AspNetCore.Server.HttpSys
{

Просмотреть файл

@ -5,6 +5,7 @@ using System.Linq;
using System.Threading;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

Просмотреть файл

@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;