private static HTTP1Response DoUppgrade(HTTP1Request req) { string value = req.HeaderLines["Upgrade"]; Console.WriteLine("Client is requesting an upgrade"); if (value.Equals("h2")) { // TLS if (Server.Port != Server.HTTPS_PORT) { throw new Exception("H2 requested on a non secure stream"); // todo } Console.WriteLine("h2 requested"); return(GetResponseForUpgradeToh2()); } else if (value.Equals("h2c")) { Console.WriteLine("h2c requested"); return(GetResponseForUpgradeToh2c()); } else { Console.WriteLine("Unknown upgrade requested: " + value); return(NullRequest()); } }
internal static HTTP1Response From(HTTP1Request req) { if (req == null) { return(NullRequest()); } switch (req.Httpv) { case "HTTP/1.0": case "HTTP/1.1": if (req.IsUpgradeTo2) { return(DoUppgrade(req)); } switch (req.Type) { case "HEAD": return(GetHTTP1Response(req, true)); case "GET": return(GetHTTP1Response(req)); default: Console.WriteLine("Method not allowed: " + req.Type); return(new HTTP1Response(HTTP1V, "405 Method Not Allowed", null, new char[0])); } case "HTTP/2.0": return(null); default: Console.WriteLine("HTTP version not supported: " + req.Httpv); return(new HTTP1Response(HTTP1V, "405 Method Not Allowed", null, new char[0])); } }
private static HTTP1Response GetHTTP1Response(HTTP1Request req, bool headrequest = false) { Console.WriteLine("Responding with http/1.1..."); Dictionary <string, string> lst = new Dictionary <string, string>(); lst.Add("Server", RESPONSE_SERVER); if (headrequest) { return(new HTTP1Response(HTTP1V, RESPONSE_NO_CONTENT, lst, new char[0])); } String file = null; if (req.HttpUrl == "") { file = Path.Combine(Environment.CurrentDirectory, Server.DIR, "index.html"); } else { file = Path.Combine(Environment.CurrentDirectory, Server.DIR, req.HttpUrl); } FileInfo fi = new FileInfo(file); if (fi.Exists) { using (FileStream fs = fi.OpenRead()) { using (BinaryReader reader = new BinaryReader(fs)) { char[] d = new char[fs.Length]; reader.Read(d, 0, d.Length); lst.Add("Content-Type", Mapping.MimeMap[fi.Extension]); lst.Add("Accept-Ranges", "bytes"); lst.Add("Content-Length", d.Length.ToString()); lst.Add("Keep-Alive", "timeout=5, max=100"); lst.Add("Connection", "Keep-Alive"); return(new HTTP1Response(HTTP1V, RESPONSE_OK, lst, (headrequest)? new char[0] : d)); } } } else { Console.WriteLine("File not found" + fi.FullName); return(NotFound()); } }
private async void StartReadingAsync() { while (Connected) { try { if (!_HttpUpgraded) { await ReadStreamToString((msg) => { // a request has ben received HTTP1Request req = new HTTP1Request(msg); Console.WriteLine(req.ToString()); HTTP1Response res = HTTP1Response.From(req); Console.WriteLine(res.ToString()); Task.Run(() => WriteResponse(res)); // todo vent på preface if (req.IsUpgradeTo2) // || req.HeaderLines.Contains(new KeyValuePair<string, string>("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"))) { InitUpgradeToHttp2(); _streamHandler.SendFrame(new HTTP2Frame(0).AddSettingsPayload(new(ushort, uint)[0])); // connection preface