private void ProcessRequestInner(HttpContext context, HttpRequest request, HttpResponse response) { if (request.Path == "/null") { return; } // If session if (request.Path.Substr(0, 2) == "/(" && request.Path.Substr(24, 1) == ")") { // Find sessionId Xid sessionId; try { sessionId = new Xid(request.Path.Substr(2, 22)); } catch (FormatException) { SendJsonFailure("Amos3.Session", "Session ID paramater malformed"); return; } // Find session Session session; if (!Session.TryGet(sessionId, out session)) { SendJsonFailure("Amos3.Session.Expired", "Session has expired"); return; } // Determine if Trigger or RPC if (request.Path.CountCharacter('/') == 1) { // RPC RpcHandler(session, request.InputStream, request, response); } else { // Trigger TriggerHandler(session, request.Url.Segments[2], request, response); } return; } // Find client IP var ip = context.Request.ServerVariables["REMOTE_ADDR"]; if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; // Handle crawlers if (null != context.Request.QueryString["_escaped_fragment_"] && context.Request.QueryString["_escaped_fragment_"].Length > 1) { // Mark IP as a crawler for the next 30 seconds crawlers[ip] = DateTime.Now; context.Response.Status = "301 Moved Permanently"; context.Response.AddHeader("Location", (RequireSecureHttp ? "https://" : "http://") + context.Request.ServerVariables["SERVER_NAME"] + context.Request.QueryString["_escaped_fragment_"]); return; } if (crawlers.ContainsKey(ip) || context.Request.UserAgent.IndexOf("facebookexternalhit") != -1 || context.Request.UserAgent.IndexOf("Feedfetcher-Google") != -1 || context.Request.UserAgent.IndexOf("bingbot") != -1 || context.Request.UserAgent.IndexOf("Googlebot") != -1 || context.Request.UserAgent.IndexOf("Slurp") != -1 || context.Request.UserAgent.IndexOf("search.msn.com") != -1 || context.Request.UserAgent.IndexOf("nutch") != -1 || context.Request.UserAgent.IndexOf("simpy") != -1 || context.Request.UserAgent.IndexOf("bot") != -1 || context.Request.UserAgent.IndexOf("ASPSeek") != -1 || context.Request.UserAgent.IndexOf("crawler") != -1 || context.Request.UserAgent.IndexOf("msnbot") != -1 || context.Request.UserAgent.IndexOf("ASPSeek") != -1 || context.Request.UserAgent.IndexOf("Libwww-perl") != -1 || context.Request.UserAgent.IndexOf("FAST") != -1 || context.Request.UserAgent.IndexOf("Baidu") != -1 || context.Request.UserAgent.IndexOf("YandexBot") != -1 ) { // Add static content StaticRender(context.Request.Url.AbsolutePath.Substring(1), context); // Remove old Crawlers var limit = DateTime.Now.AddSeconds(-30); var remove = new List<string>(); foreach (var crawler in crawlers) { if (crawler.Value < limit) remove.Add(crawler.Key); } foreach (var crawlerip in remove) { crawlers.Remove(crawlerip); } return; } // If downloading document if (request.Path.ToLower().StartsWith("/downloaddocument")) { DocumentDownload.GetDocument(request); return; } // If frame if (request.Path == "/delegateframe") { // Create a new session var session = Session.Create(request, this, new EnvelopeHandlerMulti()); // Send frame DelegateFrame.SendFrame(response, session); return; } // If robots if (request.Path.ToUpperInvariant() == "/ROBOTS.TXT") { Robots(context); return; } // Check we have WAR if (null == HttpRootFile) { response.Write("No WAR."); return; } // If needed, upgrade the connection to HTTPS if (RequireSecureHttp && !request.IsSecureConnection && string.Compare(request.Url.Host, "localhost", true) != 0) { var url = request.Url.ToString(); url = "https" + url.Substr(url.IndexOf(":")); response.Redirect(url); return; } // Find target details var path = request.Path == "/" ? "/index.html" : request.Path; // Stop hacks if (path.IndexOf("..") > -1 || path.IndexOf("//") > -1 || path.IndexOf("\\\\") > -1) { response.SendFailure(HttpStatusCode.NotFound, "Denied."); } // Get content byte[] page; lock (WebCache) { // Read cache page = WebCache[path] as byte[]; // If cache miss.. if (null == page) { // Open WAR file if (null == HttpRoot) { try { HttpRoot = ZipFile.Read(HttpRootFile.FullName); } catch (Exception ex) { // Log the exception LogException(ex, "Variant-HttpRoot", Ids.System); // Warn users that we're updating response.Write("We're currently updating our content. Hang tight - the site will be back shortly!"); return; } if (null == HttpRoot["/index.html"]) { throw new Exception("Missing '/index.html' in WAR"); } } // Open file ZipEntry file; if (null == (file = HttpRoot[path])) { // File not found - redirect to virtual space response.CacheControl = "public"; response.Expires = 31536000; response.ExpiresAbsolute = DateTime.Now.AddYears(1); response.Cache.SetCacheability(HttpCacheability.Public); response.RedirectPermanent("/#!" + path, true); return; } // Extract using (var stream = new MemoryStream()) { file.Extract(stream); page = stream.ReadAllToByteArray(); } // Add to cache WebCache[path] = page; } } // Set cache headers if (path.Contains(".nocache.")) { response.CacheControl = "private"; response.Expires = 0; response.ExpiresAbsolute = DateTime.Now; response.Cache.SetCacheability(HttpCacheability.NoCache); } else if (path.Contains(".cache.")) { response.CacheControl = "public"; response.Expires = 365 * 24 * 60 * 60; response.ExpiresAbsolute = DateTime.Now.AddDays(365); response.Cache.SetCacheability(HttpCacheability.Public); } else { response.CacheControl = "private"; response.Expires = 1 * 24 * 60 * 60; response.ExpiresAbsolute = DateTime.Now.AddDays(1); response.Cache.SetCacheability(HttpCacheability.Private); } // Set content type switch (Path.GetExtension(path).ToUpperInvariant()) { case ".JS": response.ContentType = "text/javascript"; break; case ".JSON": response.ContentType = "application/json"; break; case ".CSS": response.ContentType = "text/css"; break; case ".JPG": case ".JPEG": response.ContentType = "image/jpeg"; break; case ".PNG": response.ContentType = "image/png"; break; case ".GIF": response.ContentType = "image/gif"; break; } // Set compression response.Compress(request); // Write response.OutputStream.Write(page, 0, page.Length); }