Ejemplo n.º 1
0
        internal bool ValidateRequest(NativeRequestContext requestMemory)
        {
            try
            {
                // Block potential DOS attacks
                if (requestMemory.UnknownHeaderCount > UnknownHeaderLimit)
                {
                    SendError(requestMemory.RequestId, StatusCodes.Status400BadRequest, authChallenges: null);
                    return(false);
                }

                if (!Options.Authentication.AllowAnonymous && !requestMemory.CheckAuthenticated())
                {
                    SendError(requestMemory.RequestId, StatusCodes.Status401Unauthorized,
                              AuthenticationManager.GenerateChallenges(Options.Authentication.Schemes));
                    return(false);
                }
            }
            catch (Exception ex)
            {
                Log.RequestValidationFailed(Logger, ex, requestMemory.RequestId);
                return(false);
            }

            return(true);
        }
Ejemplo n.º 2
0
        internal void AllocateNativeRequest(uint?size = null, ulong requestId = 0)
        {
            _nativeRequestContext?.ReleasePins();
            _nativeRequestContext?.Dispose();
            //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);
        }
Ejemplo n.º 3
0
        internal Request(RequestContext requestContext, NativeRequestContext nativeRequestContext)
        {
            // TODO: Verbose log
            RequestContext        = requestContext;
            _nativeRequestContext = nativeRequestContext;
            _contentBoundaryType  = BoundaryType.None;

            RequestId     = nativeRequestContext.RequestId;
            UConnectionId = nativeRequestContext.ConnectionId;
            SslStatus     = nativeRequestContext.SslStatus;

            KnownMethod = nativeRequestContext.VerbId;
            Method      = _nativeRequestContext.GetVerb();

            RawUrl = nativeRequestContext.GetRawUrl();

            var cookedUrl = nativeRequestContext.GetCookedUrl();

            QueryString = cookedUrl.GetQueryString() ?? string.Empty;

            var prefix = requestContext.Server.Options.UrlPrefixes.GetPrefix((int)nativeRequestContext.UrlContext);

            var rawUrlInBytes = _nativeRequestContext.GetRawUrlInBytes();
            var originalPath  = RequestUriBuilder.DecodeAndUnescapePath(rawUrlInBytes);

            // 'OPTIONS * HTTP/1.1'
            if (KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawUrl, "*", StringComparison.Ordinal))
            {
                PathBase = string.Empty;
                Path     = string.Empty;
            }
            // These paths are both unescaped already.
            else if (originalPath.Length == prefix.Path.Length - 1)
            {
                // They matched exactly except for the trailing slash.
                PathBase = originalPath;
                Path     = string.Empty;
            }
            else
            {
                // url: /base/path, prefix: /base/, base: /base, path: /path
                // url: /, prefix: /, base: , path: /
                PathBase = originalPath.Substring(0, prefix.Path.Length - 1);
                Path     = originalPath.Substring(prefix.Path.Length - 1);
            }

            ProtocolVersion = _nativeRequestContext.GetVersion();

            Headers = new RequestHeaders(_nativeRequestContext);

            User = _nativeRequestContext.GetUser();

            // GetTlsTokenBindingInfo(); TODO: https://github.com/aspnet/HttpSysServer/issues/231

            // Finished directly accessing the HTTP_REQUEST structure.
            _nativeRequestContext.ReleasePins();
            // TODO: Verbose log parameters
        }
Ejemplo n.º 4
0
 internal RequestContext(HttpSysListener server, NativeRequestContext memoryBlob)
 {
     // TODO: Verbose log
     Server             = server;
     _memoryBlob        = memoryBlob;
     Request            = new Request(this, _memoryBlob);
     Response           = new Response(this);
     AllowSynchronousIO = server.Options.AllowSynchronousIO;
 }
Ejemplo n.º 5
0
 internal unsafe bool ValidateAuth(NativeRequestContext requestMemory)
 {
     if (!Options.Authentication.AllowAnonymous && !requestMemory.CheckAuthenticated())
     {
         SendError(requestMemory.RequestId, StatusCodes.Status401Unauthorized,
                   AuthenticationManager.GenerateChallenges(Options.Authentication.Schemes));
         return(false);
     }
     return(true);
 }
Ejemplo n.º 6
0
 internal unsafe bool ValidateRequest(NativeRequestContext requestMemory)
 {
     // Block potential DOS attacks
     if (requestMemory.UnknownHeaderCount > UnknownHeaderLimit)
     {
         SendError(requestMemory.RequestId, StatusCodes.Status400BadRequest, authChallenges: null);
         return(false);
     }
     return(true);
 }
Ejemplo n.º 7
0
        internal Request(RequestContext requestContext, NativeRequestContext nativeRequestContext)
        {
            // TODO: Verbose log
            RequestContext        = requestContext;
            _nativeRequestContext = nativeRequestContext;
            _contentBoundaryType  = BoundaryType.None;

            RequestId     = nativeRequestContext.RequestId;
            UConnectionId = nativeRequestContext.ConnectionId;
            SslStatus     = nativeRequestContext.SslStatus;

            KnownMethod = nativeRequestContext.VerbId;
            Method      = _nativeRequestContext.GetVerb();

            RawUrl = nativeRequestContext.GetRawUrl();

            var cookedUrl = nativeRequestContext.GetCookedUrl();

            QueryString = cookedUrl.GetQueryString() ?? string.Empty;

            var rawUrlInBytes = _nativeRequestContext.GetRawUrlInBytes();
            var originalPath  = RequestUriBuilder.DecodeAndUnescapePath(rawUrlInBytes);

            // 'OPTIONS * HTTP/1.1'
            if (KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawUrl, "*", StringComparison.Ordinal))
            {
                PathBase = string.Empty;
                Path     = string.Empty;
            }
            else if (requestContext.Server.RequestQueue.Created)
            {
                var prefix = requestContext.Server.Options.UrlPrefixes.GetPrefix((int)nativeRequestContext.UrlContext);

                if (originalPath.Length == prefix.PathWithoutTrailingSlash.Length)
                {
                    // They matched exactly except for the trailing slash.
                    PathBase = originalPath;
                    Path     = string.Empty;
                }
                else
                {
                    // url: /base/path, prefix: /base/, base: /base, path: /path
                    // url: /, prefix: /, base: , path: /
                    PathBase = originalPath.Substring(0, prefix.PathWithoutTrailingSlash.Length); // Preserve the user input casing
                    Path     = originalPath.Substring(prefix.PathWithoutTrailingSlash.Length);
                }
            }
            else
            {
                // When attaching to an existing queue, the UrlContext hint may not match our configuration. Search manualy.
                if (requestContext.Server.Options.UrlPrefixes.TryMatchLongestPrefix(IsHttps, cookedUrl.GetHost(), originalPath, out var pathBase, out var path))
                {
                    PathBase = pathBase;
                    Path     = path;
                }
Ejemplo n.º 8
0
        internal Request(RequestContext requestContext, NativeRequestContext nativeRequestContext)
        {
            // TODO: Verbose log
            RequestContext        = requestContext;
            _nativeRequestContext = nativeRequestContext;
            _contentBoundaryType  = BoundaryType.None;

            RequestId     = nativeRequestContext.RequestId;
            UConnectionId = nativeRequestContext.ConnectionId;
            SslStatus     = nativeRequestContext.SslStatus;

            KnownMethod = nativeRequestContext.VerbId;
            Method      = _nativeRequestContext.GetVerb();

            RawUrl = nativeRequestContext.GetRawUrl();

            var cookedUrl = nativeRequestContext.GetCookedUrl();

            QueryString = cookedUrl.GetQueryString() ?? string.Empty;

            var rawUrlInBytes = _nativeRequestContext.GetRawUrlInBytes();
            var originalPath  = RequestUriBuilder.DecodeAndUnescapePath(rawUrlInBytes);

            PathBase = string.Empty;
            Path     = originalPath;

            // 'OPTIONS * HTTP/1.1'
            if (KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawUrl, "*", StringComparison.Ordinal))
            {
                PathBase = string.Empty;
                Path     = string.Empty;
            }
            else
            {
                var prefix = requestContext.Server.Options.UrlPrefixes.GetPrefix((int)nativeRequestContext.UrlContext);
                // Prefix may be null if the requested has been transfered to our queue
                if (!(prefix is null))
                {
                    if (originalPath.Length == prefix.PathWithoutTrailingSlash.Length)
                    {
                        // They matched exactly except for the trailing slash.
                        PathBase = originalPath;
                        Path     = string.Empty;
                    }
                    else
                    {
                        // url: /base/path, prefix: /base/, base: /base, path: /path
                        // url: /, prefix: /, base: , path: /
                        PathBase = originalPath.Substring(0, prefix.PathWithoutTrailingSlash.Length); // Preserve the user input casing
                        Path     = originalPath.Substring(prefix.PathWithoutTrailingSlash.Length);
                    }
                }
Ejemplo n.º 9
0
        internal void AllocateNativeRequest(uint?size = null, ulong requestId = 0)
        {
            _nativeRequestContext?.ReleasePins();
            _nativeRequestContext?.Dispose();

            // We can't reuse overlapped objects
            var boundHandle      = Server.RequestQueue.BoundHandle;
            var nativeOverlapped = new SafeNativeOverlapped(boundHandle,
                                                            boundHandle.AllocateNativeOverlapped(IOCallback, this, pinData: null));

            // nativeRequest
            _nativeRequestContext = new NativeRequestContext(nativeOverlapped, Server.MemoryPool, size, requestId);
        }
Ejemplo n.º 10
0
 internal RequestHeaders(NativeRequestContext requestMemoryBlob)
 {
     _requestMemoryBlob = requestMemoryBlob;
 }