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);
 }
Example #4
0
 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;
        }
Example #7
0
        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;
        }
Example #11
0
        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;
        }