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); }
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)); }
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; }
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; }
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"]; }
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; }
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"]; } }
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); }
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)); }
internal void ForRouteWithAuth(RouteMatch route, IPrincipal principal) { this.Route = route; this.Principal = principal; }
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); }
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; }
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; }
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); }