From 2226f6c44ca3e353f44f89f14387dbb7dd986bd7 Mon Sep 17 00:00:00 2001 From: David Hall Date: Wed, 4 Oct 2023 16:12:21 -0600 Subject: [PATCH] Added nullability to HttpApi --- PInvoke/HttpApi/http.Enum.cs | 11 +- PInvoke/HttpApi/http.Func.cs | 174 ++++++++++++++++++++++++++++-- PInvoke/HttpApi/http.Struct.cs | 44 +++----- PInvoke/HttpApi/http.cs | 7 +- UnitTests/PInvoke/HttpApi/HttpApiTests.cs | 2 + 5 files changed, 195 insertions(+), 43 deletions(-) diff --git a/PInvoke/HttpApi/http.Enum.cs b/PInvoke/HttpApi/http.Enum.cs index 25bd5e8f..91a2611e 100644 --- a/PInvoke/HttpApi/http.Enum.cs +++ b/PInvoke/HttpApi/http.Enum.cs @@ -1,4 +1,3 @@ - namespace Vanara.PInvoke; /// Items from HttpApi.dll. @@ -235,9 +234,11 @@ public static partial class HttpApi [Flags] public enum HTTP_CREATE_REQUEST_QUEUE_FLAG : uint { +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member HTTP_CREATE_REQUEST_QUEUE_FLAG_OPEN_EXISTING = 0x00000001, HTTP_CREATE_REQUEST_QUEUE_FLAG_CONTROLLER = 0x00000002, HTTP_CREATE_REQUEST_QUEUE_FLAG_DELEGATION = 0x00000008, +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } /// @@ -1601,10 +1602,12 @@ public static partial class HttpApi [Flags] public enum HTTP_REQUEST_SIZING_INFO_FLAG : uint { +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member HTTP_REQUEST_SIZING_INFO_FLAG_TCP_FAST_OPEN = 0x00000001, HTTP_REQUEST_SIZING_INFO_FLAG_TLS_SESSION_RESUMPTION = 0x00000002, HTTP_REQUEST_SIZING_INFO_FLAG_TLS_FALSE_START = 0x00000004, HTTP_REQUEST_SIZING_INFO_FLAG_FIRST_REQUEST = 0x00000008, +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } /// List of possible sizes for which information will be retured in HTTP_REQUEST_SIZING_INFO. @@ -1636,6 +1639,7 @@ public static partial class HttpApi [PInvokeData("http.h")] public enum HTTP_REQUEST_TIMING_TYPE { +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member HttpRequestTimingTypeConnectionStart, HttpRequestTimingTypeDataStart, HttpRequestTimingTypeTlsCertificateLoadStart, @@ -1667,6 +1671,7 @@ public static partial class HttpApi HttpRequestTimingTypeHttp3HeaderDecodeStart, HttpRequestTimingTypeHttp3HeaderDecodeEnd, HttpRequestTimingTypeMax +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } /// @@ -2070,8 +2075,10 @@ public static partial class HttpApi [PInvokeData("http.h")] public enum HTTP_SERVICE_CONFIG_SETTING_KEY { +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member HttpNone = 0, HttpTlsThrottle +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } /// A combination of zero or more of the following flag values can be combined with OR as appropriate. @@ -2156,6 +2163,7 @@ public static partial class HttpApi HeaderWaitTimeout, } +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member /// The extended param type for the SSL extended params. [PInvokeData("http.h")] public enum HTTP_SSL_SERVICE_CONFIG_EX_PARAM_TYPE @@ -2177,6 +2185,7 @@ public static partial class HttpApi HttpSchemeHttps, HttpSchemeMaximum } +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member /// The URL flags qualifying the URL that is removed. [PInvokeData("http.h", MSDNShortId = "NF:http.HttpRemoveUrlFromUrlGroup")] diff --git a/PInvoke/HttpApi/http.Func.cs b/PInvoke/HttpApi/http.Func.cs index 0e290d23..21573f0a 100644 --- a/PInvoke/HttpApi/http.Func.cs +++ b/PInvoke/HttpApi/http.Func.cs @@ -582,7 +582,7 @@ public static partial class HttpApi [DllImport(Lib_Httpapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("http.h", MSDNShortId = "NF:http.HttpCreateRequestQueue")] public static extern Win32Error HttpCreateRequestQueue(HTTPAPI_VERSION Version, [Optional, MarshalAs(UnmanagedType.LPWStr)] string? Name, - [In, Optional] SECURITY_ATTRIBUTES SecurityAttributes, [In, Optional] HTTP_CREATE_REQUEST_QUEUE_FLAG Flags, + [In, Optional] SECURITY_ATTRIBUTES? SecurityAttributes, [In, Optional] HTTP_CREATE_REQUEST_QUEUE_FLAG Flags, out SafeHREQQUEUE RequestQueueHandle); /// The HttpCreateServerSession function creates a server session for the specified version. @@ -997,7 +997,7 @@ public static partial class HttpApi { if (!CorrespondingTypeAttribute.CanSet(out var ConfigId)) throw new ArgumentOutOfRangeException(nameof(pConfigInformation)); - using var mem = new SafeCoTaskMemStruct(pConfigInformation); + using SafeCoTaskMemStruct mem = pConfigInformation; return HttpDeleteServiceConfiguration(default, ConfigId, mem, mem.Size, default); } @@ -1245,7 +1245,7 @@ public static partial class HttpApi // https://docs.microsoft.com/en-us/windows/win32/api/http/nf-http-httpprepareurl HTTPAPI_LINKAGE ULONG HttpPrepareUrl( PVOID Reserved, // ULONG Flags, [in] PCWSTR Url, [out] PWSTR *PreparedUrl ); [PInvokeData("http.h", MSDNShortId = "NF:http.HttpPrepareUrl")] - public static Win32Error HttpPrepareUrl(string Url, out string PreparedUrl) + public static Win32Error HttpPrepareUrl(string Url, out string? PreparedUrl) { var err = HttpPrepareUrl(default, default, Url, out var pUrl); PreparedUrl = err.Succeeded ? pUrl.ToString(-1, CharSet.Unicode) : null; @@ -2883,7 +2883,7 @@ public static partial class HttpApi /// /// public static Win32Error HttpReceiveHttpRequest(HREQQUEUEv1 RequestQueueHandle, [In] HTTP_REQUEST_ID RequestId, - [In] HTTP_RECEIVE_REQUEST_FLAG Flags, out HTTP_REQUEST RequestBuffer) + [In] HTTP_RECEIVE_REQUEST_FLAG Flags, out HTTP_REQUEST? RequestBuffer) { RequestBuffer = new(); var err = HttpReceiveHttpRequest(RequestQueueHandle, RequestId, Flags, RequestBuffer.Ptr, RequestBuffer.Ptr.Size, out var sz, default); @@ -3002,7 +3002,7 @@ public static partial class HttpApi [DllImport(Lib_Httpapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("http.h", MSDNShortId = "NF:http.HttpReceiveRequestEntityBody")] public static extern Win32Error HttpReceiveRequestEntityBody([In] HREQQUEUEv1 RequestQueueHandle, [In] HTTP_REQUEST_ID RequestId, - [In] HTTP_RECEIVE_REQUEST_ENTITY_BODY_FLAG Flags, [Out] IntPtr EntityBuffer, [In] uint EntityBufferLength, out uint BytesReturned, + [In] HTTP_RECEIVE_REQUEST_ENTITY_BODY_FLAG Flags, [Out] IntPtr EntityBuffer, [In] uint EntityBufferLength, [In, Optional] IntPtr BytesReturned, in NativeOverlapped Overlapped); /// The HttpReceiveRequestEntityBody function receives additional entity body data for a specified HTTP request. @@ -3224,7 +3224,7 @@ public static partial class HttpApi // HttpRemoveUrlFromUrlGroup( [in] HTTP_URL_GROUP_ID UrlGroupId, [in] PCWSTR pFullyQualifiedUrl, [in] ULONG Flags ); [DllImport(Lib_Httpapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("http.h", MSDNShortId = "NF:http.HttpRemoveUrlFromUrlGroup")] - public static extern Win32Error HttpRemoveUrlFromUrlGroup([In] HTTP_URL_GROUP_ID UrlGroupId, [MarshalAs(UnmanagedType.LPWStr)] string pFullyQualifiedUrl, + public static extern Win32Error HttpRemoveUrlFromUrlGroup([In] HTTP_URL_GROUP_ID UrlGroupId, [MarshalAs(UnmanagedType.LPWStr)] string? pFullyQualifiedUrl, [In, Optional] HTTP_URL_FLAG Flags); /// The HttpSendHttpResponse function sends an HTTP response to the specified HTTP request. @@ -3380,7 +3380,7 @@ public static partial class HttpApi [DllImport(Lib_Httpapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("http.h", MSDNShortId = "NF:http.HttpSendHttpResponse")] public static extern Win32Error HttpSendHttpResponse([In] HREQQUEUEv1 RequestQueueHandle, [In] HTTP_REQUEST_ID RequestId, [In] HTTP_SEND_RESPONSE_FLAG Flags, - in HTTP_RESPONSE_V1 HttpResponse, in HTTP_CACHE_POLICY CachePolicy, out uint BytesSent, [In, Optional] IntPtr Reserved1, [In, Optional] uint Reserved2, + in HTTP_RESPONSE_V1 HttpResponse, in HTTP_CACHE_POLICY CachePolicy, [Optional] IntPtr BytesSent, [In, Optional] IntPtr Reserved1, [In, Optional] uint Reserved2, in NativeOverlapped Overlapped, in HTTP_LOG_DATA LogData); /// The HttpSendHttpResponse function sends an HTTP response to the specified HTTP request. @@ -3692,7 +3692,7 @@ public static partial class HttpApi [DllImport(Lib_Httpapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("http.h", MSDNShortId = "NF:http.HttpSendHttpResponse")] public static extern Win32Error HttpSendHttpResponse([In] HREQQUEUEv1 RequestQueueHandle, [In] HTTP_REQUEST_ID RequestId, [In] HTTP_SEND_RESPONSE_FLAG Flags, - in HTTP_RESPONSE_V2 HttpResponse, in HTTP_CACHE_POLICY CachePolicy, out uint BytesSent, [In, Optional] IntPtr Reserved1, [In, Optional] uint Reserved2, + in HTTP_RESPONSE_V2 HttpResponse, in HTTP_CACHE_POLICY CachePolicy, [Optional] IntPtr BytesSent, [In, Optional] IntPtr Reserved1, [In, Optional] uint Reserved2, in NativeOverlapped Overlapped, in HTTP_LOG_DATA LogData); /// The HttpSendHttpResponse function sends an HTTP response to the specified HTTP request. @@ -3851,6 +3851,162 @@ public static partial class HttpApi in HTTP_RESPONSE_V2 HttpResponse, [In, Optional] IntPtr CachePolicy, out uint BytesSent, [In, Optional] IntPtr Reserved1, [In, Optional] uint Reserved2, [In, Optional] IntPtr Overlapped, [In, Optional] IntPtr LogData); + /// The HttpSendHttpResponse function sends an HTTP response to the specified HTTP request. + /// + /// + /// A handle to the request queue from which the specified request was retrieved. A request queue is created and its handle returned by a + /// call to the HttpCreateRequestQueue function. + /// + /// + /// Windows Server 2003 with SP1 and Windows XP with SP2: The handle to the request queue is created by the HttpCreateHttpHandle function. + /// + /// + /// + /// An identifier of the HTTP request to which this response corresponds. This value is returned in the RequestId member of the + /// HTTP_REQUEST structure by a call to the HttpReceiveHttpRequest function. This value cannot be HTTP_NULL_ID. + /// + /// + /// This parameter can be a combination of some of the following flag values. Those that are mutually exclusive are marked accordingly. + /// + /// + /// Flags + /// Meaning + /// + /// + /// HTTP_SEND_RESPONSE_FLAG_DISCONNECT + /// + /// The network connection should be disconnected after sending this response, overriding any persistent connection features associated + /// with the version of HTTP in use. + /// + /// + /// + /// HTTP_SEND_RESPONSE_FLAG_MORE_DATA + /// + /// Additional entity body data for this response is sent by the application through one or more subsequent calls to + /// HttpSendResponseEntityBody. The last call sending entity-body data then sets this flag to zero. + /// + /// + /// + /// HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA + /// + /// This flag enables buffering of data in the kernel on a per-response basis. It should be used by an application doing synchronous I/O + /// or by an application doing asynchronous I/O with no more than one outstanding send at a time. Applications that use asynchronous I/O + /// and that may have more than one send outstanding at a time should not use this flag. When this flag is set, it should also be used + /// consistently in calls to the HttpSendResponseEntityBody function. Windows Server 2003: This flag is not supported. This flag + /// is new for Windows Server 2003 with SP1. + /// + /// + /// + /// HTTP_SEND_RESPONSE_FLAG_ENABLE_NAGLING + /// + /// Enables the TCP nagling algorithm for this send only. Windows Server 2003 with SP1 and Windows XP with SP2: This flag is not supported. + /// + /// + /// + /// HTTP_SEND_RESPONSE_FLAG_PROCESS_RANGES + /// + /// Specifies that for a range request, the full response content is passed and the caller wants the HTTP API to process ranges + /// appropriately. Windows Server 2008 R2 and Windows 7 or later. Note This flag is supported. + /// + /// + /// + /// HTTP_SEND_RESPONSE_FLAG_OPAQUE + /// + /// Specifies that the request/response is not HTTP compliant and all subsequent bytes should be treated as entity-body. Applications + /// specify this flag when it is accepting a Web Socket upgrade request and informing HTTP.sys to treat the connection data as opaque + /// data. This flag is only allowed when the StatusCode member of pHttpResponse is 101, switching protocols. + /// HttpSendHttpResponse returns ERROR_INVALID_PARAMETER for all other HTTP response types if this flag is used. Windows + /// 8 and later: This flag is supported. + /// + /// + /// + /// + /// A pointer to an HTTP_RESPONSE structure that defines the HTTP response. + /// + /// A pointer to the HTTP_CACHE_POLICY structure used to cache the response. + /// Windows Server 2003 with SP1 and Windows XP with SP2: This parameter is reserved and must be NULL. + /// + /// + /// Optional. A pointer to a variable that receives the number, in bytes, sent if the function operates synchronously. + /// + /// When making an asynchronous call using pOverlapped, set pBytesSent to NULL. Otherwise, when pOverlapped + /// is set to NULL, pBytesSent must contain a valid memory address and not be set to NULL. + /// + /// + /// This parameter is reserved and must be NULL. + /// This parameter is reserved and must be zero. + /// + /// For asynchronous calls, set pOverlapped to point to an OVERLAPPED structure; for synchronous calls, set to NULL. + /// + /// A synchronous call blocks until all response data specified in the pHttpResponse parameter is sent, whereas an asynchronous + /// call immediately returns ERROR_IO_PENDING and the calling application then uses GetOverlappedResult or I/O completion ports to + /// determine when the operation is completed. For more information about using OVERLAPPED structures for synchronization, see + /// Synchronization and Overlapped Input and Output. + /// + /// + /// + /// + /// A pointer to the HTTP_LOG_DATA structure used to log the response. Pass a pointer to the HTTP_LOG_FIELDS_DATA structure and cast it + /// to PHTTP_LOG_DATA. + /// + /// + /// Be aware that even when logging is enabled on a URL Group, or server session, the response will not be logged unless the application + /// supplies the log fields data structure. + /// + /// Windows Server 2003 and Windows XP with SP2: This parameter is reserved and must be NULL. + /// Windows Vista and Windows Server 2008: This parameter is new for Windows Vista, and Windows Server 2008 + /// + /// + /// If the function succeeds, the function returns NO_ERROR. + /// + /// If the function is used asynchronously, a return value of ERROR_IO_PENDING indicates that the next request is not yet ready + /// and is retrieved later through normal overlapped I/O completion mechanisms. + /// + /// If the function fails, it returns one of the following error codes. + /// + /// + /// Value + /// Meaning + /// + /// + /// ERROR_INVALID_PARAMETER + /// One or more of the supplied parameters is in an unusable form. + /// + /// + /// Other + /// A system error code defined in WinError.h. + /// + /// + /// + /// + /// + /// The HttpSendHttpResponse function is used to create and send a response header, and the HttpSendResponseEntityBody function + /// can be used to send entity-body data as required. + /// + /// + /// If neither a content-length header nor a transfer-encoding header is included with the response, the application must indicate the + /// end of the response by explicitly closing the connection by using the HTTP_SEND_RESPONSE_DISCONNECT flag. + /// + /// + /// If an application specifies a "Server:" header in a response, using the HttpHeaderServer identifier in the HTTP_KNOWN_HEADER + /// structure, that specified value is placed as the first part of the header, followed by a space and then "Microsoft-HTTPAPI/1.0". If + /// no server header is specified, HttpSendHttpResponse supplies "Microsoft-HTTPAPI/1.0" as the server header. + /// + /// + /// Note The HttpSendHttpResponse and HttpSendResponseEntityBody function must not be called simultaneously from different + /// threads on the same RequestId. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/http/nf-http-httpsendhttpresponse HTTPAPI_LINKAGE ULONG HttpSendHttpResponse( [in] + // HANDLE RequestQueueHandle, [in] HTTP_REQUEST_ID RequestId, [in] ULONG Flags, [in] PHTTP_RESPONSE HttpResponse, [in, optional] + // PHTTP_CACHE_POLICY CachePolicy, [out] PULONG BytesSent, [in] PVOID Reserved1, [in] ULONG Reserved2, [in] LPOVERLAPPED Overlapped, [in, + // optional] PHTTP_LOG_DATA LogData ); + [DllImport(Lib_Httpapi, SetLastError = false, ExactSpelling = true)] + [PInvokeData("http.h", MSDNShortId = "NF:http.HttpSendHttpResponse")] + public static unsafe extern Win32Error HttpSendHttpResponse([In] HREQQUEUEv1 RequestQueueHandle, [In] HTTP_REQUEST_ID RequestId, [In] HTTP_SEND_RESPONSE_FLAG Flags, + [In] IntPtr HttpResponse, [In] HTTP_CACHE_POLICY* CachePolicy, [Optional] uint* BytesSent, [In, Optional] IntPtr Reserved1, [In, Optional] uint Reserved2, + [In, Optional] NativeOverlapped* Overlapped, [In, Optional] HTTP_LOG_DATA* LogData); + /// The HttpSendResponseEntityBody function sends entity-body data associated with an HTTP response. /// /// @@ -3998,7 +4154,7 @@ public static partial class HttpApi [DllImport(Lib_Httpapi, SetLastError = false, ExactSpelling = true)] [PInvokeData("http.h", MSDNShortId = "NF:http.HttpSendResponseEntityBody")] public static extern Win32Error HttpSendResponseEntityBody([In] HREQQUEUEv1 RequestQueueHandle, [In] HTTP_REQUEST_ID RequestId, [In] HTTP_SEND_RESPONSE_FLAG Flags, - [In] ushort EntityChunkCount, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] HTTP_DATA_CHUNK[] EntityChunks, out uint BytesSent, + [In] ushort EntityChunkCount, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] HTTP_DATA_CHUNK[] EntityChunks, [Optional] IntPtr BytesSent, [In, Optional] IntPtr Reserved1, [In, Optional] uint Reserved2, in NativeOverlapped Overlapped, in HTTP_LOG_DATA LogData); /// The HttpSendResponseEntityBody function sends entity-body data associated with an HTTP response. diff --git a/PInvoke/HttpApi/http.Struct.cs b/PInvoke/HttpApi/http.Struct.cs index 0994fb3a..2418e37e 100644 --- a/PInvoke/HttpApi/http.Struct.cs +++ b/PInvoke/HttpApi/http.Struct.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using System.Collections.Generic; namespace Vanara.PInvoke; @@ -260,7 +262,7 @@ public static partial class HttpApi /// Pointer to the first question mark (?) in the string, or NULL if there is none. [MarshalAs(UnmanagedType.LPWStr)] - public string pQueryString; + public string? pQueryString; } /// Properties that can be passed down with IOCTL_HTTP_CREATE_REQUEST_QUEUE_EX. @@ -295,42 +297,29 @@ public static partial class HttpApi /// Initializes a new instance of the struct for HttpDataChunkFromMemory. /// The memory. - public HTTP_DATA_CHUNK(SafeAllocatedMemoryHandleBase mem) : this(HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory) - { - FromMemory = new(mem); - } + public HTTP_DATA_CHUNK(SafeAllocatedMemoryHandleBase mem) : this(HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory) => FromMemory = new(mem); /// Initializes a new instance of the struct for HttpDataChunkFromFileHandle. /// The file handle. /// The starting offset. /// The length. - public HTTP_DATA_CHUNK(HFILE hFile, ulong startingOffset = 0, ulong length = HTTP_BYTE_RANGE_TO_EOF) : this(HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFileHandle) - { + public HTTP_DATA_CHUNK(HFILE hFile, ulong startingOffset = 0, ulong length = HTTP_BYTE_RANGE_TO_EOF) : this(HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFileHandle) => FromFileHandle = new() { FileHandle = hFile, ByteRange = new() { StartingOffset = startingOffset, Length = length } }; - } /// Initializes a new instance of the struct for HttpDataChunkFromFragmentCache. /// Name of the fragment. - public HTTP_DATA_CHUNK(SafeLPWSTR fragmentName) : this(HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFragmentCache) - { - FromFragmentCache = new(fragmentName); - } + public HTTP_DATA_CHUNK(SafeLPWSTR fragmentName) : this(HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFragmentCache) => FromFragmentCache = new(fragmentName); /// Initializes a new instance of the struct for HttpDataChunkFromFragmentCacheEx. /// Name of the fragment. /// The starting offset. /// The length. - public HTTP_DATA_CHUNK(SafeLPWSTR fragmentName, ulong startingOffset = 0, ulong length = HTTP_BYTE_RANGE_TO_EOF) : this(HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFragmentCacheEx) - { + public HTTP_DATA_CHUNK(SafeLPWSTR fragmentName, ulong startingOffset = 0, ulong length = HTTP_BYTE_RANGE_TO_EOF) : this(HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromFragmentCacheEx) => FromFragmentCacheEx = new() { pFragmentName = fragmentName, ByteRange = new() { StartingOffset = startingOffset, Length = length } }; - } /// Initializes a new instance of the struct for HttpDataChunkTrailers. /// The headers. - public HTTP_DATA_CHUNK(SafeNativeArray headers) : this(HTTP_DATA_CHUNK_TYPE.HttpDataChunkTrailers) - { - Trailers = new() { TrailerCount = (ushort)(headers?.Count ?? 0), pTrailers = headers }; - } + public HTTP_DATA_CHUNK(SafeNativeArray headers) : this(HTTP_DATA_CHUNK_TYPE.HttpDataChunkTrailers) => Trailers = new() { TrailerCount = (ushort)headers.Count, pTrailers = headers }; /// Type of data store. This member can be one of the values from the HTTP_DATA_CHUNK_TYPE enumeration. public HTTP_DATA_CHUNK_TYPE DataChunkType; @@ -338,6 +327,7 @@ public static partial class HttpApi /// private UNION union; + /// public FROMMEMORY FromMemory { get => union.FromMemory; set => union.FromMemory = value; } /// @@ -387,7 +377,7 @@ public static partial class HttpApi /// Length, in bytes, of the data block. public uint BufferLength; - internal FROMMEMORY(SafeAllocatedMemoryHandleBase mem) { pBuffer = mem ?? default; BufferLength = mem?.Size ?? 0; } + internal FROMMEMORY(SafeAllocatedMemoryHandleBase mem) { pBuffer = mem; BufferLength = mem.Size; } } /// @@ -921,7 +911,7 @@ public static partial class HttpApi /// is NULL, the HTTP Server API logs a default string. /// [MarshalAs(UnmanagedType.LPWStr)] - public string SoftwareName; + public string? SoftwareName; /// /// The length, in bytes, of the software name. The length cannot be greater than MAX_PATH. @@ -1450,7 +1440,7 @@ public static partial class HttpApi /// An array of HTTP_UNKNOWN_HEADER structures. This array contains one structure for each of the unknown headers sent /// in the HTTP request. /// - public HTTP_UNKNOWN_HEADER[] UnknownHeaders => pUnknownHeaders.ToArray(UnknownHeaderCount); + public HTTP_UNKNOWN_HEADER[] UnknownHeaders => pUnknownHeaders.ToArray(UnknownHeaderCount) ?? new HTTP_UNKNOWN_HEADER[0]; } /// The HTTP_REQUEST_INFO structure extends the HTTP_REQUEST structure with additional information about the request. @@ -1891,7 +1881,7 @@ public static partial class HttpApi /// An array of structures that contains the data blocks making up the entity body. /// HttpReceiveHttpRequest does not copy the entity body unless called with the HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY flag set. /// - public HTTP_DATA_CHUNK[] EntityChunks => Ptr.AsRef().pEntityChunks.ToArray(Ptr.AsRef().EntityChunkCount); + public HTTP_DATA_CHUNK[] EntityChunks => Ptr.AsRef().pEntityChunks.ToArray(Ptr.AsRef().EntityChunkCount) ?? new HTTP_DATA_CHUNK[0]; /// Raw connection ID for an Secure Sockets Layer (SSL) request. public HTTP_RAW_CONNECTION_ID RawConnectionId => Ptr.AsRef().RawConnectionId; @@ -1905,7 +1895,7 @@ public static partial class HttpApi /// /// An array of structures that contains additional information about the request. /// - public HTTP_REQUEST_INFO[] RequestInfo => Ptr.AsRef().pRequestInfo.ToArray(Ptr.AsRef().RequestInfoCount); + public HTTP_REQUEST_INFO[] RequestInfo => Ptr.AsRef().pRequestInfo.ToArray(Ptr.AsRef().RequestInfoCount) ?? new HTTP_REQUEST_INFO[0]; internal SafeCoTaskMemStruct Ptr { get; private set; } } @@ -2150,7 +2140,7 @@ public static partial class HttpApi /// If NULL, the client assumes the protection space consists of all the URIs under the responding server. /// [MarshalAs(UnmanagedType.LPWStr)] - public string DomainName; + public string? DomainName; /// The length, in bytes, of the Realm member. public ushort RealmLength; @@ -2635,7 +2625,7 @@ public static partial class HttpApi /// store location. /// [MarshalAs(UnmanagedType.LPWStr)] - public string pSslCertStoreName; + public string? pSslCertStoreName; /// /// Determines how client certificates are checked. This member can be one of the following values. @@ -3126,7 +3116,7 @@ public static partial class HttpApi [MarshalAs(UnmanagedType.U1)] public bool CertDeniedByMapper; /// The actual certificate. - public byte[] CertEncoded => pCertEncoded.ToByteArray((int)CertEncodedSize); + public byte[] CertEncoded => pCertEncoded.ToByteArray((int)CertEncodedSize) ?? new byte[0]; } /// diff --git a/PInvoke/HttpApi/http.cs b/PInvoke/HttpApi/http.cs index d9cbb0fc..48c09452 100644 --- a/PInvoke/HttpApi/http.cs +++ b/PInvoke/HttpApi/http.cs @@ -1,9 +1,4 @@ -global using System; -global using System.Collections.Generic; -global using System.Runtime.InteropServices; -global using Vanara.Extensions; -global using Vanara.InteropServices; -global using static Vanara.PInvoke.Ws2_32; +global using static Vanara.PInvoke.Ws2_32; global using HTTP_SERVICE_CONFIG_SETTING_PARAM = System.UInt32; global using HTTP_CONNECTION_ID = System.UInt64; global using HTTP_OPAQUE_ID = System.UInt64; diff --git a/UnitTests/PInvoke/HttpApi/HttpApiTests.cs b/UnitTests/PInvoke/HttpApi/HttpApiTests.cs index 9eab3739..1c7fe2ef 100644 --- a/UnitTests/PInvoke/HttpApi/HttpApiTests.cs +++ b/UnitTests/PInvoke/HttpApi/HttpApiTests.cs @@ -7,7 +7,9 @@ namespace Vanara.PInvoke.Tests; [TestFixture] public class HttpApiTests { +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. SafeHttpInitialize init; +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. [OneTimeSetUp] public void _Setup()