diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2017-05-24 15:12:55 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2017-05-24 15:12:55 -0400 |
| commit | f07af448fa11330db93dd7ddcabac37ef9e014c7 (patch) | |
| tree | 1b52a4f73d674a48258c2f14c94117b96ca4a678 /SocketHttpListener.Portable/Net/HttpListenerRequest.cs | |
| parent | 27c3acb2bfde9025c33f584c759a4038020cb702 (diff) | |
update main projects
Diffstat (limited to 'SocketHttpListener.Portable/Net/HttpListenerRequest.cs')
| -rw-r--r-- | SocketHttpListener.Portable/Net/HttpListenerRequest.cs | 654 |
1 files changed, 0 insertions, 654 deletions
diff --git a/SocketHttpListener.Portable/Net/HttpListenerRequest.cs b/SocketHttpListener.Portable/Net/HttpListenerRequest.cs deleted file mode 100644 index cfbd49203..000000000 --- a/SocketHttpListener.Portable/Net/HttpListenerRequest.cs +++ /dev/null @@ -1,654 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Globalization; -using System.IO; -using System.Net; -using System.Text; -using System.Threading.Tasks; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.Services; -using MediaBrowser.Model.Text; -using SocketHttpListener.Primitives; - -namespace SocketHttpListener.Net -{ - public sealed class HttpListenerRequest - { - string[] accept_types; - Encoding content_encoding; - long content_length; - bool cl_set; - CookieCollection cookies; - WebHeaderCollection headers; - string method; - Stream input_stream; - Version version; - QueryParamCollection query_string; // check if null is ok, check if read-only, check case-sensitiveness - string raw_url; - Uri url; - Uri referrer; - string[] user_languages; - HttpListenerContext context; - bool is_chunked; - bool ka_set; - bool keep_alive; - - private readonly ITextEncoding _textEncoding; - - internal HttpListenerRequest(HttpListenerContext context, ITextEncoding textEncoding) - { - this.context = context; - _textEncoding = textEncoding; - headers = new WebHeaderCollection(); - version = HttpVersion.Version10; - } - - static char[] separators = new char[] { ' ' }; - - internal void SetRequestLine(string req) - { - string[] parts = req.Split(separators, 3); - if (parts.Length != 3) - { - context.ErrorMessage = "Invalid request line (parts)."; - return; - } - - method = parts[0]; - foreach (char c in method) - { - int ic = (int)c; - - if ((ic >= 'A' && ic <= 'Z') || - (ic > 32 && c < 127 && c != '(' && c != ')' && c != '<' && - c != '<' && c != '>' && c != '@' && c != ',' && c != ';' && - c != ':' && c != '\\' && c != '"' && c != '/' && c != '[' && - c != ']' && c != '?' && c != '=' && c != '{' && c != '}')) - continue; - - context.ErrorMessage = "(Invalid verb)"; - return; - } - - raw_url = parts[1]; - if (parts[2].Length != 8 || !parts[2].StartsWith("HTTP/")) - { - context.ErrorMessage = "Invalid request line (version)."; - return; - } - - try - { - version = new Version(parts[2].Substring(5)); - if (version.Major < 1) - throw new Exception(); - } - catch - { - context.ErrorMessage = "Invalid request line (version)."; - return; - } - } - - void CreateQueryString(string query) - { - if (query == null || query.Length == 0) - { - query_string = new QueryParamCollection(); - return; - } - - query_string = new QueryParamCollection(); - if (query[0] == '?') - query = query.Substring(1); - string[] components = query.Split('&'); - foreach (string kv in components) - { - int pos = kv.IndexOf('='); - if (pos == -1) - { - query_string.Add(null, WebUtility.UrlDecode(kv)); - } - else - { - string key = WebUtility.UrlDecode(kv.Substring(0, pos)); - string val = WebUtility.UrlDecode(kv.Substring(pos + 1)); - - query_string.Add(key, val); - } - } - } - - internal void FinishInitialization() - { - string host = UserHostName; - if (version > HttpVersion.Version10 && (host == null || host.Length == 0)) - { - context.ErrorMessage = "Invalid host name"; - return; - } - - string path; - Uri raw_uri = null; - if (MaybeUri(raw_url.ToLowerInvariant()) && Uri.TryCreate(raw_url, UriKind.Absolute, out raw_uri)) - path = raw_uri.PathAndQuery; - else - path = raw_url; - - if ((host == null || host.Length == 0)) - host = UserHostAddress; - - if (raw_uri != null) - host = raw_uri.Host; - - int colon = host.LastIndexOf(':'); - if (colon >= 0) - host = host.Substring(0, colon); - - string base_uri = String.Format("{0}://{1}:{2}", - (IsSecureConnection) ? (IsWebSocketRequest ? "wss" : "https") : (IsWebSocketRequest ? "ws" : "http"), - host, LocalEndPoint.Port); - - if (!Uri.TryCreate(base_uri + path, UriKind.Absolute, out url)) - { - context.ErrorMessage = WebUtility.HtmlEncode("Invalid url: " + base_uri + path); - return; return; - } - - CreateQueryString(url.Query); - - if (version >= HttpVersion.Version11) - { - string t_encoding = Headers["Transfer-Encoding"]; - is_chunked = (t_encoding != null && String.Compare(t_encoding, "chunked", StringComparison.OrdinalIgnoreCase) == 0); - // 'identity' is not valid! - if (t_encoding != null && !is_chunked) - { - context.Connection.SendError(null, 501); - return; - } - } - - if (!is_chunked && !cl_set) - { - if (String.Compare(method, "POST", StringComparison.OrdinalIgnoreCase) == 0 || - String.Compare(method, "PUT", StringComparison.OrdinalIgnoreCase) == 0) - { - context.Connection.SendError(null, 411); - return; - } - } - - if (String.Compare(Headers["Expect"], "100-continue", StringComparison.OrdinalIgnoreCase) == 0) - { - var output = (ResponseStream)context.Connection.GetResponseStream(true); - - var _100continue = _textEncoding.GetASCIIEncoding().GetBytes("HTTP/1.1 100 Continue\r\n\r\n"); - - output.InternalWrite(_100continue, 0, _100continue.Length); - } - } - - static bool MaybeUri(string s) - { - int p = s.IndexOf(':'); - if (p == -1) - return false; - - if (p >= 10) - return false; - - return IsPredefinedScheme(s.Substring(0, p)); - } - - // - // Using a simple block of if's is twice as slow as the compiler generated - // switch statement. But using this tuned code is faster than the - // compiler generated code, with a million loops on x86-64: - // - // With "http": .10 vs .51 (first check) - // with "https": .16 vs .51 (second check) - // with "foo": .22 vs .31 (never found) - // with "mailto": .12 vs .51 (last check) - // - // - static bool IsPredefinedScheme(string scheme) - { - if (scheme == null || scheme.Length < 3) - return false; - - char c = scheme[0]; - if (c == 'h') - return (scheme == "http" || scheme == "https"); - if (c == 'f') - return (scheme == "file" || scheme == "ftp"); - - if (c == 'n') - { - c = scheme[1]; - if (c == 'e') - return (scheme == "news" || scheme == "net.pipe" || scheme == "net.tcp"); - if (scheme == "nntp") - return true; - return false; - } - if ((c == 'g' && scheme == "gopher") || (c == 'm' && scheme == "mailto")) - return true; - - return false; - } - - internal static string Unquote(String str) - { - int start = str.IndexOf('\"'); - int end = str.LastIndexOf('\"'); - if (start >= 0 && end >= 0) - str = str.Substring(start + 1, end - 1); - return str.Trim(); - } - - internal void AddHeader(string header) - { - int colon = header.IndexOf(':'); - if (colon == -1 || colon == 0) - { - context.ErrorMessage = "Bad Request"; - context.ErrorStatus = 400; - return; - } - - string name = header.Substring(0, colon).Trim(); - string val = header.Substring(colon + 1).Trim(); - string lower = name.ToLowerInvariant(); - headers.SetInternal(name, val); - switch (lower) - { - case "accept-language": - user_languages = val.Split(','); // yes, only split with a ',' - break; - case "accept": - accept_types = val.Split(','); // yes, only split with a ',' - break; - case "content-length": - try - { - //TODO: max. content_length? - content_length = Int64.Parse(val.Trim()); - if (content_length < 0) - context.ErrorMessage = "Invalid Content-Length."; - cl_set = true; - } - catch - { - context.ErrorMessage = "Invalid Content-Length."; - } - - break; - case "content-type": - { - var contents = val.Split(';'); - foreach (var content in contents) - { - var tmp = content.Trim(); - if (tmp.StartsWith("charset")) - { - var charset = tmp.GetValue("="); - if (charset != null && charset.Length > 0) - { - try - { - - // Support upnp/dlna devices - CONTENT-TYPE: text/xml ; charset="utf-8"\r\n - charset = charset.Trim('"'); - var index = charset.IndexOf('"'); - if (index != -1) charset = charset.Substring(0, index); - - content_encoding = Encoding.GetEncoding(charset); - } - catch - { - context.ErrorMessage = "Invalid Content-Type header: " + charset; - } - } - - break; - } - } - } - break; - case "referer": - try - { - referrer = new Uri(val); - } - catch - { - referrer = new Uri("http://someone.is.screwing.with.the.headers.com/"); - } - break; - case "cookie": - if (cookies == null) - cookies = new CookieCollection(); - - string[] cookieStrings = val.Split(new char[] { ',', ';' }); - Cookie current = null; - int version = 0; - foreach (string cookieString in cookieStrings) - { - string str = cookieString.Trim(); - if (str.Length == 0) - continue; - if (str.StartsWith("$Version")) - { - version = Int32.Parse(Unquote(str.Substring(str.IndexOf('=') + 1))); - } - else if (str.StartsWith("$Path")) - { - if (current != null) - current.Path = str.Substring(str.IndexOf('=') + 1).Trim(); - } - else if (str.StartsWith("$Domain")) - { - if (current != null) - current.Domain = str.Substring(str.IndexOf('=') + 1).Trim(); - } - else if (str.StartsWith("$Port")) - { - if (current != null) - current.Port = str.Substring(str.IndexOf('=') + 1).Trim(); - } - else - { - if (current != null) - { - cookies.Add(current); - } - current = new Cookie(); - int idx = str.IndexOf('='); - if (idx > 0) - { - current.Name = str.Substring(0, idx).Trim(); - current.Value = str.Substring(idx + 1).Trim(); - } - else - { - current.Name = str.Trim(); - current.Value = String.Empty; - } - current.Version = version; - } - } - if (current != null) - { - cookies.Add(current); - } - break; - } - } - - // returns true is the stream could be reused. - internal bool FlushInput() - { - if (!HasEntityBody) - return true; - - int length = 2048; - if (content_length > 0) - length = (int)Math.Min(content_length, (long)length); - - byte[] bytes = new byte[length]; - while (true) - { - // TODO: test if MS has a timeout when doing this - try - { - var task = InputStream.ReadAsync(bytes, 0, length); - var result = Task.WaitAll(new [] { task }, 1000); - if (!result) - { - return false; - } - if (task.Result <= 0) - { - return true; - } - } - catch (ObjectDisposedException e) - { - input_stream = null; - return true; - } - catch - { - return false; - } - } - } - - public string[] AcceptTypes - { - get { return accept_types; } - } - - public int ClientCertificateError - { - get - { - HttpConnection cnc = context.Connection; - //if (cnc.ClientCertificate == null) - // throw new InvalidOperationException("No client certificate"); - //int[] errors = cnc.ClientCertificateErrors; - //if (errors != null && errors.Length > 0) - // return errors[0]; - return 0; - } - } - - public Encoding ContentEncoding - { - get - { - if (content_encoding == null) - content_encoding = _textEncoding.GetDefaultEncoding(); - return content_encoding; - } - } - - public long ContentLength64 - { - get { return is_chunked ? -1 : content_length; } - } - - public string ContentType - { - get { return headers["content-type"]; } - } - - public CookieCollection Cookies - { - get - { - // TODO: check if the collection is read-only - if (cookies == null) - cookies = new CookieCollection(); - return cookies; - } - } - - public bool HasEntityBody - { - get { return (content_length > 0 || is_chunked); } - } - - public QueryParamCollection Headers - { - get { return headers; } - } - - public string HttpMethod - { - get { return method; } - } - - public Stream InputStream - { - get - { - if (input_stream == null) - { - if (is_chunked || content_length > 0) - input_stream = context.Connection.GetRequestStream(is_chunked, content_length); - else - input_stream = Stream.Null; - } - - return input_stream; - } - } - - public bool IsAuthenticated - { - get { return false; } - } - - public bool IsLocal - { - get { return RemoteEndPoint.IpAddress.Equals(IpAddressInfo.Loopback) || RemoteEndPoint.IpAddress.Equals(IpAddressInfo.IPv6Loopback) || LocalEndPoint.IpAddress.Equals(RemoteEndPoint.IpAddress); } - } - - public bool IsSecureConnection - { - get { return context.Connection.IsSecure; } - } - - public bool KeepAlive - { - get - { - if (ka_set) - return keep_alive; - - ka_set = true; - // 1. Connection header - // 2. Protocol (1.1 == keep-alive by default) - // 3. Keep-Alive header - string cnc = headers["Connection"]; - if (!String.IsNullOrEmpty(cnc)) - { - keep_alive = (0 == String.Compare(cnc, "keep-alive", StringComparison.OrdinalIgnoreCase)); - } - else if (version == HttpVersion.Version11) - { - keep_alive = true; - } - else - { - cnc = headers["keep-alive"]; - if (!String.IsNullOrEmpty(cnc)) - keep_alive = (0 != String.Compare(cnc, "closed", StringComparison.OrdinalIgnoreCase)); - } - return keep_alive; - } - } - - public IpEndPointInfo LocalEndPoint - { - get { return context.Connection.LocalEndPoint; } - } - - public Version ProtocolVersion - { - get { return version; } - } - - public QueryParamCollection QueryString - { - get { return query_string; } - } - - public string RawUrl - { - get { return raw_url; } - } - - public IpEndPointInfo RemoteEndPoint - { - get { return context.Connection.RemoteEndPoint; } - } - - public Guid RequestTraceIdentifier - { - get { return Guid.Empty; } - } - - public Uri Url - { - get { return url; } - } - - public Uri UrlReferrer - { - get { return referrer; } - } - - public string UserAgent - { - get { return headers["user-agent"]; } - } - - public string UserHostAddress - { - get { return LocalEndPoint.ToString(); } - } - - public string UserHostName - { - get { return headers["host"]; } - } - - public string[] UserLanguages - { - get { return user_languages; } - } - - public string ServiceName - { - get - { - return null; - } - } - - private bool _websocketRequestWasSet; - private bool _websocketRequest; - - /// <summary> - /// Gets a value indicating whether the request is a WebSocket connection request. - /// </summary> - /// <value> - /// <c>true</c> if the request is a WebSocket connection request; otherwise, <c>false</c>. - /// </value> - public bool IsWebSocketRequest - { - get - { - if (!_websocketRequestWasSet) - { - _websocketRequest = method == "GET" && - version > HttpVersion.Version10 && - headers.Contains("Upgrade", "websocket") && - headers.Contains("Connection", "Upgrade"); - - _websocketRequestWasSet = true; - } - - return _websocketRequest; - } - } - - public Task<ICertificate> GetClientCertificateAsync() - { - return Task.FromResult<ICertificate>(null); - } - } -} |
