Ejemplo n.º 1
0
        private void ProcessRequestCallback(IAsyncResult ar)
        {
            var context = httpListener.EndGetContext(ar);

            // Tell listener to stast the next connection simultaneously
            httpListener.BeginGetContext(ProcessRequestCallback, null);

            var request    = context.Request;
            var requestUrl = new Uri(request.Url.ToString().ToLower());

            // Check for double request
            if (requestUrl.AbsoluteUri.Contains("favicon"))
            {
                return;
            }

            if (request.HttpMethod == "OPTIONS")
            {
                context.Response.AddHeader("Access-Control-Allow-Origin", "*");
                context.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Z-Key");
                context.Response.AddHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
                context.Response.Close();
                return;
            }

            var readingResource = request.HttpMethod == "GET";
            var pathList        = requestUrl.LocalPath.Split("/").Where(s => !string.IsNullOrEmpty(s)).Take(2).ToList();

            if (pathList.Count == 2)
            {
                if (!readingResource)
                {
                    var resource = pathList[0] + "/" + pathList[1];
                    RemoveCacheByPattern("*" + resource + "*");
                    Console.Out.WriteLineAsync($"[Thread {Thread.CurrentThread.ManagedThreadId}] Removing cache for " + resource + " because of method : " + request.HttpMethod);
                }
            }
            var redisKey = requestUrl.PathAndQuery;

            if (readingResource &&
                connectionMultiplexer.GetDatabase(0).KeyExists(redisKey))
            {
                Console.Out.WriteLineAsync($"[Thread {Thread.CurrentThread.ManagedThreadId}] Returning cached request.");
                var content        = connectionMultiplexer.GetDatabase(0).StringGet(redisKey);
                var cachedResponse = JsonConvert.DeserializeObject <CachedResponse>(content);

                CopyHelper.Headers(CopyHelper.ToNameValueCollection(cachedResponse.Headers), context.Response.Headers);
                CopyHelper.Response(context.Response, cachedResponse.Body, cachedResponse.Body.Length);
            }
            else
            {
                var uri = GetRedirectUri(request);

                Console.Out.WriteLineAsync($"[Thread {Thread.CurrentThread.ManagedThreadId}] Incoming {request.HttpMethod} request for: {uri}");

                var webRequest = WebRequest.Create(uri);
                CopyHelper.RequestDetails(webRequest, request);
                CopyHelper.Headers(request.Headers, webRequest.Headers);
                CopyHelper.InputStream(webRequest, request);
                var webResponse = webRequest.GetResponse();

                var buffer = new byte[CopyHelper.BufferSize];
                var read   = webResponse.GetResponseStream().Read(buffer, 0, buffer.Length);

                CopyHelper.Headers(webResponse.Headers, context.Response.Headers);
                CopyHelper.Response(context.Response, buffer, read);

                if (readingResource)
                {
                    var serializeObject = JsonConvert.SerializeObject(new CachedResponse
                    {
                        Body    = buffer.Take(read).ToArray(),
                        Headers = CopyHelper.ToDictionary(webResponse.Headers)
                    });
                    connectionMultiplexer.GetDatabase(0).StringSet(redisKey, serializeObject);
                }
            }
        }