public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session) { string command = request.UriPath; if (command.StartsWith("/threadinfo")) { string board = request.QueryString["board"].Value; string id = request.QueryString["id"].Value; if (string.IsNullOrEmpty(board) || string.IsNullOrEmpty(id)) { response.Redirect("/wjobs"); return true; } if (Program.active_dumpers.ContainsKey(board)) { BoardWatcher bw = Program.active_dumpers[board]; int tid = 0; Int32.TryParse(id, out tid); if (bw.watched_threads.ContainsKey(tid)) { ThreadWorker tw = bw.watched_threads[tid]; StringBuilder properties = new StringBuilder(); properties.AppendFormat("<span>{0}: </span><code>{1}</code><br/>", "Thread ID", tw.ID); properties.AppendFormat("<span>{0}: </span><code>{1}</code><br/>", "Board", tw.Board.Board); properties.AppendFormat("<span>{0}: </span><code>{1}</code><br/>", "Update Interval (in min)", tw.UpdateInterval); properties.AppendFormat("<span>{0}: </span><code>{1}</code><br/>", "BumpLimit", tw.BumpLimit); properties.AppendFormat("<span>{0}: </span><code>{1}</code><br/>", "ImageLimit", tw.ImageLimit); response.Status = System.Net.HttpStatusCode.OK; response.ContentType = "text/html"; byte[] data = Encoding.UTF8.GetBytes (Properties.Resources.threadinfo_page .Replace("{properties}", properties.ToString()) .Replace("{Logs}", get_logs(tw.Logs))); response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); return true; } } response.Redirect("/wjobs"); return true; } return false; }
public static void _404(HttpServer.IHttpResponse response) { response.Status = System.Net.HttpStatusCode.NotFound; byte[] d = System.Text.Encoding.UTF8.GetBytes("404"); response.ContentLength = d.Length; response.SendHeaders(); response.SendBody(d); }
public static void write_text(string text, HttpServer.IHttpResponse response) { byte[] data = Encoding.UTF8.GetBytes(text); response.ContentType = ServerConstants.HtmlContentType; response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); }
protected void WriteFinalHtmlResponse(HttpServer.IHttpResponse response, string html) { byte[] data = Encoding.UTF8.GetBytes(html); response.Status = System.Net.HttpStatusCode.OK; response.ContentType = ServerConstants.HtmlContentType; response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); }
public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session) { string command = request.UriPath; if (command == "/settings") { StringBuilder page = new StringBuilder(Properties.Resources.settings_page); //-------------------- General Settings -------------------------- if (Settings.AutoStartManuallyAddedThreads) { page.Replace("{gs0c}", Checked); } else { page.Replace("{gs0c}", ""); } if (Settings.ThumbnailOnly) { page.Replace("{gs1c}", Checked); } else { page.Replace("{gs1c}", ""); } if (Settings.EnableFileStats) { page.Replace("{gs2c}", Checked); } else { page.Replace("{gs2c}", ""); } if (Settings.UseHttps) { page.Replace("{gs3c}", Checked); } else { page.Replace("{gs3c}", ""); } if (Settings.RemoveThreadsWhenTheyEnterArchivedState) { page.Replace("{gs4c}", Checked); } else { page.Replace("{gs4c}", ""); } if (Settings.SaveBannedFileThumbnail) { page.Replace("{gs5c}", Checked); } else { page.Replace("{gs5c}", ""); } if (Settings.CacheAPIFilesInMemory) { page.Replace("{gs6c}", Checked); } else { page.Replace("{gs6c}", ""); } //-------------------- Security Settings -------------------------- if (Settings.EnableAuthentication) { page.Replace("{ss0c}", Checked); } else { page.Replace("{ss0c}", ""); } if (Settings.AllowGuestAccess) { page.Replace("{ss1c}", Checked); } else { page.Replace("{ss1c}", ""); } page.Replace("{bauser}", string.IsNullOrEmpty(Settings.AuthUsername) ? "" : Settings.AuthUsername); page.Replace("{bapass}", string.IsNullOrEmpty(Settings.AuthPassword) ? "" : Settings.AuthPassword); //-------------------- FFMPEG Settings -------------------------- page.Replace("{ffpath}", Program.ffmpeg_path); if (Settings.ConvertGifsToWebm) { page.Replace("{ff0c}", Checked); } else { page.Replace("{ff0c}", ""); } if (Settings.ConvertWebmToMp4) { page.Replace("{ff1c}", Checked); } else { page.Replace("{ff1c}", ""); } if (Settings.Convert_Webmgif_To_Target) { page.Replace("{ff2c}", Checked); } else { page.Replace("{ff2c}", ""); } if (Settings.Convert_Webmgif_Target == Settings.X_Target.GIF) { page.Replace("{ff2s1o1c}", Selected); page.Replace("{ff2s1o2c}", ""); } else { page.Replace("{ff2s1o1c}", ""); page.Replace("{ff2s1o2c}", Selected); } if (Settings.Convert_Webmgif_only_devices) { page.Replace("{ff2s2o1c}", Selected); page.Replace("{ff2s2o2c}", ""); } else { page.Replace("{ff2s2o1c}", ""); page.Replace("{ff2s2o2c}", Selected); } //-------------------- File Queue Settings -------------------------- if (Settings.ListThumbsInQueue) { page.Replace("{fq0c}", Checked); } else { page.Replace("{fq0c}", ""); } /* if (Settings.PrioritizeBumpLimit) { page.Replace("{fq1c}", Checked); } else { page.Replace("{fq1c}", ""); } switch (Settings.FilePrioritizeMode) { case Settings.FilePrioritizeModeEnum.BoardSpeed: page.Replace("{fq2s1o1c}", ""); page.Replace("{fq2s1o2c}", ""); page.Replace("{fq2s1o3c}", Selected); break; case Settings.FilePrioritizeModeEnum.LargerFirst: page.Replace("{fq2s1o1c}", ""); page.Replace("{fq2s1o2c}", Selected); page.Replace("{fq2s1o3c}", ""); break; case Settings.FilePrioritizeModeEnum.SmallerFirst: page.Replace("{fq2s1o1c}", Selected); page.Replace("{fq2s1o2c}", ""); page.Replace("{fq2s1o3c}", ""); break; default: break; } */ if (Settings.AutoRemoveCompleteFiles) { page.Replace("{fq3c}", Checked); } else { page.Replace("{fq3c}", ""); } response.Status = System.Net.HttpStatusCode.OK; response.ContentType = "text/html"; byte[] data = Encoding.UTF8.GetBytes(page.ToString()); response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); return true; } if (command.StartsWith("/settings/")) { // -------------- General Settings ------------ Settings.AutoStartManuallyAddedThreads = request.QueryString["gs0"].Value == "1"; Settings.ThumbnailOnly = request.QueryString["gs1"].Value == "1"; Settings.EnableFileStats = request.QueryString["gs2"].Value == "1"; Settings.UseHttps = request.QueryString["gs3"].Value == "1"; Settings.RemoveThreadsWhenTheyEnterArchivedState = request.QueryString["gs4"].Value == "1"; Settings.SaveBannedFileThumbnail = request.QueryString["gs5"].Value == "1"; Settings.CacheAPIFilesInMemory = request.QueryString["gs6"].Value == "1"; if (Settings.EnableFileStats) { FileSystemStats.Init(); } // -------------- Security Settings ------------ Settings.EnableAuthentication = request.QueryString["ss0"].Value == "1"; Settings.AllowGuestAccess = request.QueryString["ss1"].Value == "1"; Settings.AuthUsername = request.QueryString["ba_user"].Value; Settings.AuthPassword = request.QueryString["ba_pass"].Value; // -------------- FFMPEG Settings ------------ Settings.ConvertGifsToWebm = request.QueryString["ff0"].Value == "1"; Settings.ConvertWebmToMp4 = request.QueryString["ff1"].Value == "1"; Settings.Convert_Webmgif_To_Target = request.QueryString["ff2"].Value == "1"; if (request.QueryString["ff2s1"].Value == "gif") { Settings.Convert_Webmgif_Target = Settings.X_Target.GIF; } else { Settings.Convert_Webmgif_Target = Settings.X_Target.MP4; } Settings.Convert_Webmgif_only_devices = request.QueryString["ff2s2"].Value == "ff2s2o1"; // -------------- File Queue Settings ------------ Settings.ListThumbsInQueue = request.QueryString["fq0"].Value == "1"; /* Settings.PrioritizeBumpLimit = request.QueryString["fq1"].Value == "1"; switch (request.QueryString["fq2s1"].Value) { case "fq2s1o1": Settings.FilePrioritizeMode = Settings.FilePrioritizeModeEnum.SmallerFirst; break; case "fq2s1o2": Settings.FilePrioritizeMode = Settings.FilePrioritizeModeEnum.LargerFirst; break; case "fq2s1o3": Settings.FilePrioritizeMode = Settings.FilePrioritizeModeEnum.BoardSpeed; break; default: Settings.FilePrioritizeMode = Settings.FilePrioritizeModeEnum.SmallerFirst; break; }*/ Settings.AutoRemoveCompleteFiles = request.QueryString["fq3"].Value == "1"; Settings.Save(); if (!Settings.EnableAuthentication) { session.Clear(); response.Cookies.Clear(); } response.Redirect("/settings"); return true; } return false; }
public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session) { string command = request.UriPath; if (command.StartsWith("/fileinfo/")) { string[] a = command.Split('/'); if (a.Length >= 3) { string filehash = a[2]; FileQueueStateInfo fqs = Program.get_file_state(filehash); if (fqs != null) { StringBuilder page = new StringBuilder(Properties.Resources.fileinfo); page.Replace("{fullfilelink}", string.Format("/file/{0}.{1}", fqs.Hash, fqs.Ext)); page.Replace("{thumbsource}", string.Format("/thumb/{0}.jpg", fqs.Hash)); page.Replace("{url}", fqs.Url); page.Replace("{p}", fqs.Percent().ToString()); page.Replace("{md5}", fqs.Hash); page.Replace("{name}", fqs.FileName); page.Replace("{workid}", filehash); page.Replace("{jtype}", fqs.Type.ToString()); page.Replace("{rcount}", fqs.RetryCount.ToString()); page.Replace("{downloaded}", Program.format_size_string(fqs.Downloaded)); page.Replace("{length}", Program.format_size_string(fqs.Length)); page.Replace("{Logs}", get_logs(fqs.Logs)); response.Status = System.Net.HttpStatusCode.OK; response.ContentType = "text/html"; byte[] data = Encoding.UTF8.GetBytes(page.ToString()); response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); return true; } else { response.Redirect("/fq"); return true; } } } return false; }
public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session) { string command = request.UriPath.ToString(); if (command.StartsWith("/file/")) { string[] e = command.Split('/').Last().Split('.'); if (e.Length != 2) return false; string hash = e[0]; string extension = e[1]; string path = FileOperations.MapFullFile(hash, extension); string ua = request.Headers["User-Agent"].ToLower(); bool no_webm = device_not_support_webm(ua); FileInfo fi = new FileInfo(path); if (fi.Exists && fi.DirectoryName.Contains(Program.file_save_dir)) { #region WebM to MP4 if (extension == "webm" && Settings.ConvertWebmToMp4) { if (File.Exists(Program.ffmpeg_path) && no_webm) { //convert the video for the user ProcessStartInfo psr = new System.Diagnostics.ProcessStartInfo(Program.ffmpeg_path); string temp_path = Path.Combine(Program.temp_files_dir, "con-" + hash + ".mp4"); File.Delete(temp_path); psr.CreateNoWindow = true; psr.UseShellExecute = false; psr.Arguments = string.Format("-y -i \"{0}\" -c:v libx264 -preset ultrafast -vf scale=320:240 -threads 2 \"{1}\"", path, temp_path); psr.RedirectStandardOutput = true; using (Process proc = System.Diagnostics.Process.Start(psr)) { proc.WaitForExit(20000); if (!proc.HasExited) { proc.Kill(); } } if (File.Exists(temp_path)) { byte[] converted_data = File.ReadAllBytes(temp_path); response.Status = System.Net.HttpStatusCode.OK; response.ContentType = "video/mpeg"; response.ContentLength = converted_data.Length; response.AddHeader("content-disposition", string.Format("inline; filename=\"{0}\"", hash + ".mp4")); response.SendHeaders(); response.SendBody(converted_data); File.Delete(temp_path); return true; } } } // webm to mp4 check #endregion response.ContentType = get_mime(extension); response.Status = System.Net.HttpStatusCode.OK; byte[] data = File.ReadAllBytes(path); response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); return true; } // probably this gif file has been converted to a webm else if (File.Exists(path + ".webm") && fi.DirectoryName.Contains(Program.file_save_dir)) { string was_gif_path = path + ".webm"; if (Settings.Convert_Webmgif_To_Target /*the general switch to gif to x*/ && (!Settings.Convert_Webmgif_only_devices || (Settings.Convert_Webmgif_only_devices && no_webm))) { if (File.Exists(Program.ffmpeg_path)) { ProcessStartInfo psr = new System.Diagnostics.ProcessStartInfo(Program.ffmpeg_path) { CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true, }; string temp_path = ""; if (Settings.Convert_Webmgif_Target == Settings.X_Target.GIF) { temp_path = Path.Combine(Program.temp_files_dir, "con-" + hash + ".gif"); psr.Arguments = string.Format("-y -i \"{0}\" -threads 2 \"{1}\"", was_gif_path, temp_path); response.ContentType = "image/gif"; } else { temp_path = Path.Combine(Program.temp_files_dir, "con-" + hash + ".mp4"); psr.Arguments = string.Format("-y -i \"{0}\" -threads 2 -c:v libx264 -preset ultrafast \"{1}\"", was_gif_path, temp_path); response.ContentType = "video/mpeg"; } File.Delete(temp_path); using (Process proc = System.Diagnostics.Process.Start(psr)) { proc.WaitForExit(20000); if (!proc.HasExited) { proc.Kill(); } } if (File.Exists(temp_path)) { byte[] converted_data = File.ReadAllBytes(temp_path); response.Status = System.Net.HttpStatusCode.OK; response.ContentLength = converted_data.Length; if (Settings.Convert_Webmgif_Target == Settings.X_Target.GIF) { response.AddHeader("content-disposition", string.Format("inline; filename=\"{0}\"", hash + ".gif")); } else { response.AddHeader("content-disposition", string.Format("inline; filename=\"{0}\"", hash + ".mp4")); } response.SendHeaders(); response.SendBody(converted_data); File.Delete(temp_path); return true; } else { goto aw; } } } // (wg --> x) aw: //other wise send it as webm response.ContentType = "video/webm"; response.Status = System.Net.HttpStatusCode.OK; byte[] data = File.ReadAllBytes(was_gif_path); response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); return true; } else { byte[] data = Properties.Resources._4; //if (Program.is_file_banned(hash)) //{ // data = Properties.Resources._b; //} response.ContentType = "image/gif"; response.Status = System.Net.HttpStatusCode.NotFound; response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); return true; } } if (command.StartsWith("/filecn/")) { string[] e = command.Split('?').First().Split('/').Last().Split('.'); if (e.Length != 2) return false; string path = FileOperations.MapFullFile(e[0], e[1]); if (File.Exists(path)) { string custom_name = request.QueryString["cn"].Value; if (!string.IsNullOrEmpty(custom_name)) { response.AddHeader("content-disposition", string.Format("attachment; filename=\"{0}\"", custom_name.Replace("\"", ""))); } response.ContentType = get_mime(command.Split('.').Last().ToLower()); response.Status = System.Net.HttpStatusCode.OK; byte[] data = File.ReadAllBytes(path); response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); } else if (File.Exists(path + ".webm")) { response.ContentType = "video/webm"; response.Status = System.Net.HttpStatusCode.OK; byte[] data = File.ReadAllBytes(path + ".webm"); response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); return true; } else { response.ContentType = "image/gif"; response.Status = System.Net.HttpStatusCode.NotFound; response.ContentLength = Properties.Resources._4.Length; response.SendHeaders(); response.SendBody(Properties.Resources._4); } return true; } if (command.StartsWith("/thumb/")) { string hash = command.Split('/').Last(); if (hash.Length == 36) { string path = Path.Combine(Program.thumb_save_dir, hash[0].ToString().ToUpper(), hash[1].ToString().ToUpper(), hash); FileInfo fi = new FileInfo(path); if (fi.Exists && fi.Name == hash) { response.ContentType = "image/jpeg"; response.Status = System.Net.HttpStatusCode.OK; response.AddHeader("cache-control", "max-age=9999"); byte[] data = File.ReadAllBytes(path); response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); return true; } } response.ContentType = "image/gif"; response.Status = System.Net.HttpStatusCode.NotFound; response.ContentLength = Properties.Resources._4.Length; response.SendHeaders(); response.SendBody(Properties.Resources._4); return true; } return false; }
public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session) { string command = request.UriPath.ToString(); if (command == "/favicon.ico") { response.Status = System.Net.HttpStatusCode.OK; response.ContentLength = Properties.Resources.favicon_ico.Length; response.ContentType = "image/x-icon"; response.SendHeaders(); response.SendBody(Properties.Resources.favicon_ico); return true; } if (command.StartsWith("/res/")) { byte[] data = null; switch (command.Split('/')[2].ToLower()) { case "bgwhite.png": data = Properties.Resources.bgwhite; response.ContentType = "image/png"; break; case "hr.png": data = Properties.Resources.hr; response.ContentType = "image/png"; break; case "locked.png": data = Properties.Resources.locked; response.ContentType = "image/png"; break; case "sticky.png": data = Properties.Resources.sticky; response.ContentType = "image/png"; break; case "bootstrap.css": //data = Encoding.UTF8.GetBytes(Properties.Resources.bootstrap_css); data = Properties.Resources.paper_theme_min; response.ContentType = "text/css"; break; case "dashboard.css": data = Encoding.UTF8.GetBytes(Properties.Resources.dashboard_css); response.ContentType = "text/css"; break; case "bootstrap.js": data = Encoding.UTF8.GetBytes(Properties.Resources.bootstrap_js); response.ContentType = "application/javascript"; break; case "jquery.js": data = Encoding.UTF8.GetBytes(Properties.Resources.jquery_js); response.ContentType = "application/javascript"; break; case "docs.js": data = Encoding.UTF8.GetBytes(Properties.Resources.docs_js); response.ContentType = "application/javascript"; break; case "css.css": data = Encoding.UTF8.GetBytes(ChanArchiver.Properties.Resources.layout); response.ContentType = "text/css"; break; case "blue.css": data = Encoding.UTF8.GetBytes(ChanArchiver.Properties.Resources.css_blue); response.ContentType = "text/css"; break; case "favicon.ico": data = Properties.Resources.favicon_ico; response.ContentType = "image/x-icon"; break; case "jquery.flot.min.js": data = Encoding.UTF8.GetBytes(Properties.Resources.jquery_flot_min); response.ContentType = "application/javascript"; break; case "jquery.flot.categories.min.js": data = Encoding.UTF8.GetBytes(Properties.Resources.jquery_flot_categories_min); response.ContentType = "application/javascript"; break; case "jquery.flot.pie.min.js": data = Properties.Resources.jquery_flot_pie_min; response.ContentType = "application/javascript"; break; case "sorttable.js": data = Properties.Resources.sorttable_js; response.ContentType = "application/javascript"; break; //webfonts case "font-awesome.min.css": data = Properties.Resources.font_awesome_min; response.ContentType = "text/css"; break; case "fontawesome-webfont.eot": data = Properties.Resources.fontawesome_webfont_eot; response.ContentType = "application/vnd.ms-fontobject"; break; case "fontawesome-webfont.svg": data = Properties.Resources.fontawesome_webfont_svg; response.ContentType = "image/svg+xml"; break; case "fontawesome-webfont.ttf": case "fontawesome-webfont.ttf?v=4.1.0": data = Properties.Resources.fontawesome_webfont_ttf; response.ContentType = "application/font-sfnt"; break; case "fontawesome-webfont.woff": case "fontawesome-webfont.woff?v=4.1.0": data = Properties.Resources.fontawesome_webfont_woff; response.ContentType = "application/font-woff"; break; case "FontAwesome.otf": data = Properties.Resources.FontAwesome_otf; response.ContentType = "application/font-sfnt"; break; case "verify.js": data = Encoding.UTF8.GetBytes(Properties.Resources.verify_notify_min); response.ContentType = "application/javascript"; break; default: break; } if (data == null) { ThreadServerModule._404(response); } else { response.Status = System.Net.HttpStatusCode.OK; response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); } } return false; }
public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session) { string command = request.UriPath.ToString(); ; if (command.StartsWith("/filetree")) { int selector_index = -1; string file_type = request.QueryString["ftype"].Value; if (!string.IsNullOrEmpty(file_type)) { Int32.TryParse(file_type, out selector_index); } int limit = 250; string limit_user = request.QueryString["limit"].Value; if (!string.IsNullOrEmpty(limit_user)) { Int32.TryParse(request.QueryString["limit"].Value, out limit); } StringBuilder sb = new StringBuilder(); string filter = "blank"; string prev_value = request.QueryString["prev_value"].Value; string next_value = ""; if (!(selector_index < 0 || selector_index > 4)) { switch (selector_index) { case 0: case 1: filter = "*.webm"; break; case 2: filter = "*.jpg"; break; case 3: filter = "*.png"; break; case 4: filter = "*.gif"; break; default: break; } var fc = Selectors[selector_index]; int counter = 0; bool has_reached_next_page = false; has_reached_next_page = string.IsNullOrEmpty(prev_value); foreach (string path in FileOperations.EnumerateOptimizedDirectory(Program.file_save_dir)) { string filename = System.IO.Path.GetFileName(path); if (has_reached_next_page) { if (counter > limit) { next_value = filename; break; } if (fc(filename)) { string file_name_without_extension = System.IO.Path.GetFileNameWithoutExtension(filename); string ext = System.IO.Path.GetExtension(filename); sb.AppendFormat("<a href=\"/file/{0}{1}\"><img src=\"/thumb/{0}.jpg\" /></a><br />", file_name_without_extension, ext); counter++; } } else { has_reached_next_page = prev_value == filename; } } } StringBuilder page = new StringBuilder(Properties.Resources.file_list_page); for (int i = 0; i < 4; i++) { if (i == selector_index) { page.Replace("{o" + i.ToString() + "}", "selected='selected'"); } else { page.Replace("{o" + i.ToString() + "}", ""); } } page//.Replace("{prev}", prev_value) .Replace("{next}", next_value) .Replace("{ftvalue}", filter) .Replace("{lvalue}", limit.ToString()) .Replace("{items}", sb.ToString()); response.Status = System.Net.HttpStatusCode.OK; response.ContentType = "text/html"; byte[] data = Encoding.UTF8.GetBytes(page.ToString()); response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); return true; } return false; }
public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session) { if (request.UriPath.StartsWith(Url)) { string board = request.QueryString[UrlParameters.Board].Value; string threadIdStr = request.QueryString[UrlParameters.ThreadId].Value; int threadId = -1; int.TryParse(threadIdStr, out threadId); if (!Program.IsBoardLetterValid(board)) { ThreadServerModule.write_text("Invalid board letter", response); return true; } if (threadId <= 0) { ThreadServerModule.write_text("Invalid thread id", response); return true; } PostFormatter[] thread_data = ThreadStore.GetStorageEngine().GetThread(board, threadIdStr); MemoryStream memIO = new MemoryStream(); ZipOutputStream zipStream = new ZipOutputStream(memIO); zipStream.SetLevel(0); // no compression is needed since most of the files are media files, and they are already compressed anyway write_file_to_zip(zipStream, "res/blue.css", Encoding.UTF8.GetBytes(Properties.Resources.css_blue)); write_file_to_zip(zipStream, "res/sticky.png", Properties.Resources.sticky); write_file_to_zip(zipStream, "res/locked.png", Properties.Resources.locked); foreach (PostFormatter pf in thread_data) { if (pf.MyFile != null) { string full_path; if (FileOperations.ResolveFullFilePath(pf.MyFile.Hash, pf.MyFile.Extension, out full_path)) { string ext = Path.GetExtension(full_path); if (!string.IsNullOrEmpty(ext)) { ext = ext.Substring(1); } if (ext != pf.MyFile.Extension) { pf.MyFile.ChangeExtension(ext); } string zip_file_name = string.Format("file/{0}.{1}", pf.MyFile.Hash, ext); byte[] data = File.ReadAllBytes(full_path); pf.MyFile.Size = data.Length; write_file_to_zip(zipStream, zip_file_name, data); } string thumb_path; if (FileOperations.CheckThumbFileExist(pf.MyFile.Hash, out thumb_path)) { string zip_file_name = string.Format("thumb/{0}.jpg", pf.MyFile.Hash); write_file_to_zip(zipStream, zip_file_name, File.ReadAllBytes(thumb_path)); } } } string notes = ThreadStore.GetStorageEngine().GetThreadNotes(board, threadId); string pageHtml = build_page_html(board, threadIdStr, thread_data, notes); write_file_to_zip(zipStream, "index.html", Encoding.UTF8.GetBytes(pageHtml)); zipStream.Close(); memIO.Close(); byte[] result = memIO.ToArray(); response.Status = System.Net.HttpStatusCode.OK; response.ContentType = ServerConstants.ZipContentType; response.ContentLength = result.Length; response.AddHeader("content-disposition", string.Format("attachment; filename=\"{0}.zip\"", threadId)); response.SendHeaders(); response.SendBody(result); return true; } return false; }
public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session) { string command = request.UriPath.ToString(); if (command.StartsWith("/logs/")) { string[] a = command.Split('/'); if (a.Length >= 3) { string mode = a[2]; string id = a[3]; LogEntry[] data = null; switch (mode) { case "file": FileQueueStateInfo st = Program.get_file_state(id); if (st != null) { data = st.Logs; } break; case "threadworker": // /logs/threadworker/board/tid if (Program.active_dumpers.ContainsKey(id)) { BoardWatcher bw = Program.active_dumpers[id]; if (bw.watched_threads.ContainsKey(Convert.ToInt32(a[4]))) { data = bw.watched_threads[Convert.ToInt32(a[4])].Logs; } } break; case "boardwatcher": if (Program.active_dumpers.ContainsKey(id)) { BoardWatcher bw = Program.active_dumpers[id]; data = bw.Logs; } break; default: break; } if (data != null) { StringBuilder items = new StringBuilder(); for (int index = 0; index < data.Length; index++) { try { LogEntry e = data[index]; items.Append("<tr>"); switch (e.Level) { case LogEntry.LogLevel.Fail: items.Append("<td><span class=\"label label-danger\">Fail</span></td>"); break; case LogEntry.LogLevel.Info: items.Append("<td><span class=\"label label-info\">Info</span></td>"); break; case LogEntry.LogLevel.Success: items.Append("<td><span class=\"label label-success\">Success</span></td>"); break; case LogEntry.LogLevel.Warning: items.Append("<td><span class=\"label label-warning\">Warning</span></td>"); break; default: items.Append("<td><span class=\"label label-default\">Unknown</span></td>"); break; } items.AppendFormat("<td>{0}</td>", e.Time); items.AppendFormat("<td>{0}</td>", e.Title); items.AppendFormat("<td>{0}</td>", e.Sender); items.AppendFormat("<td>{0}</td>", e.Message); items.Append("</tr>"); } catch (Exception) { continue; } } //write everything response.Status = System.Net.HttpStatusCode.OK; response.ContentType = "text/html"; byte[] fdata = Encoding.UTF8.GetBytes(Properties.Resources.logs_page.Replace("{Logs}", items.ToString())); response.ContentLength = fdata.Length; response.SendHeaders(); response.SendBody(fdata); return true; } else { //404 return false; } } } return false; }
public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session) { string command = request.UriPath.ToString(); #region Thread & Index View if (command.StartsWith("/boards/")) { response.Encoding = System.Text.Encoding.UTF8; string[] parame = command.Split('?')[0].Split('/'); if (parame.Length == 3) { //board index view mode string board = parame[2]; if (string.IsNullOrEmpty(board)) { response.Redirect("/boards"); return true; } ThreadStore.GetStorageEngine().UpdateThreadStoreStats(); int board_thread_count = ThreadStore.GetStorageEngine().StoreStats[board]; if (board_thread_count == 0) { response.Redirect("/boards"); return true; } int rem = (board_thread_count % ThreadPerPage); int page_count = ((board_thread_count - rem) / ThreadPerPage) + (rem > 0 ? 1 : 0); if (page_count <= 0) { page_count = 1; } int page_offset = 0; Int32.TryParse(request.QueryString["pn"].Value, out page_offset); page_offset = Math.Abs(page_offset); int start = page_offset * (ThreadPerPage); PostFormatter[] board_index = ThreadStore.GetStorageEngine().GetIndex(board, start, ThreadPerPage); StringBuilder s = new StringBuilder(); foreach (var pf in board_index) { s.Append("<div class='row'>"); s.Append ( pf.ToString() .Replace("{post:link}", string.Format("/boards/{0}/{1}", board, pf.PostID)) ); s.Append("</div>"); } StringBuilder page_numbers = new StringBuilder(); for (int i = 0; i < page_count; i++) { if (i == page_offset) { page_numbers.AppendFormat("<li class=\"active\"><a href=\"?pn={0}\">{1}</a></li>", i, i + 1); } else { page_numbers.AppendFormat("<li><a href=\"?pn={0}\">{1}</a></li>", i, i + 1); } } byte[] data = Encoding.UTF8.GetBytes( Properties.Resources.board_index_page .Replace("{po}", Convert.ToString(page_offset == 0 ? 0 : page_offset - 1)) .Replace("{no}", Convert.ToString(page_offset == page_count - 1 ? page_count : page_offset + 1)) .Replace("{pagen}", page_numbers.ToString()) .Replace("{Items}", s.ToString())); response.ContentType = ServerConstants.HtmlContentType; response.Encoding = Encoding.UTF8; response.Status = System.Net.HttpStatusCode.OK; response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); return true; } else if (parame.Length >= 4) { //thread view mode string board = parame[2]; string threadid = parame[3]; int parsedThreadId = -1; int.TryParse(threadid, out parsedThreadId); if (string.IsNullOrEmpty(board) || string.IsNullOrEmpty(threadid)) { _404(response); return true; } if (parsedThreadId <= 0) { _404(response); return true; } StringBuilder pageHtml = new StringBuilder(Properties.Resources.page_template); StringBuilder body = new StringBuilder(); { PostFormatter[] thread_data = ThreadStore.GetStorageEngine().GetThread(board, threadid); if (thread_data.Length == 0) { _404(response); return true; } body.Append(thread_data[0]); body.Replace("{post:link}", string.Format("#p{0}", thread_data[0].PostID)); for (int i = 1; i < thread_data.Length; i++) { body.Append(thread_data[i]); } } string thread_notes = ThreadStore.GetStorageEngine().GetThreadNotes(board, parsedThreadId); thread_notes = System.Web.HttpUtility.HtmlEncode(thread_notes); pageHtml.Replace("{board-title}", string.Format("[ChanArchiver] - /{0}/ Thread No. {1}", board, threadid)); pageHtml.Replace("{board-letter}", board); pageHtml.Replace("{thread-id}", threadid); pageHtml.Replace("{{notes}}", thread_notes); pageHtml.Replace("{thread-posts}", body.ToString()); byte[] content = Encoding.UTF8.GetBytes(pageHtml.ToString()); response.ContentType = ServerConstants.HtmlContentType; response.ContentLength = content.Length; response.Encoding = Encoding.UTF8; response.SendHeaders(); response.SendBody(content); return true; } } if (command.StartsWith("/getfilelist?")) { string board = request.QueryString["board"].Value; string threadid = request.QueryString["thread"].Value; if (string.IsNullOrEmpty(board) || string.IsNullOrEmpty(threadid)) { _404(response); } PostFormatter[] thread_data = ThreadStore.GetStorageEngine().GetThread(board, threadid); if (thread_data.Length == 0) { _404(response); return true; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < thread_data.Length; i++) { PostFormatter pf = thread_data[i]; if (pf.MyFile != null) { string url_name = System.Web.HttpUtility.UrlEncodeUnicode(pf.MyFile.FileName); string url = string.Format("/filecn/{0}.{1}?cn={2}", pf.MyFile.Hash, pf.MyFile.Extension, url_name); sb.AppendFormat("<a href='{0}'>{1}</a><br/>", url, pf.MyFile.FileName); } } byte[] data = Encoding.UTF8.GetBytes(sb.ToString()); response.ContentType = ServerConstants.HtmlContentType; response.ContentLength = data.Length; response.Encoding = Encoding.UTF8; response.SendHeaders(); response.SendBody(data); return true; } if (command.StartsWith("/deletethread/?")) { lock (delete_thread_lock) { string board = request.QueryString["board"].Value; string threadid = request.QueryString["thread"].Value; if (string.IsNullOrEmpty(board) || string.IsNullOrEmpty(threadid)) { _404(response); } PostFormatter[] thread_data = ThreadStore.GetThread(board, threadid); //delete the files foreach (var post in thread_data) { if (post.MyFile != null) { var state = FileIndex.GetIndexState(post.MyFile.Hash); if (state != null) { if (state.RepostCount == 1) { string path = FileOperations.MapFullFile(post.MyFile.Hash, post.MyFile.Extension); if (File.Exists(path)) { File.Delete(path); } else if (File.Exists(path + ".webm")) { File.Exists(path + ".webm"); } path = FileOperations.MapThumbFile(post.MyFile.Hash); File.Delete(path); FileIndex.RemovePost(post.MyFile.Hash, post.PostID); } } } } //delete the thread ThreadStore.GetStorageEngine().DeleteThread(board, threadid); response.Redirect("/boards/" + board); return true; } } if (command == "/boards" || command == "/boards/") { if (Directory.Exists(Program.post_files_dir)) { StringBuilder s = new StringBuilder(); foreach (string folder_path in Directory.EnumerateDirectories(Program.post_files_dir)) { string folder_name = Path.GetFileName(folder_path); s.Append("<div class=\"col-6 col-sm-6 col-lg-4\">"); s.AppendFormat("<h2>/{0}/</h2>", folder_name); s.AppendFormat("<p>Thread Count: {0}</p>", ThreadStore.StoreStats[folder_name]); s.AppendFormat("<p><a class=\"btn btn-default\" href=\"/boards/{0}\" role=\"button\">browse ยป</a></p>", folder_name); s.Append("</div>"); } byte[] data = Encoding.UTF8.GetBytes(Properties.Resources.archivedboard_page.Replace("{Items}", s.ToString())); response.Encoding = System.Text.Encoding.UTF8; response.ContentType = "text/html; charset=utf-8"; response.Status = System.Net.HttpStatusCode.OK; response.ContentLength = data.Length; response.SendHeaders(); response.SendBody(data); } else { response.Redirect("/"); } return true; } #endregion #region File Queue Actions if (command.StartsWith("/set/maxfilequeue/")) { if (string.IsNullOrEmpty(request.QueryString["count"].Value)) { response.Redirect("/fq"); } else { int t = Program.file_stp.MaxThreads; Int32.TryParse(request.QueryString["count"].Value, out t); if (t != Program.file_stp.MaxThreads) { if (t > Program.file_stp.MinThreads) { Program.file_stp.MaxThreads = t; } } response.Redirect("/fq"); } return true; } if (command == "/action/removecompletefiles") { List<string> hashes_to_remove = new List<string>(); for (int index = 0; index < Program.queued_files.Count(); index++) { try { FileQueueStateInfo f = Program.queued_files.ElementAt(index).Value; if (f.Status == FileQueueStateInfo.DownloadStatus.Complete) { hashes_to_remove.Add(Program.queued_files.ElementAt(index).Key); } } catch (Exception) { if (index > Program.queued_files.Count()) { break; } } } foreach (string s in hashes_to_remove) { Program.queued_files.Remove(s); } response.Redirect("/fq"); return true; } if (command == "/action/removefailedfiles") { List<string> hashes_to_remove = new List<string>(); for (int index = 0; index < Program.queued_files.Count(); index++) { try { FileQueueStateInfo f = Program.queued_files.ElementAt(index).Value; if (f.Status == FileQueueStateInfo.DownloadStatus.Error || f.Status == FileQueueStateInfo.DownloadStatus.NotFound) { hashes_to_remove.Add(Program.queued_files.ElementAt(index).Key); } } catch (Exception) { if (index > Program.queued_files.Count()) { break; } } } foreach (string s in hashes_to_remove) { Program.queued_files.Remove(s); } response.Redirect("/fq"); return true; } if (command == "/action/restartfailedfiles") { List<KeyValuePair<string, FileQueueStateInfo>> files_to_restart = new List<KeyValuePair<string, FileQueueStateInfo>>(); for (int index = 0; index < Program.queued_files.Count(); index++) { try { FileQueueStateInfo f = Program.queued_files.ElementAt(index).Value; if (f.Status == FileQueueStateInfo.DownloadStatus.Error) { files_to_restart.Add(Program.queued_files.ElementAt(index)); } } catch (Exception) { if (index > Program.queued_files.Count()) { break; } } } foreach (KeyValuePair<string, FileQueueStateInfo> s in files_to_restart) { Program.queued_files.Remove(s.Key); Program.dump_files(s.Value.PostFile, s.Value.IsThumbOnly); } response.Redirect("/fq"); return true; } #endregion #region Watch Jobs Actions if (command.StartsWith("/add/")) { string[] rdata = command.Split('/'); string mode = rdata[2].ToLower(); if (mode == "board") { if (string.IsNullOrEmpty(request.QueryString["boardletter"].Value)) { _404(response); } string board = request.QueryString["boardletter"].Value; string mon_type = request.QueryString["montype"].Value; BoardWatcher.BoardMode m = BoardWatcher.BoardMode.None; if (mon_type == "part") { m = BoardWatcher.BoardMode.Monitor; } if (mon_type == "full") { m = BoardWatcher.BoardMode.FullBoard; } if (mon_type == "harvest") { m = BoardWatcher.BoardMode.Harvester; } Program.archive_board(board, m); response.Status = System.Net.HttpStatusCode.OK; response.Redirect("/monboards"); } else if (mode == "thread") { if (string.IsNullOrEmpty(request.QueryString["urlorformat"].Value)) { _404(response); } string input = request.QueryString["urlorformat"].Value; bool thumbOnly = request.QueryString["to"].Value == "1"; string board = ""; int id = -1; if (input.ToLower().StartsWith("http")) { //http://boards.4chan.org/g/res/39075359 string temp = input.ToLower().Replace("https://", "").Replace("http://", ""); //boards.4chan.org/g/res/int // 0 1 2 3 string[] data = temp.Split('/'); if (data.Length >= 4) { board = data[1]; Int32.TryParse(data[3].Split('#')[0], out id); } } else { string[] data = input.Split(':'); if (data.Length >= 2) { board = data[0]; Int32.TryParse(data[1], out id); } } if (id > 0 & !string.IsNullOrEmpty(board)) { Program.archive_single(board, id, thumbOnly); response.Status = System.Net.HttpStatusCode.OK; response.Redirect("/wjobs"); } else { _404(response); } } else if (mode == "threadfromarchive") { try { string ai_index_str = request.QueryString["ai_index"].Value; string board = request.QueryString["board"].Value; string threadid_str = request.QueryString["threadid"].Value; if (!string.IsNullOrEmpty(ai_index_str) && !string.IsNullOrEmpty(board) && !string.IsNullOrEmpty(threadid_str)) { int ai_index = -1; int tid = -1; if (int.TryParse(ai_index_str, out ai_index) && int.TryParse(threadid_str, out tid)) { ArchiveInfo info = ArchivesProvider.GetAllArchives().ElementAt(ai_index); var status = ArchivedThreadAdder.AddThreadFromArchive(board, tid, false, info); if (status != AddThreadFromArchiveStatus.Success) { write_text("Unable to add thread, reason: " + status.ToString(), response); return true; } else { response.Redirect("/wjobs"); return true; } } } } catch (FormatException) { write_text("Unable to add thread, reason: Invalid thread id", response); return true; } catch (IndexOutOfRangeException) { write_text("Unable to add thread, reason: Invalid archvie info index", response); return true; } write_text("Unable to add thread, reason: possible malformed parameters", response); return true; } else { _404(response); } return true; } if (command.StartsWith("/cancel/")) { string[] data = command.Split('/'); string mode = data[2]; if (mode == "bw") { string board = data[3]; if (Program.active_dumpers.ContainsKey(board)) { BoardWatcher bw = Program.active_dumpers[board]; bw.StopMonitoring(); response.Redirect("/monboards"); } } if (mode == "bwr") { string board = data[3]; if (Program.active_dumpers.ContainsKey(board)) { BoardWatcher bw = Program.active_dumpers[board]; bw.StartMonitoring(BoardWatcher.BoardMode.FullBoard); response.Redirect("/monboards"); } } if (mode == "tw") { string board = data[3]; string tid = data[4]; if (Program.active_dumpers.ContainsKey(board)) { BoardWatcher bw = Program.active_dumpers[board]; int id = Convert.ToInt32(tid); if (bw.watched_threads.ContainsKey(id)) { ThreadWorker tw = bw.watched_threads[id]; tw.Stop(); response.Redirect("/wjobs"); } } } if (mode == "twr") { string board = data[3]; string tid = data[4]; if (Program.active_dumpers.ContainsKey(board)) { BoardWatcher bw = Program.active_dumpers[board]; int id = Convert.ToInt32(tid); if (bw.watched_threads.ContainsKey(id)) { ThreadWorker tw = bw.watched_threads[id]; tw.Start(); response.Redirect("/wjobs"); } } } return true; } if (command.StartsWith("/action/removethreadworker/")) { string board = request.QueryString["board"].Value; string tid = request.QueryString["id"].Value; if (Program.active_dumpers.ContainsKey(board)) { BoardWatcher bw = Program.active_dumpers[board]; int id = -1; Int32.TryParse(tid, out id); if (bw.watched_threads.ContainsKey(id)) { ThreadWorker tw = bw.watched_threads[id]; tw.Stop(); bw.watched_threads.Remove(id); } } response.Redirect("/wjobs"); return true; } #endregion #region File Actions if (command.StartsWith("/action/restartfile/")) { string workid = command.Split('/').Last(); FileQueueStateInfo f = Program.get_file_state(workid); if (f != null) { f.ForceStop = true; Program.queued_files.Remove(workid); Program.dump_files(f.PostFile, f.IsThumbOnly); response.Redirect("/fileinfo/" + workid); } else { response.Redirect("/fq"); } return true; } if (command.StartsWith("/action/stopandbanfile/")) { string workid = command.Split('/').Last(); FileQueueStateInfo f = Program.get_file_state(workid); if (f != null) { f.ForceStop = true; Program.ban_file(f.Hash); f.Log(new LogEntry() { Level = LogEntry.LogLevel.Success, Message = "File was banned", Sender = "-", Title = "" }); // Program.queued_files.Remove(workid); response.Redirect("/fileinfo/" + workid); } else { response.Redirect("/fq"); } return true; } if (command.StartsWith("/action/banfile")) { string hash = request.QueryString["hash"].Value; if (!string.IsNullOrEmpty(hash)) { Program.ban_file(hash); } string referrer = request.Headers["referer"]; if (!string.IsNullOrEmpty(referrer)) { response.Redirect(referrer); } return true; } if (command.StartsWith("/action/showfilereposts")) { string hash = request.QueryString["hash"].Value; if (!string.IsNullOrWhiteSpace(hash)) { FileIndexInfo info = FileIndex.GetIndexState(hash); if (info != null) { StringBuilder sb = new StringBuilder(); var rposts = info.GetRepostsData(); for (int i = 0; i < rposts.Length; i++) { sb.Append("<tr>"); sb.AppendFormat("<td>{0}</td>", rposts[i].FileName); sb.AppendFormat("<td><a href='/boards/{0}'></a>{0}</td>", rposts[i].Board); sb.AppendFormat("<td><code><a href='/boards/{0}/{1}'>{1}</a></code></td>", rposts[i].Board, rposts[i].ThreadID); sb.AppendFormat("<td><code><a href='/boards/{0}/{1}#p{2}'>{2}</a></code></td>", rposts[i].Board, rposts[i].ThreadID, rposts[i].PostID); sb.Append("</tr>"); } write_text(Properties.Resources.file_reposts_page .Replace("{thumbsource}", string.Format("/thumb/{0}.jpg", hash)) .Replace("{md5}", hash) .Replace("{rinfo}", sb.ToString()), response); return true; } } else { _404(response); return true; } return true; } if (command.StartsWith("/action/removefile/")) { string workid = command.Split('/').Last(); FileQueueStateInfo f = Program.get_file_state(workid); if (f != null) { Program.queued_files.Remove(workid); response.Redirect("/fq"); } else { response.Redirect("/fq"); } return true; } if (command.StartsWith("/action/resetfileretrycount/")) { string workid = command.Split('/').Last(); FileQueueStateInfo f = Program.get_file_state(workid); if (f != null) { f.RetryCount = 0; response.Redirect("/fileinfo/" + workid); } else { response.Redirect("/fq"); } return true; } if (command.StartsWith("/action/forcestopfile/")) { string workid = command.Split('/').Last(); FileQueueStateInfo f = Program.get_file_state(workid); if (f != null) { f.ForceStop = true; response.Redirect("/fileinfo/" + workid); } else { response.Redirect("/fq"); } return true; } if (command.StartsWith("/action/forcestopfile_thread/")) { string workid = command.Split('/').Last(); FileQueueStateInfo f = Program.get_file_state(workid); if (f != null) { f.ThreadBG.Cancel(true); response.Redirect("/fileinfo/" + workid); } else { response.Redirect("/fq"); } return true; } if (command.StartsWith("/action/unbanfile")) { string hash = request.QueryString["hash"].Value; Program.unban_file(hash); response.Redirect("/bannedfiles"); return true; } #endregion if (command == "/ua") { string ua = request.Headers["User-Agent"].ToLower(); write_text(string.Format("Your user agent: {0}<br/>Device support WebM: {1}", ua, !ChanArchiver.HttpServerHandlers.FileHandler.device_not_support_webm(ua)), response); return true; } if (command == "/ua/t") { string ua = request.Headers["User-Agent"].ToLower(); if (!Program.uas_always_mp4.Contains(ua)) { Program.uas_always_mp4.Add(ua); write_text("added to mp4 list", response); return true; } else { Program.uas_always_mp4.Remove(ua); write_text("removed from mp4 list", response); return true; } } if (command.StartsWith("/get_archive_info/")) { string board = request.QueryString["b"].Value; StringBuilder sb = new StringBuilder(); var data = ArchivesProvider.GetArchivesForBoard(board, true); sb.AppendFormat("Result count: {0}<br/>", data.Count()); foreach (var d in data) { sb.AppendFormat("HOST: {0} <br/>", d.Domain); } write_text(sb.ToString(), response); return true; } return false; }