From a08993519f7ee22696024a178e67df821eea448d Mon Sep 17 00:00:00 2001 From: noisyfox Date: Mon, 12 Dec 2016 23:53:15 +1100 Subject: [PATCH] Handle request line correctlly This coudl fix #937 --- .../Controller/Service/HttpHandler.cs | 42 +++++++++++++++++----- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/shadowsocks-csharp/Controller/Service/HttpHandler.cs b/shadowsocks-csharp/Controller/Service/HttpHandler.cs index 2f1f05b6..36804d4c 100644 --- a/shadowsocks-csharp/Controller/Service/HttpHandler.cs +++ b/shadowsocks-csharp/Controller/Service/HttpHandler.cs @@ -64,7 +64,7 @@ namespace Shadowsocks.Controller.Service Close(); } - private static readonly Regex HttpRequestHeaderRegex = new Regex(@"^([A-Z]+?) ([^\s]+) HTTP/1\.\d$"); + private static readonly Regex HttpRequestHeaderRegex = new Regex(@"^(?[A-Z]+?) (?[^\s]+) (?HTTP/1\.\d)$"); private int _requestLineCount = 0; private bool _isConnect = false; @@ -101,31 +101,57 @@ namespace Shadowsocks.Controller.Service Logging.Debug(line); - if (!line.StartsWith("Proxy-")) - { - _headers.Enqueue(line); - } - if (_requestLineCount == 0) { var m = HttpRequestHeaderRegex.Match(line); if (m.Success) { - var method = m.Groups[1].Value; + var method = m.Groups["method"].Value; + var path = m.Groups["path"].Value; if (method == "CONNECT") { _isConnect = true; - if (!ParseHost(m.Groups[2].Value)) + if (!ParseHost(path)) { throw new Exception("Bad http header: " + line); } } + else + { + var targetUrl = new Uri(path); + + if (!ParseHost(targetUrl.Authority)) + { + throw new Exception("Bad http header: " + line); + } + + var newRequestLine = $"{method} {targetUrl.PathAndQuery} {m.Groups["tail"].Value}"; + _headers.Enqueue(newRequestLine); + } + } + else + { + throw new FormatException("Not a vaild request line"); } } else { + // Handle Proxy-x Headers + + if (!line.StartsWith("Proxy-")) + { + _headers.Enqueue(line); + } + else + { + if (line.StartsWith("Proxy-Connection: ")) + { + _headers.Enqueue(line.Substring(6)); + } + } + if (line.IsNullOrEmpty()) { return true;