| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660 | 
							- 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? _keepAlive;
 
-         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 = (HttpResponseStream)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 (!_keepAlive.HasValue)
 
-                 {
 
-                     string header = Headers["Proxy-Connection"];
 
-                     if (string.IsNullOrEmpty(header))
 
-                     {
 
-                         header = Headers["Connection"];
 
-                     }
 
-                     if (string.IsNullOrEmpty(header))
 
-                     {
 
-                         if (ProtocolVersion >= HttpVersion.Version11)
 
-                         {
 
-                             _keepAlive = true;
 
-                         }
 
-                         else
 
-                         {
 
-                             header = Headers["Keep-Alive"];
 
-                             _keepAlive = !string.IsNullOrEmpty(header);
 
-                         }
 
-                     }
 
-                     else
 
-                     {
 
-                         header = header.ToLower(CultureInfo.InvariantCulture);
 
-                         _keepAlive =
 
-                             header.IndexOf("close", StringComparison.OrdinalIgnoreCase) < 0 ||
 
-                             header.IndexOf("keep-alive", StringComparison.OrdinalIgnoreCase) >= 0;
 
-                     }
 
-                 }
 
-                 return _keepAlive.Value;
 
-             }
 
-         }
 
-         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);
 
-         }
 
-     }
 
- }
 
 
  |