public void GET(string key, RequestInfo info) { if (string.IsNullOrWhiteSpace(key)) { info.OutputError(null, System.Net.HttpStatusCode.BadRequest, "Key is missing"); return; } if (key.Equals("server-ssl-certificate", StringComparison.InvariantCultureIgnoreCase) || key.Equals("ServerSSLCertificate", StringComparison.InvariantCultureIgnoreCase)) { info.OutputOK(Program.DataConnection.ApplicationSettings.ServerSSLCertificate == null ? "False" : "True"); return; } if (key.StartsWith("--", StringComparison.Ordinal)) { var prop = Program.DataConnection.Settings.FirstOrDefault(x => string.Equals(key, x.Name, StringComparison.InvariantCultureIgnoreCase)); info.OutputOK(prop == null ? null : prop.Value); } else { var prop = typeof(Database.ServerSettings).GetProperty(key); if (prop == null) { info.OutputError(null, System.Net.HttpStatusCode.NotFound, "Not found"); } else { info.OutputOK(prop.GetValue(Program.DataConnection.ApplicationSettings)); } } }
public void PUT(string key, RequestInfo info) { if (string.IsNullOrWhiteSpace(key)) { info.OutputError(null, System.Net.HttpStatusCode.BadRequest, "Key is missing"); return; } if (key.Equals("server-ssl-certificate", StringComparison.InvariantCultureIgnoreCase) || key.Equals("ServerSSLCertificate", StringComparison.InvariantCultureIgnoreCase)) { info.OutputError(null, System.Net.HttpStatusCode.BadRequest, "Can only update SSL certificate from commandline"); return; } if (key.StartsWith("--", StringComparison.Ordinal)) { var settings = Program.DataConnection.Settings.ToList(); var prop = settings.Where(x => string.Equals(key, x.Name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); if (prop == null) { settings.Add(prop = new Database.Setting() { Name = key, Value = info.Request.Form["data"].Value }); } else { prop.Value = info.Request.Form["data"].Value; } Program.DataConnection.Settings = settings.ToArray(); info.OutputOK(prop == null ? null : prop.Value); } else { var prop = typeof(Database.ServerSettings).GetProperty(key); if (prop == null) { info.OutputError(null, System.Net.HttpStatusCode.NotFound, "Not found"); } else { var dict = new Dictionary <string, string>(); dict[key] = info.Request.Form["data"].Value; Program.DataConnection.ApplicationSettings.UpdateSettings(dict, false); info.OutputOK(); } } }
public void GET(string key, RequestInfo info) { var prop = typeof(Database.ApplicationSettings).GetProperty(key); if (prop == null) info.OutputError(null, System.Net.HttpStatusCode.NotFound, "Not found"); else info.OutputOK(prop.GetValue(Program.DataConnection.ApplicationSettings)); }
public void PUT(string key, RequestInfo info) { var prop = typeof(Database.ApplicationSettings).GetProperty(key); if (prop == null) info.OutputError(null, System.Net.HttpStatusCode.NotFound, "Not found"); else { var dict = new Dictionary<string, string>(); dict[key] = info.Request.Form["data"].Value; Program.DataConnection.ApplicationSettings.UpdateSettings(dict, false); info.OutputOK(); } }
public void GET(string key, RequestInfo info) { var prop = typeof(Database.ApplicationSettings).GetProperty(key); if (prop == null) { info.OutputError(null, System.Net.HttpStatusCode.NotFound, "Not found"); } else { info.OutputOK(prop.GetValue(Program.DataConnection.ApplicationSettings)); } }
public void GET(string key, RequestInfo info) { if (string.IsNullOrWhiteSpace(key)) { info.OutputOK( Duplicati.CommandLine.Program.SupportedCommands ); } else { ActiveRun t; if (!m_activeItems.TryGetValue(key, out t)) { info.OutputError(code: System.Net.HttpStatusCode.NotFound); return; } int pagesize; int offset; int.TryParse(info.Request.QueryString["pagesize"].Value, out pagesize); int.TryParse(info.Request.QueryString["offset"].Value, out offset); pagesize = Math.Max(10, Math.Min(500, pagesize)); offset = Math.Max(0, offset); var items = new List <string>(); long count; bool started; bool finished; lock (t.Lock) { t.LastAccess = DateTime.Now; count = t.Log.Count; offset = Math.Min((int)count, offset); items.AddRange(t.Log.Skip(offset).Take(pagesize)); finished = t.Finished; started = t.Started; } info.OutputOK(new { Pagesize = pagesize, Offset = offset, Count = count, Items = items, Finished = finished, Started = started }); } }
public void PUT(string key, RequestInfo info) { var prop = typeof(Database.ApplicationSettings).GetProperty(key); if (prop == null) { info.OutputError(null, System.Net.HttpStatusCode.NotFound, "Not found"); } else { var dict = new Dictionary <string, string>(); dict[key] = info.Request.Form["data"].Value; Program.DataConnection.ApplicationSettings.UpdateSettings(dict, false); info.OutputOK(); } }
public void DELETE(string key, RequestInfo info) { var backup = Program.DataConnection.GetBackup(key); if (backup == null) { info.ReportClientError("Invalid or missing backup id"); return; } var delete_remote_files = Library.Utility.Utility.ParseBool(info.Request.Param["delete-remote-files"].Value, false); if (delete_remote_files) { var captcha_token = info.Request.Param["captcha-token"].Value; var captcha_answer = info.Request.Param["captcha-answer"].Value; if (string.IsNullOrWhiteSpace(captcha_token) || string.IsNullOrWhiteSpace(captcha_answer)) { info.ReportClientError("Missing captcha"); return; } if (!Captcha.SolvedCaptcha(captcha_token, "DELETE /backup/" + backup.ID, captcha_answer)) { info.ReportClientError("Invalid captcha", System.Net.HttpStatusCode.Forbidden); return; } } if (Program.WorkThread.Active) { try { //TODO: It's not safe to access the values like this, //because the runner thread might interfere var nt = Program.WorkThread.CurrentTask; if (backup.Equals(nt == null ? null : nt.Backup)) { bool force; if (!bool.TryParse(info.Request.QueryString["force"].Value, out force)) { force = false; } if (!force) { info.OutputError(new { status = "failed", reason = "backup-in-progress" }); return; } bool hasPaused = Program.LiveControl.State == LiveControls.LiveControlState.Paused; Program.LiveControl.Pause(); try { for (int i = 0; i < 10; i++) { if (Program.WorkThread.Active) { var t = Program.WorkThread.CurrentTask; if (backup.Equals(t == null ? null : t.Backup)) { System.Threading.Thread.Sleep(1000); } else { break; } } else { break; } } } finally { } if (Program.WorkThread.Active) { var t = Program.WorkThread.CurrentTask; if (backup.Equals(t == null ? null : t.Backup)) { if (hasPaused) { Program.LiveControl.Resume(); } info.OutputError(new { status = "failed", reason = "backup-unstoppable" }); return; } } if (hasPaused) { Program.LiveControl.Resume(); } } } catch (Exception ex) { info.OutputError(new { status = "error", message = ex.Message }); return; } } var extra = new Dictionary <string, string>(); if (!string.IsNullOrWhiteSpace(info.Request.Param["delete-local-db"].Value)) { extra["delete-local-db"] = info.Request.Param["delete-local-db"].Value; } if (delete_remote_files) { extra["delete-remote-files"] = "true"; } var task = Runner.CreateTask(DuplicatiOperation.Delete, backup, extra); Program.WorkThread.AddTask(task); Program.StatusEventNotifyer.SignalNewEvent(); info.OutputOK(new { Status = "OK", ID = task.TaskID }); }
public void DELETE(string key, RequestInfo info) { var backup = Program.DataConnection.GetBackup(key); if (backup == null) { info.ReportClientError("Invalid or missing backup id"); return; } if (Program.WorkThread.Active) { try { //TODO: It's not safe to access the values like this, //because the runner thread might interfere var nt = Program.WorkThread.CurrentTask; if (backup.Equals(nt == null ? null : nt.Backup)) { bool force; if (!bool.TryParse(info.Request.QueryString["force"].Value, out force)) { force = false; } if (!force) { info.OutputError(new { status = "failed", reason = "backup-in-progress" }); return; } bool hasPaused = Program.LiveControl.State == LiveControls.LiveControlState.Paused; Program.LiveControl.Pause(); try { for (int i = 0; i < 10; i++) { if (Program.WorkThread.Active) { var t = Program.WorkThread.CurrentTask; if (backup.Equals(t == null ? null : t.Backup)) { System.Threading.Thread.Sleep(1000); } else { break; } } else { break; } } } finally { } if (Program.WorkThread.Active) { var t = Program.WorkThread.CurrentTask; if (backup.Equals(t == null ? null : t.Backup)) { if (hasPaused) { Program.LiveControl.Resume(); } info.OutputError(new { status = "failed", reason = "backup-unstoppable" }); return; } } if (hasPaused) { Program.LiveControl.Resume(); } } } catch (Exception ex) { info.OutputError(new { status = "error", message = ex.Message }); return; } } //var dbpath = backup.DBPath; Program.DataConnection.DeleteBackup(backup); // TODO: Before we activate this, // we need some strategy to figure out // if the db is shared with something else // like the commandline or another backup /*try * { * if (System.IO.File.Exists(dbpath)) * System.IO.File.Delete(dbpath); * } * catch (Exception ex) * { * Program.DataConnection.LogError(null, string.Format("Failed to delete database: {0}", dbpath), ex); * }*/ //We have fiddled with the schedules Program.Scheduler.Reschedule(); info.OutputOK(); }
public void POST(string key, RequestInfo info) { if (string.IsNullOrWhiteSpace(key)) { string[] args; using (var sr = new StreamReader(info.Request.Body, System.Text.Encoding.UTF8, true)) args = Newtonsoft.Json.JsonConvert.DeserializeObject <string[]>(sr.ReadToEnd()); var k = new ActiveRun(); k.Writer = new LogWriter(k); m_activeItems[k.ID] = k; StartCleanupTask(); k.Task = Runner.CreateCustomTask((sink) => { try { k.Thread = System.Threading.Thread.CurrentThread; k.Started = true; var code = Duplicati.CommandLine.Program.RunCommandLine(k.Writer, k.Writer, c => { k.Task.SetController(c); c.AppendSink(sink); }, args); k.Writer.WriteLine(string.Format("Return code: {0}", code)); } catch (Exception ex) { var rx = ex; if (rx is System.Reflection.TargetInvocationException) { rx = rx.InnerException; } if (rx is Library.Interface.UserInformationException) { k.Log.Add(rx.Message); } else { k.Log.Add(rx.ToString()); } throw rx; } finally { k.Finished = true; k.Thread = null; } }); Program.WorkThread.AddTask(k.Task); info.OutputOK(new { ID = k.ID }); } else { if (!key.EndsWith("/abort", StringComparison.OrdinalIgnoreCase)) { info.ReportClientError("Only abort commands are allowed"); return; } key = key.Substring(0, key.Length - "/abort".Length); if (string.IsNullOrWhiteSpace(key)) { info.ReportClientError("No task key found"); return; } ActiveRun t; if (!m_activeItems.TryGetValue(key, out t)) { info.OutputError(code: System.Net.HttpStatusCode.NotFound); return; } var tt = t.Task; if (tt != null) { tt.Abort(); } var tr = t.Thread; if (tr != null) { tr.Abort(); } info.OutputOK(); } }
public void DELETE(string key, RequestInfo info) { var backup = Program.DataConnection.GetBackup(key); if (backup == null) { info.ReportClientError("Invalid or missing backup id"); return; } if (Program.WorkThread.Active) { try { //TODO: It's not safe to access the values like this, //because the runner thread might interfere var nt = Program.WorkThread.CurrentTask; if (backup.Equals(nt == null ? null : nt.Backup)) { bool force; if (!bool.TryParse(info.Request.QueryString["force"].Value, out force)) force = false; if (!force) { info.OutputError(new { status = "failed", reason = "backup-in-progress" }); return; } bool hasPaused = Program.LiveControl.State == LiveControls.LiveControlState.Paused; Program.LiveControl.Pause(); try { for(int i = 0; i < 10; i++) if (Program.WorkThread.Active) { var t = Program.WorkThread.CurrentTask; if (backup.Equals(t == null ? null : t.Backup)) System.Threading.Thread.Sleep(1000); else break; } else break; } finally { } if (Program.WorkThread.Active) { var t = Program.WorkThread.CurrentTask; if (backup.Equals(t == null ? null : t.Backup)) { if (hasPaused) Program.LiveControl.Resume(); info.OutputError(new { status = "failed", reason = "backup-unstoppable" }); return; } } if (hasPaused) Program.LiveControl.Resume(); } } catch (Exception ex) { info.OutputError(new { status = "error", message = ex.Message }); return; } } //var dbpath = backup.DBPath; Program.DataConnection.DeleteBackup(backup); // TODO: Before we activate this, // we need some strategy to figure out // if the db is shared with something else // like the commandline or another backup /*try { if (System.IO.File.Exists(dbpath)) System.IO.File.Delete(dbpath); } catch (Exception ex) { Program.DataConnection.LogError(null, string.Format("Failed to delete database: {0}", dbpath), ex); }*/ //We have fiddled with the schedules Program.Scheduler.Reschedule(); info.OutputOK(); }
using Duplicati.Server.Serialization.Interface;