Beispiel #1
0
        private RouteHandler ReadUrl(int rowEnd, out RouteMatch match)
        {
            var httpLen1 = HttpMethod.Length + 1;
            var charBuf  = TmpCharBuf;
            var end      = rowEnd - 2 - HttpProtocolVersion.Length;

            for (int x = httpLen1; x < end; x++)
            {
                var tb = InputTemp[x];
                if (tb > 250)
                {
                    RawUrl = UTF8.GetString(InputTemp, httpLen1, end - httpLen1);
                    var askSign      = RawUrl.IndexOf('?');
                    var absolutePath = askSign == -1 ? RawUrl : RawUrl.Substring(0, askSign);
                    return(Routes.Find(HttpMethod, RawUrl, absolutePath, out match));
                }
                charBuf[x - httpLen1] = (char)tb;
            }
            var route = Routes.Find(HttpMethod, charBuf, end - httpLen1, out match);

            if (route == null)
            {
                RawUrl = new string(charBuf, 0, end - httpLen1);
            }
            else
            {
                RawUrl = route.Url;
            }
            return(route);
        }
Beispiel #2
0
        internal RouteHandler Find(string httpMethod, char[] buffer, int len, out RouteMatch routeMatch)
        {
            RouteHandler handler;
            var          reqHash = StringCache.CalcHash(httpMethod, buffer, len);
            int          askSign = -1;

            for (int i = 0; i < len; i++)
            {
                if (buffer[i] == '?')
                {
                    askSign = i;
                    break;
                }
            }
            if (askSign == -1 && Cache.TryGetValue(reqHash, out handler))
            {
                if (handler.Pattern.IsStatic)
                {
                    routeMatch = handler.Pattern.ExtractMatch(handler.Url, 0);
                    return(handler);
                }
            }
            var rawUrl = new string(buffer, 0, len);

            return(FindRoute(httpMethod, rawUrl, reqHash, out routeMatch));
        }
Beispiel #3
0
 public ThreadArgs(RequestInfo request, HttpSocketContext context, ManualResetEvent resetEvent, HttpAuth.AuthorizeOrError auth, RouteHandler route, RouteMatch match)
 {
     this.Request    = request;;
     this.Context    = context;
     this.ResetEvent = resetEvent;
     this.Auth       = auth;
     this.Route      = route;
     this.Match      = match;
 }
Beispiel #4
0
 public ThreadArgs(Socket socket, HttpSocketContext context, ManualResetEventSlim resetEvent, HttpAuth.AuthorizeOrError auth, RouteHandler route, RouteMatch match)
 {
     this.Socket     = socket;
     this.Context    = context;
     this.ResetEvent = resetEvent;
     this.Auth       = auth;
     this.Route      = route;
     this.Match      = match;
 }
Beispiel #5
0
 public HttpListenerContex(
     HttpListenerRequest request,
     HttpListenerResponse response,
     RouteMatch routeMatch,
     IPrincipal principal)
 {
     this.Request = request;
     this.Response = response;
     this.RouteMatch = routeMatch;
     this.Principal = principal;
     var at = request.AcceptTypes;
     if (at != null && at.Length == 1)
         AcceptType = at[0];
     else if (at != null)
         AcceptType = request.Headers["Accept"];
 }
Beispiel #6
0
 public RouteHandler Find(HttpListenerRequest request, out RouteMatch routeMatch)
 {
     var url = request.Url;
     var rawUrl = request.RawUrl;
     var reqId = request.HttpMethod + ":" + url.AbsolutePath;
     RouteHandler handler;
     string argUrl;
     if (Cache.TryGetValue(reqId, out handler))
     {
         argUrl = rawUrl.Substring(handler.Service.Length);
         routeMatch = handler.Pattern.ExtractMatch(argUrl, url);
         return handler;
     }
     routeMatch = null;
     Dictionary<string, List<RouteHandler>> handlers;
     if (!MethodRoutes.TryGetValue(request.HttpMethod, out handlers))
         return null;
     if (request.Url.Segments.Length < 2)
         return null;
     string service;
     int pos = request.RawUrl.IndexOf('/', 1);
     if (pos == -1)
         service = rawUrl.ToLowerInvariant();
     else
         service = rawUrl.Substring(0, pos).ToLowerInvariant();
     List<RouteHandler> routes;
     if (!handlers.TryGetValue(service, out routes))
         return null;
     argUrl = rawUrl.Substring(service.Length);
     foreach (var h in routes)
     {
         var match = h.Pattern.Match(argUrl, url);
         if (match != null)
         {
             routeMatch = match;
             Cache.TryAdd(reqId, h);
             return h;
         }
     }
     return null;
 }
Beispiel #7
0
        public HttpListenerContex(
            HttpListenerRequest request,
            HttpListenerResponse response,
            RouteMatch routeMatch,
            IPrincipal principal)
        {
            this.Request    = request;
            this.Response   = response;
            this.RouteMatch = routeMatch;
            this.Principal  = principal;
            var at = request.AcceptTypes;

            if (at != null && at.Length == 1)
            {
                AcceptType = at[0];
            }
            else if (at != null)
            {
                AcceptType = request.Headers["Accept"];
            }
        }
Beispiel #8
0
        private RouteHandler FindRoute(string httpMethod, string rawUrl, int reqHash, out RouteMatch routeMatch)
        {
            routeMatch = null;
            Dictionary <string, List <RouteHandler> > handlers;

            if (!MethodRoutes.TryGetValue(httpMethod, out handlers))
            {
                return(null);
            }
            if (rawUrl.IndexOf('/') == rawUrl.LastIndexOf('/'))
            {
                return(null);
            }
            string service;
            int    pos = rawUrl.IndexOf('/', 1);

            if (pos == -1)
            {
                service = rawUrl.ToLowerInvariant();
            }
            else
            {
                service = rawUrl.Substring(0, pos).ToLowerInvariant();
            }
            List <RouteHandler> routes;

            if (!handlers.TryGetValue(service, out routes))
            {
                return(null);
            }
            foreach (var h in routes)
            {
                var match = h.Pattern.Match(rawUrl, service.Length);
                if (match != null)
                {
                    routeMatch = match;
                    var newCache = new Dictionary <int, RouteHandler>(Cache);
                    newCache[reqHash] = h;
                    Cache             = newCache;
                    return(h);
                }
            }
            return(null);
        }
Beispiel #9
0
        public RouteHandler Find(string httpMethod, string rawUrl, string absolutePath, out RouteMatch routeMatch)
        {
            var          reqHash = StringCache.CalcHash(httpMethod, absolutePath);
            RouteHandler handler;

            if (Cache.TryGetValue(reqHash, out handler))
            {
                routeMatch = handler.Pattern.ExtractMatch(rawUrl, handler.Service.Length);
                return(handler);
            }
            return(FindRoute(httpMethod, rawUrl, reqHash, out routeMatch));
        }
Beispiel #10
0
 internal void ForRouteWithAuth(RouteMatch route, IPrincipal principal)
 {
     this.Route     = route;
     this.Principal = principal;
 }
Beispiel #11
0
        public RouteHandler Find(string httpMethod, string rawUrl, string absolutePath, out RouteMatch routeMatch)
        {
            var          reqId = new ReqId(httpMethod, absolutePath);
            RouteHandler handler;

            if (Cache.TryGetValue(reqId, out handler))
            {
                routeMatch = handler.Pattern.ExtractMatch(rawUrl, handler.Service.Length);
                return(handler);
            }
            routeMatch = null;
            Dictionary <string, List <RouteHandler> > handlers;

            if (!MethodRoutes.TryGetValue(httpMethod, out handlers))
            {
                return(null);
            }
            if (rawUrl.IndexOf('/') == rawUrl.LastIndexOf('/'))
            {
                return(null);
            }
            string service;
            int    pos = rawUrl.IndexOf('/', 1);

            if (pos == -1)
            {
                service = rawUrl.ToLowerInvariant();
            }
            else
            {
                service = rawUrl.Substring(0, pos).ToLowerInvariant();
            }
            List <RouteHandler> routes;

            if (!handlers.TryGetValue(service, out routes))
            {
                return(null);
            }
            foreach (var h in routes)
            {
                var match = h.Pattern.Match(rawUrl, service.Length);
                if (match != null)
                {
                    routeMatch = match;
                    var newCache = new Dictionary <ReqId, RouteHandler>(Cache);
                    newCache[reqId] = h;
                    Cache           = newCache;
                    return(h);
                }
            }
            return(null);
        }
Beispiel #12
0
 public ThreadArgs(RequestInfo request, HttpSocketContext context, ManualResetEvent resetEvent, HttpAuth.AuthorizeOrError auth, RouteHandler route, RouteMatch match)
 {
     this.Request = request; ;
     this.Context = context;
     this.ResetEvent = resetEvent;
     this.Auth = auth;
     this.Route = route;
     this.Match = match;
 }
Beispiel #13
0
 internal void ForRouteWithAuth(RouteMatch route, IPrincipal principal)
 {
     this.Route = route;
     this.Principal = principal;
 }
Beispiel #14
0
 public bool Parse(Socket socket, out RouteMatch? match, out RouteHandler route)
 {
     positionInTmp = 0;
     Pipeline = false;
     var methodEnd = ReadUntil(socket, Space, 0);
     if (methodEnd == -1)
     {
         match = null;
         route = null;
         if (!socket.Connected)
         {
             offsetInOutput = 0;
             return false;
         }
         else if (positionInTmp == 0)
         {
             if (offsetInOutput != 0)
             {
                 socket.Send(OutputTemp, offsetInOutput, SocketFlags.None);
                 offsetInOutput = 0;
                 socket.Close();
                 return false;
             }
             else return ReturnError(socket, 408);
         }
         else return ReturnError(socket, 505);
     }
     HttpMethod = ReadMethod(methodEnd, InputTemp);
     var rowEnd = ReadUntil(socket, LF, methodEnd + 1);
     if (rowEnd == -1 || rowEnd < 12)
     {
         match = null;
         route = null;
         return ReturnError(socket, 505);
     }
     RequestHeadersLength = 0;
     ResponseHeadersLength = 0;
     HttpProtocolVersion = ReadProtocol(rowEnd - 2);
     if (HttpProtocolVersion == null)
     {
         match = null;
         route = null;
         ReturnError(socket, 505, "Only HTTP/1.1 and HTTP/1.0 supported (partially)", false);
         return false;
     }
     match = ReadUrl(rowEnd, out route);
     if (route == null)
     {
         var unknownRoute = "Unknown route " + RawUrl + " on method " + HttpMethod;
         ReturnError(socket, 404, unknownRoute, false);
         return false;
     }
     ResponseStatus = HttpStatusCode.OK;
     ResponseLength = null;
     ResponseContentType = null;
     TemplateMatch = null;
     ResponseIsJson = false;
     ContentTypeResponseIndex = -1;
     do
     {
         var start = rowEnd + 1;
         rowEnd = ReadUntil(socket, CR, start);
         if (rowEnd == start) break;
         else if (rowEnd == -1) return ReturnError(socket, 414);
         else
         {
             int i = start;
             for (; i < rowEnd; i++)
                 if (InputTemp[i] == ':')
                     break;
             if (i == rowEnd) return ReturnError(socket, 414);
             var nameBuf = TmpCharBuf;
             for (int x = start; x < i; x++)
                 nameBuf[x - start] = Lower[InputTemp[x]];
             var name = KeyCache.Get(nameBuf, i - start);
             if (InputTemp[i + 1] == 32) i++;
             for (int x = i + 1; x < rowEnd; x++)
                 nameBuf[x - i - 1] = (char)InputTemp[x];
             var value = ValueCache.Get(nameBuf, rowEnd - i - 1);
             if (RequestHeadersLength == RequestHeaders.Length)
             {
                 var newHeaders = new HeaderPair[RequestHeaders.Length * 2];
                 Array.Copy(RequestHeaders, newHeaders, RequestHeaders.Length);
                 RequestHeaders = newHeaders;
             }
             RequestHeaders[RequestHeadersLength++] = new HeaderPair(name, value);
         }
         rowEnd++;
     } while (positionInTmp <= InputTemp.Length);
     rowEnd += 2;
     if (HttpMethod == "POST" || HttpMethod == "PUT")
     {
         int len = 0;
         var ct = GetRequestHeader("content-length");
         if (ct != null)
         {
             if (!int.TryParse(ct, out len)) return ReturnError(socket, 411);
             if (len > Limit) return ReturnError(socket, 413);
         }
         else return ReturnError(socket, 411);
         InputStream.Reset();
         var size = totalBytes - rowEnd;
         InputStream.Write(InputTemp, rowEnd, size);
         len -= size;
         var oldTimeout = socket.ReceiveTimeout;
         socket.ReceiveTimeout = 10000;
         while (len > 0)
         {
             size = socket.Receive(InputTemp, Math.Min(len, InputTemp.Length), SocketFlags.None);
             if (size < 1) return ReturnError(socket, 408);
             InputStream.Write(InputTemp, 0, size);
             len -= size;
         }
         socket.ReceiveTimeout = oldTimeout;
         InputStream.Position = 0;
         rowEnd = totalBytes;
         totalBytes = 0;
     }
     else
     {
         Pipeline = rowEnd < totalBytes;
         if (Pipeline)
         {
             Buffer.BlockCopy(InputTemp, rowEnd, InputTemp, 0, totalBytes - rowEnd);
             totalBytes -= rowEnd;
         }
         else
         {
             totalBytes = 0;
         }
     }
     return true;
 }
Beispiel #15
0
        public bool Parse(Socket socket, out RouteMatch match, out RouteHandler route)
        {
            positionInTmp = 0;
            Pipeline      = false;
            var methodEnd = ReadUntil(socket, Space, 0);

            if (methodEnd == -1)
            {
                match = null;
                route = null;
                if (!socket.Connected)
                {
                    offsetInOutput = 0;
                    return(false);
                }
                else if (positionInTmp == 0)
                {
                    if (offsetInOutput != 0)
                    {
                        socket.Send(OutputTemp, offsetInOutput, SocketFlags.None);
                        offsetInOutput = 0;
                        socket.Close();
                        return(false);
                    }
                    else
                    {
                        return(ReturnError(socket, 408));
                    }
                }
                else
                {
                    return(ReturnError(socket, 505));
                }
            }
            HttpMethod = ReadMethod(methodEnd, InputTemp);
            var rowEnd = ReadUntil(socket, LF, methodEnd + 1);

            if (rowEnd == -1 || rowEnd < 12)
            {
                match = null;
                route = null;
                return(ReturnError(socket, 505));
            }
            RequestHeadersLength  = 0;
            ResponseHeadersLength = 0;
            HttpProtocolVersion   = ReadProtocol(rowEnd - 2);
            if (HttpProtocolVersion == null)
            {
                match = null;
                route = null;
                ReturnError(socket, 505, "Only HTTP/1.1 and HTTP/1.0 supported (partially)", false);
                return(false);
            }
            route = ReadUrl(rowEnd, out match);
            if (route == null)
            {
                var unknownRoute = "Unknown route " + RawUrl + " on method " + HttpMethod;
                ReturnError(socket, 404, unknownRoute, false);
                return(false);
            }
            ResponseStatus           = HttpStatusCode.OK;
            ResponseLength           = null;
            ResponseContentType      = null;
            TemplateMatch            = null;
            ResponseIsJson           = false;
            ContentTypeResponseIndex = -1;
            do
            {
                var start = rowEnd + 1;
                rowEnd = ReadUntil(socket, CR, start);
                if (rowEnd == start)
                {
                    break;
                }
                else if (rowEnd == -1)
                {
                    return(ReturnError(socket, 414));
                }
                else
                {
                    int i = start;
                    for (; i < rowEnd; i++)
                    {
                        if (InputTemp[i] == ':')
                        {
                            break;
                        }
                    }
                    if (i == rowEnd)
                    {
                        return(ReturnError(socket, 414));
                    }
                    var nameBuf = TmpCharBuf;
                    for (int x = start; x < i; x++)
                    {
                        nameBuf[x - start] = Lower[InputTemp[x]];
                    }
                    var name = KeyCache.Get(nameBuf, i - start);
                    if (InputTemp[i + 1] == 32)
                    {
                        i++;
                    }
                    for (int x = i + 1; x < rowEnd; x++)
                    {
                        nameBuf[x - i - 1] = (char)InputTemp[x];
                    }
                    var value = ValueCache.Get(nameBuf, rowEnd - i - 1);
                    if (RequestHeadersLength == RequestHeaders.Length)
                    {
                        var newHeaders = new HeaderPair[RequestHeaders.Length * 2];
                        Array.Copy(RequestHeaders, newHeaders, RequestHeaders.Length);
                        RequestHeaders = newHeaders;
                    }
                    RequestHeaders[RequestHeadersLength++] = new HeaderPair(name, value);
                }
                rowEnd++;
            } while (positionInTmp <= InputTemp.Length);
            rowEnd += 2;
            if (HttpMethod == "POST" || HttpMethod == "PUT")
            {
                int len = 0;
                var ct  = GetRequestHeader("content-length");
                if (ct != null)
                {
                    if (!int.TryParse(ct, out len))
                    {
                        return(ReturnError(socket, 411));
                    }
                    if (len > Limit)
                    {
                        return(ReturnError(socket, 413));
                    }
                }
                else
                {
                    return(ReturnError(socket, 411));
                }
                InputStream.Reset();
                var size = totalBytes - rowEnd;
                InputStream.Write(InputTemp, rowEnd, size);
                len -= size;
                while (len > 0)
                {
                    size = socket.Receive(InputTemp, Math.Min(len, InputTemp.Length), SocketFlags.None);
                    if (size < 1)
                    {
                        return(ReturnError(socket, 408));
                    }
                    InputStream.Write(InputTemp, 0, size);
                    len -= size;
                }
                InputStream.Position = 0;
                rowEnd     = totalBytes;
                totalBytes = 0;
            }
            else
            {
                Pipeline = rowEnd < totalBytes;
                if (Pipeline)
                {
                    Buffer.BlockCopy(InputTemp, rowEnd, InputTemp, 0, totalBytes - rowEnd);
                    totalBytes -= rowEnd;
                }
                else
                {
                    totalBytes = 0;
                }
            }
            return(true);
        }