Exemple #1
0
        protected void FlushResponse(HttpListenerContext context, FileStream stream)
        {
            if (stream.Length > 1024
                && context.Request.Headers.AllKeys.Contains("Accept-Encoding")
                && context.Request.Headers["Accept-Encoding"].Contains("gzip"))
            {
                using (var ms = new MemoryStream())
                {
                    using (var zip = new GZipStream(ms, CompressionMode.Compress, true))
                    {
                        stream.CopyTo( zip );
                    }
                    ms.Position = 0;

                    context.Response.AddHeader("Content-Encoding", "gzip");
                    context.Response.ContentLength64 = ms.Length;
                    ms.WriteTo( context.Response.OutputStream );
                 }
            }
            else
            {
                context.Response.ContentLength64 = stream.Length;
                stream.CopyTo( context.Response.OutputStream );
            }

            context.Response.OutputStream.Close();
            context.Response.Close();
        }
 public ChunkedInputStream(HttpListenerContext context, Stream stream,
                 byte[] buffer, int offset, int length)
     : base(stream, buffer, offset, length)
 {
     this.context = context;
     WebHeaderCollection coll = (WebHeaderCollection)context.Request.Headers;
     decoder = new ChunkStream(coll);
 }
        private void InitTask(HttpListenerContext context)
        {
            try
            {
                var task = this.ProcessRequestAsync(context);
                task.ContinueWith(x => HandleError(x.Exception, context), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent);

                //if (task.Status == TaskStatus.Created)
                //{
                //    task.RunSynchronously();
                //}
            }
            catch (Exception ex)
            {
                HandleError(ex, context);
            }
        }
Exemple #4
0
        /// <summary>
        /// Finds and invokes a route to match this context. Returns true if found,
        /// false if no route matches.
        /// </summary>
        internal bool FindAndInvokeRoute(HttpListenerContext context)
        {
            RESTResource resource;
            MethodInfo route;
            Match match;
            if (! FindRoute(context, out resource, out route, out match))
                return false;

            if (route.GetParameters().Length == 2)
            {
                route.Invoke(resource, new object[] { context, match });
            }
            else
            {
                route.Invoke(resource, new object[] { context });
            }
            return true;
        }
        private Task ProcessRequestAsync(HttpListenerContext context)
        {
            var request = context.Request;

            LogHttpRequest(request);

            if (request.IsWebSocketRequest)
            {
                ProcessWebSocketRequest(context);
                return Task.FromResult(true);
            }

            if (string.IsNullOrEmpty(context.Request.RawUrl))
                return ((object)null).AsTaskResult();

            var httpReq = GetRequest(context);

            return RequestHandler(httpReq, request.Url);
        }
Exemple #6
0
        private void QueueRequest(HttpListenerContext context)
        {
            lock (this._queue)
            {
                if (_queue.Count > MaxPendingRequests)
                {
                    context.Response.StatusCode = 503;
                    context.Response.OutputStream.Close();
                    context.Response.Close();
                    EventLogger.Log(
                        String.Format( "Request queue max size reached: {0}. Connection refused with 503 error.",
                                       MaxPendingRequests ) );
                    return;
                }

                this._queue.Enqueue(context);
                this._ready.Set();
            }
        }
 internal void UnregisterContext(HttpListenerContext context)
 {
     lock (registry)
         registry.Remove(context);
 }
Exemple #8
0
        private void ProcessRequest(HttpListenerContext context)
        {
            try
            {
                if (ServerHeader != null)
                    context.Response.Headers["Server"] = ServerHeader;

                var notfound = true;
                if (this._routeCache.FindAndInvokeRoute(context))
                {
                    notfound = false;
                }
                else if ((context.Request.HttpMethod.ToUpper().Equals("GET")) && (!object.ReferenceEquals(this.WebRoot, null)))
                {
                    var filename = this.GetFilePath( context.Request.Url.LocalPath );
                    if (!object.ReferenceEquals(filename, null))
                    {
                        this.SendFileResponse(context, filename);
                        notfound = false;
                    }
                }

                if (notfound)
                {
                    this.NotFound(context);
                }
            }
            catch (Exception e)
            {
                try
                {
                    EventLogger.Log(e);
                    this.InternalServerError(context, e);
                }
                catch (Exception) // We can't even serve an error?
                {
                    context.Response.StatusCode = 500; // Maybe we can serve the code
                }
            }
            finally
            {
                context.Response.OutputStream.Close(); // prevent resource leaks
                context.Response.Close(); // paranoia
            }
        }
 internal void UnregisterContext(HttpListenerContext context)
 {
     lock (registry)
         registry.Remove(context);
 }
Exemple #10
0
        /// <summary>
        /// Respond to a request using text.
        /// 
        /// Does not set cache-control, so the response may be cached. Useful for serving simple text responses that
        /// you do not expect to change.
        /// </summary>
        protected void SendTextResponse(HttpListenerContext context, string payload, Encoding encoding = null)
        {
            encoding = (object.ReferenceEquals(encoding, null)) ? Encoding.UTF8 : encoding;

            var buffer = encoding.GetBytes(payload);
            var length = buffer.Length;

            context.Response.ContentEncoding = encoding;
            FlushResponse(context, buffer, length);
        }
        private void HandleError(Exception ex, HttpListenerContext context)
        {
            var httpReq = GetRequest(context);

            if (ErrorHandler != null)
            {
                ErrorHandler(ex, httpReq);
            }
        }
        private void ProcessWebSocketRequest(HttpListenerContext ctx)
        {
            try
            {
                var webSocketContext = ctx.AcceptWebSocket(null);

                if (WebSocketHandler != null)
                {
                    WebSocketHandler(new WebSocketConnectEventArgs
                    {
                        WebSocket = new SharpWebSocket(webSocketContext.WebSocket, _logger),
                        Endpoint = ctx.Request.RemoteEndPoint.ToString()
                    });
                }
            }
            catch (Exception ex)
            {
                _logger.ErrorException("AcceptWebSocketAsync error", ex);
                ctx.Response.StatusCode = 500;
                ctx.Response.Close();
            }
        }
        internal void RegisterContext(HttpListenerContext context)
        {
            if (OnContext != null && IsListening)
            {
                OnContext(context);
            }

            lock (registry)
                registry[context] = context;
        }
 internal HttpListenerRequest(HttpListenerContext context)
 {
     this.context = context;
     headers      = new WebHeaderCollection();
     version      = HttpVersion.Version10;
 }
        private void SendResponse(HttpListenerContext context, long? positionTicks)
        {
            var response = context.Response;

            var state = GetState();
            state.positionTicks = positionTicks ?? state.positionTicks;

            var bytes = Encoding.UTF8.GetBytes(_json.SerializeToString(state));

            response.ContentType = "application/json";
            response.ContentLength64 = bytes.Length;
            response.OutputStream.Write(bytes, 0, bytes.Length);
        }
Exemple #16
0
        //
        // todo: I don't like multiple out parameters, but I don't like special "result"
        //       data structures either. Hmm.
        //
        internal bool FindRoute(HttpListenerContext context, out RESTResource resource, out MethodInfo method, out Match match)
        {
            var httpMethod = context.Request.HttpMethod.ToUpper();
               string url = HttpUtility.UrlDecode( context.Request.Url.AbsolutePath );

               foreach (Entry route in _routes)
               {
              if (route.Match(url, httpMethod, out match))
              {
                 method = route.MethodInfo;
                 resource = route.RESTResource;
                 return true;
              }
               }

               match = null;        // out parameters must be set
               resource = null;
               method = null;
               return false;
        }
        private void ProcessRequestInternal(HttpListenerContext context, string localPath)
        {
            var command = localPath.Split('/').LastOrDefault();
            long? positionTicks = null;

            if (string.Equals(command, "config", StringComparison.OrdinalIgnoreCase))
            {
                var response = context.Response;

                var bytes = Encoding.UTF8.GetBytes(_json.SerializeToString(_player.GetConfiguration()));

                response.ContentType = "application/json";
                response.ContentLength64 = bytes.Length;
                response.OutputStream.Write(bytes, 0, bytes.Length);
                return;
            }
            if (string.Equals(command, "configsave", StringComparison.OrdinalIgnoreCase))
            {
                var config = _json.DeserializeFromStream<DirectShowPlayerConfiguration>(context.Request.InputStream);
                _player.UpdateConfiguration(config);

                var response = context.Response;

                var bytes = Encoding.UTF8.GetBytes(_json.SerializeToString(_player.GetConfiguration()));

                response.ContentType = "application/json";
                response.ContentLength64 = bytes.Length;
                response.OutputStream.Write(bytes, 0, bytes.Length);
                return;
            }
            if (string.Equals(command, "play", StringComparison.OrdinalIgnoreCase))
            {
                var playRequest = _json.DeserializeFromStream<PlayRequest>(context.Request.InputStream);

                Play(playRequest.url, playRequest.startPositionTicks ?? 0, playRequest.isVideo, playRequest.mediaSource, playRequest.item, playRequest.fullscreen);
            }
            else if (string.Equals(command, "pause", StringComparison.OrdinalIgnoreCase))
            {
                Pause();
            }
            else if (string.Equals(command, "unpause", StringComparison.OrdinalIgnoreCase))
            {
                UnPause();
            }
            else if (string.Equals(command, "stopfade", StringComparison.OrdinalIgnoreCase))
            {
                positionTicks = GetPositionTicks();
                Stop(true);
            }
            else if (string.Equals(command, "stop", StringComparison.OrdinalIgnoreCase))
            {
                positionTicks = GetPositionTicks();
                Stop(false);
            }
            else if (string.Equals(command, "mute", StringComparison.OrdinalIgnoreCase))
            {
                SetMute(true);
            }
            else if (string.Equals(command, "unmute", StringComparison.OrdinalIgnoreCase))
            {
                SetMute(false);
            }
            else if (string.Equals(command, "volume", StringComparison.OrdinalIgnoreCase))
            {
                float value;
                if (float.TryParse(context.Request.QueryString["val"], NumberStyles.Any, CultureInfo.InvariantCulture, out value))
                {
                    SetVolume(value);
                }
            }
            else if (string.Equals(command, "positionticks", StringComparison.OrdinalIgnoreCase))
            {
                long value;
                if (long.TryParse(context.Request.QueryString["val"], NumberStyles.Any, CultureInfo.InvariantCulture, out value))
                {
                    SetPositionTicks(value);
                }
            }
            else if (string.Equals(command, "setAudioStreamIndex", StringComparison.OrdinalIgnoreCase))
            {
                int value;
                if (int.TryParse(context.Request.QueryString["index"], NumberStyles.Any, CultureInfo.InvariantCulture, out value))
                {
                    _player.SetAudioStreamIndex(value);
                }
            }
            else if (string.Equals(command, "setSubtitleStreamIndex", StringComparison.OrdinalIgnoreCase))
            {
                int value;
                if (int.TryParse(context.Request.QueryString["index"], NumberStyles.Any, CultureInfo.InvariantCulture, out value))
                {
                    _player.SetSubtitleStreamIndex(value);
                }
            }

            ResetStandby();
            SendResponse(context, positionTicks);
        }
        public async Task ProcessRequest(HttpListenerContext context, string localPath)
        {
            await _requestSemaphore.WaitAsync().ConfigureAwait(false);

            try
            {
                ProcessRequestInternal(context, localPath);
            }
            finally
            {
                _requestSemaphore.Release();
            }
        }
        void Cleanup(bool close_existing)
        {
            lock (registry)
            {
                if (close_existing)
                {
                    // Need to copy this since closing will call UnregisterContext
                    ICollection keys = registry.Keys;
                    var all = new HttpListenerContext[keys.Count];
                    keys.CopyTo(all, 0);
                    registry.Clear();
                    for (int i = all.Length - 1; i >= 0; i--)
                        all[i].Connection.Close(true);
                }

                lock (connections.SyncRoot)
                {
                    ICollection keys = connections.Keys;
                    var conns = new HttpConnection[keys.Count];
                    keys.CopyTo(conns, 0);
                    connections.Clear();
                    for (int i = conns.Length - 1; i >= 0; i--)
                        conns[i].Close(true);
                }
            }
        }
        private void ProcessWebSocketRequest(HttpListenerContext ctx)
        {
            try
            {
                var endpoint = ctx.Request.RemoteEndPoint.ToString();
                var url = ctx.Request.RawUrl;
                var queryString = new NameValueCollection(ctx.Request.QueryString ?? new NameValueCollection());

                var connectingArgs = new WebSocketConnectingEventArgs
                {
                    Url = url,
                    QueryString = queryString,
                    Endpoint = endpoint
                };

                if (WebSocketConnecting != null)
                {
                    WebSocketConnecting(connectingArgs);
                }

                if (connectingArgs.AllowConnection)
                {
                    _logger.Debug("Web socket connection allowed");

                    var webSocketContext = ctx.AcceptWebSocket(null);

                    if (WebSocketConnected != null)
                    {
                        WebSocketConnected(new WebSocketConnectEventArgs
                        {
                            Url = url,
                            QueryString = queryString,
                            WebSocket = new SharpWebSocket(webSocketContext.WebSocket, _logger),
                            Endpoint = endpoint
                        });
                    }
                }
                else
                {
                    _logger.Warn("Web socket connection not allowed");
                    ctx.Response.StatusCode = 401;
                    ctx.Response.Close();
                }
            }
            catch (Exception ex)
            {
                _logger.ErrorException("AcceptWebSocketAsync error", ex);
                ctx.Response.StatusCode = 500;
                ctx.Response.Close();
            }
        }
Exemple #21
0
        /// <summary>
        /// Default response method to an Internal Server Error
        /// </summary>
        protected virtual void InternalServerError(HttpListenerContext context, string payload = "<h1>Internal Server Error</h1>", ContentType contentType = ContentType.HTML)
        {
            var buffer = Encoding.UTF8.GetBytes(payload);
            var length = buffer.Length;

            context.Response.StatusCode = 500;
            context.Response.StatusDescription = "Internal Server Error";
            context.Response.ContentType = contentType.ToValue();
            FlushResponse(context, buffer, length);
        }
        private IHttpRequest GetRequest(HttpListenerContext httpContext)
        {
            var operationName = httpContext.Request.GetOperationName();

            var req = new WebSocketSharpRequest(httpContext, operationName, RequestAttributes.None, _logger);
            req.RequestAttributes = req.GetAttributes();

            return req;
        }
Exemple #23
0
        /// <summary>
        /// Default response method when a route or file is not found. You can override this to 
        /// customize RESTServer's response. By default, the response may be cached,
        /// so this is not suitable for use in REST interfaces where a 404 response is not permanent.
        /// </summary>
        protected virtual void NotFound(HttpListenerContext context, string payload = "<h1>Not Found</h1>", ContentType contentType = ContentType.HTML)
        {
            var buffer = Encoding.UTF8.GetBytes(payload);
            var length = buffer.Length;

            context.Response.StatusCode = 404;
            context.Response.StatusDescription = "Not Found";
            context.Response.ContentType = contentType.ToValue();
            FlushResponse(context, buffer, length);
        }
 private void ProcessContext(HttpListenerContext context)
 {
     Task.Factory.StartNew(() => InitTask(context));
 }
Exemple #25
0
        /// <summary>
        /// Respond to a request with the contents of a file
        /// </summary>
        protected void SendFileResponse(HttpListenerContext context, string path)
        {
            var ext = Path.GetExtension(path).ToUpper().TrimStart('.');
            var type = (Enum.IsDefined(typeof(ContentType), ext)) ? (ContentType)Enum.Parse(typeof(ContentType), ext) : ContentType.DEFAULT;

            var lastWriteTime = File.GetLastWriteTimeUtc(path);
            var lastModified = lastWriteTime.ToString("R");
            var maxAge = (long)((DateTime.UtcNow - lastWriteTime).TotalSeconds + 86400);

            context.Response.AddHeader("Last-Modified", lastModified);
            context.Response.AddHeader("max-age", maxAge.ToString());
            context.Response.ContentType = type.ToValue();

            var ifModified = context.Request.Headers["If-Modified-Since"];
            if (null != ifModified && ifModified == lastModified)
            {
                context.Response.StatusCode = (int)HttpStatusCode.NotModified;
                context.Response.Close();
            }
            else
            {
                if (type.IsText())
                {
                    // Don't get too excited; this only detects UTF-8 and UTF-16.
                    byte [] buffer;
                    using (var reader = new StreamReader(path))
                    {
                        buffer = Encoding.UTF8.GetBytes(reader.ReadToEnd());
                    }
                    FlushResponse(context, buffer, buffer.Length);
                }
                else
                {
                    using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                    {
                        FlushResponse(context, stream);
                    }
                }
            }
        }
Exemple #26
0
 /// <summary>
 /// Default response method to an Internal Server Error
 /// </summary>
 protected virtual void InternalServerError(HttpListenerContext context, Exception e)
 {
     this.InternalServerError (context, e.ToString());
 }
 internal AuthenticationSchemes SelectAuthenticationScheme(HttpListenerContext context)
 {
     if (AuthenticationSchemeSelectorDelegate != null)
         return AuthenticationSchemeSelectorDelegate(context.Request);
     else
         return auth_schemes;
 }