private void Cleanup() { _regWatcher?.Stop(); _tcpListener?.Stop(); _udpServer?.Close(); JsonImageCache.Save(); }
private void RegEventHandler(object sender, EventArrivedEventArgs e) { using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\GaRyan2\epg123", false)) { if (key != null) { var regToken = (string)key.GetValue("token", ""); if (regToken != TokenService.Token) { Helper.WriteLogEntry($"New token detected in registry. token={regToken}"); TokenService.Token = regToken; TokenService.GoodToken = true; JsonImageCache.Save(); // seems like a good time to save } var regRefresh = (int)key.GetValue("autoRefreshToken", 0) > 0; if (regRefresh != TokenService.RefreshToken) { Helper.WriteLogEntry($"Auto token refresh setting changed. autoRefreshToken={regRefresh}"); TokenService.RefreshToken = regRefresh; } var regCache = (int)key.GetValue("cacheImages", 0) > 0; if (regCache != JsonImageCache.cacheImages) { Helper.WriteLogEntry($"Cache images setting changed. cacheImages={regCache}"); JsonImageCache.cacheImages = regCache; } var regCacheRetent = (int)key.GetValue("cacheRetention", 30); if (regCacheRetent != JsonImageCache.cacheRetention) { Helper.WriteLogEntry($"Cache retention setting changed. cacheRetention={regCacheRetent}"); JsonImageCache.cacheRetention = regCacheRetent; } } else { Helper.WriteLogEntry("Registry key no longer exists. Stopping watcher."); _regWatcher.Stop(); } } }
private void ProcessImageRequest(Stream stream, string asset, DateTime ifModifiedSince, bool retry = false) { // update web stats if (ifModifiedSince == DateTime.MinValue) { WebStats.IncrementRequestReceived(); } else { WebStats.IncrementConditionalRequestReceived(); } // throttle refreshing images that have already been checked recently if (JsonImageCache.cacheImages && JsonImageCache.IsImageRecent(asset.Substring(7), ifModifiedSince)) { if (Send304OrImageFromCache(stream, ifModifiedSince, JsonImageCache.GetCachedImage(asset))) { return; } } // build url for Schedules Direct with token var url = $"{Helper.SdBaseName}{asset}"; if (!string.IsNullOrEmpty(TokenService.Token)) { url += $"?token={TokenService.Token}"; } // create web request var request = (HttpWebRequest)WebRequest.Create(url); // add if-modified-since as needed var fileInfo = JsonImageCache.cacheImages ? JsonImageCache.GetCachedImage(asset) : null; if (ifModifiedSince != DateTime.MinValue || fileInfo != null) { request.IfModifiedSince = new[] { ifModifiedSince.ToUniversalTime(), fileInfo?.LastWriteTimeUtc ?? DateTime.MinValue }.Max(); } try { // update web stats if (request.IfModifiedSince == DateTime.MinValue) { WebStats.IncrementRequestSent(); } else { WebStats.IncrementConditionalRequestSent(); } // get response using (var response = request.GetResponseWithoutException() as HttpWebResponse) using (var memStream = new MemoryStream()) { response.GetResponseStream().CopyTo(memStream); memStream.Position = 0; // if image is included if (memStream.Length > 0 && response.ContentType.StartsWith("image")) { // update web stats WebStats.AddSdDownload(memStream.Length); // success implies limit has not been exceeded lock (_limitLock) { _limitExceeded = WebStats.LimitLocked = false; } // send response to client var message = $"HTTP/1.1 {(int) response.StatusCode} {response.StatusDescription}\r\n"; for (var i = 0; i < response.Headers.Count; ++i) { message += $"{response.Headers.Keys[i]}: {response.Headers[i]}\r\n"; } var messageBytes = Encoding.UTF8.GetBytes($"{message}\r\n"); stream.Write(messageBytes, 0, messageBytes.Length); memStream.CopyTo(stream); if (!JsonImageCache.cacheImages) { return; } // save image to cache if enabled memStream.Position = 0; var filename = asset.Substring(7); var dirInfo = Directory.CreateDirectory($"{Helper.Epg123ImageCache}\\{filename.Substring(0, 1)}"); var location = $"{dirInfo.FullName}\\{filename}"; using (var fStream = new FileStream(location, FileMode.Create, FileAccess.Write)) { memStream.CopyTo(fStream); fStream.Flush(); } File.SetLastWriteTimeUtc(location, response.LastModified); JsonImageCache.AddImageToCache(filename, response.LastModified); return; } // handle any 304 or 404 responses by providing either a 304 response or the cached image if available if (Send304OrImageFromCache(stream, ifModifiedSince, fileInfo)) { return; } // reject a 200 response that has no content if (response.StatusCode == HttpStatusCode.OK && memStream.Length == 0) { WebStats.Increment502Response(); var message = "HTTP/1.1 502 Bad Gateway\r\n" + $"Date: {DateTime.UtcNow:R}\r\n"; var messageBytes = Encoding.UTF8.GetBytes($"{message}\r\n"); stream.Write(messageBytes, 0, messageBytes.Length); return; } // handle any errors from SD HandleRequestError(stream, asset, response, ifModifiedSince, memStream, retry); // 200 for exceeded image limit or unknown user return; } } catch (WebException e) { Helper.WriteLogEntry($"{asset}\nWebException: {e.Status} - {e.Message}"); } // fallback for failed connection if (Send304OrImageFromCache(stream, ifModifiedSince, fileInfo)) { return; } // nothing to give the client WebStats.Increment404Response(); var messageBytes2 = Encoding.UTF8.GetBytes($"HTTP/1.1 404 Not Found\r\nDate: {DateTime.UtcNow:R}\r\n\r\n"); stream.Write(messageBytes2, 0, messageBytes2.Length); }