API rewrite to parse JSON body for POST and DELETE

This commit is contained in:
Dity 2024-04-07 18:20:28 -04:00
parent 7628510b87
commit 6f5fb7e0bb

View File

@ -102,6 +102,22 @@ public class Server : GlobalBase
return ret;
}
private Dictionary<string, string> GetRequestBody(HttpListenerRequest request)
{
if (!request.HasEntityBody)
{
Log("No request body");
Dictionary<string, string> emptyBody = new();
return emptyBody;
}
Stream body = request.InputStream;
Encoding encoding = request.ContentEncoding;
StreamReader reader = new StreamReader(body, encoding);
string s = reader.ReadToEnd();
Dictionary<string, string> requestBody = JsonConvert.DeserializeObject<Dictionary<string, string>>(s);
return requestBody;
}
private void HandleGet(HttpListenerRequest request, HttpListenerResponse response)
{
Dictionary<string, string> requestVariables = GetRequestVariables(request.Url!.Query);
@ -265,7 +281,13 @@ public class Server : GlobalBase
private void HandlePost(HttpListenerRequest request, HttpListenerResponse response)
{
Dictionary<string, string> requestVariables = GetRequestVariables(request.Url!.Query);
Dictionary<string, string> requestVariables = GetRequestVariables(request.Url!.Query); //Variables in the URI
Dictionary<string, string> requestBody = GetRequestBody(request); //Variables in the JSON body
Dictionary<string, string> requestParams = new(); //The actual variable used for the API
//Concatenate the two dictionaries for compatibility with older versions of front-ends
requestParams = requestVariables.Concat(requestBody).ToDictionary(x => x.Key, x => x.Value);
string? connectorName, internalId, jobId, chapterNumStr, customFolderName, translatedLanguage, notificationConnectorStr, libraryConnectorStr;
MangaConnector? connector;
Manga? tmpManga;
@ -277,7 +299,7 @@ public class Server : GlobalBase
switch (path)
{
case "Manga":
if(!requestVariables.TryGetValue("internalId", out internalId) ||
if(!requestParams.TryGetValue("internalId", out internalId) ||
!_parent.TryGetPublicationById(internalId, out tmpManga))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -287,9 +309,9 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.OK, response, manga);
break;
case "Jobs/MonitorManga":
if(!requestVariables.TryGetValue("connector", out connectorName) ||
!requestVariables.TryGetValue("internalId", out internalId) ||
!requestVariables.TryGetValue("interval", out string? intervalStr) ||
if(!requestParams.TryGetValue("connector", out connectorName) ||
!requestParams.TryGetValue("internalId", out internalId) ||
!requestParams.TryGetValue("interval", out string? intervalStr) ||
!_parent.TryGetConnector(connectorName, out connector)||
!_parent.TryGetPublicationById(internalId, out tmpManga) ||
!TimeSpan.TryParse(intervalStr, out TimeSpan interval))
@ -300,7 +322,7 @@ public class Server : GlobalBase
manga = (Manga)tmpManga!;
if (requestVariables.TryGetValue("ignoreBelowChapterNum", out chapterNumStr))
if (requestParams.TryGetValue("ignoreBelowChapterNum", out chapterNumStr))
{
if (!float.TryParse(chapterNumStr, numberFormatDecimalPoint, out float chapterNum))
{
@ -310,16 +332,16 @@ public class Server : GlobalBase
manga.ignoreChaptersBelow = chapterNum;
}
if (requestVariables.TryGetValue("customFolderName", out customFolderName))
if (requestParams.TryGetValue("customFolderName", out customFolderName))
manga.MovePublicationFolder(settings.downloadLocation, customFolderName);
requestVariables.TryGetValue("translatedLanguage", out translatedLanguage);
requestParams.TryGetValue("translatedLanguage", out translatedLanguage);
_parent.jobBoss.AddJob(new DownloadNewChapters(this, connector!, manga, true, interval, translatedLanguage: translatedLanguage??"en"));
SendResponse(HttpStatusCode.Accepted, response);
break;
case "Jobs/DownloadNewChapters":
if(!requestVariables.TryGetValue("connector", out connectorName) ||
!requestVariables.TryGetValue("internalId", out internalId) ||
if(!requestParams.TryGetValue("connector", out connectorName) ||
!requestParams.TryGetValue("internalId", out internalId) ||
!_parent.TryGetConnector(connectorName, out connector)||
!_parent.TryGetPublicationById(internalId, out tmpManga))
{
@ -329,7 +351,7 @@ public class Server : GlobalBase
manga = (Manga)tmpManga!;
if (requestVariables.TryGetValue("ignoreBelowChapterNum", out chapterNumStr))
if (requestParams.TryGetValue("ignoreBelowChapterNum", out chapterNumStr))
{
if (!float.TryParse(chapterNumStr, numberFormatDecimalPoint, out float chapterNum))
{
@ -339,15 +361,15 @@ public class Server : GlobalBase
manga.ignoreChaptersBelow = chapterNum;
}
if (requestVariables.TryGetValue("customFolderName", out customFolderName))
if (requestParams.TryGetValue("customFolderName", out customFolderName))
manga.MovePublicationFolder(settings.downloadLocation, customFolderName);
requestVariables.TryGetValue("translatedLanguage", out translatedLanguage);
requestParams.TryGetValue("translatedLanguage", out translatedLanguage);
_parent.jobBoss.AddJob(new DownloadNewChapters(this, connector!, manga, false, translatedLanguage: translatedLanguage??"en"));
SendResponse(HttpStatusCode.Accepted, response);
break;
case "Jobs/UpdateMetadata":
if (!requestVariables.TryGetValue("internalId", out internalId))
if (!requestParams.TryGetValue("internalId", out internalId))
{
foreach (Job pJob in _parent.jobBoss.jobs.Where(possibleDncJob =>
possibleDncJob.jobType is Job.JobType.DownloadNewChaptersJob).ToArray())//ToArray to avoid modyifying while adding new jobs
@ -375,7 +397,7 @@ public class Server : GlobalBase
}
break;
case "Jobs/StartNow":
if (!requestVariables.TryGetValue("jobId", out jobId) ||
if (!requestParams.TryGetValue("jobId", out jobId) ||
!_parent.jobBoss.TryGetJobById(jobId, out job))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -385,7 +407,7 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
break;
case "Jobs/Cancel":
if (!requestVariables.TryGetValue("jobId", out jobId) ||
if (!requestParams.TryGetValue("jobId", out jobId) ||
!_parent.jobBoss.TryGetJobById(jobId, out job))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -395,8 +417,8 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
break;
case "Settings/UpdateDownloadLocation":
if (!requestVariables.TryGetValue("downloadLocation", out string? downloadLocation) ||
!requestVariables.TryGetValue("moveFiles", out string? moveFilesStr) ||
if (!requestParams.TryGetValue("downloadLocation", out string? downloadLocation) ||
!requestParams.TryGetValue("moveFiles", out string? moveFilesStr) ||
!Boolean.TryParse(moveFilesStr, out bool moveFiles))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -406,7 +428,7 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
break;
/*case "Settings/UpdateWorkingDirectory":
if (!requestVariables.TryGetValue("workingDirectory", out string? workingDirectory))
if (!requestParams.TryGetValue("workingDirectory", out string? workingDirectory))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -415,7 +437,7 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
break;*/
case "Settings/userAgent":
if(!requestVariables.TryGetValue("userAgent", out string? customUserAgent))
if(!requestParams.TryGetValue("userAgent", out string? customUserAgent))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -428,8 +450,8 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
break;
case "Settings/customRequestLimit":
if (!requestVariables.TryGetValue("requestType", out string? requestTypeStr) ||
!requestVariables.TryGetValue("requestsPerMinute", out string? requestsPerMinuteStr) ||
if (!requestParams.TryGetValue("requestType", out string? requestTypeStr) ||
!requestParams.TryGetValue("requestsPerMinute", out string? requestsPerMinuteStr) ||
!Enum.TryParse(requestTypeStr, out RequestType requestType) ||
!int.TryParse(requestsPerMinuteStr, out int requestsPerMinute))
{
@ -450,7 +472,7 @@ public class Server : GlobalBase
settings.ExportSettings();
break;
case "NotificationConnectors/Update":
if (!requestVariables.TryGetValue("notificationConnector", out notificationConnectorStr) ||
if (!requestParams.TryGetValue("notificationConnector", out notificationConnectorStr) ||
!Enum.TryParse(notificationConnectorStr, out notificationConnectorType))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -459,8 +481,8 @@ public class Server : GlobalBase
if (notificationConnectorType is NotificationConnector.NotificationConnectorType.Gotify)
{
if (!requestVariables.TryGetValue("gotifyUrl", out string? gotifyUrl) ||
!requestVariables.TryGetValue("gotifyAppToken", out string? gotifyAppToken))
if (!requestParams.TryGetValue("gotifyUrl", out string? gotifyUrl) ||
!requestParams.TryGetValue("gotifyAppToken", out string? gotifyAppToken))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -469,7 +491,7 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
}else if (notificationConnectorType is NotificationConnector.NotificationConnectorType.LunaSea)
{
if (!requestVariables.TryGetValue("lunaseaWebhook", out string? lunaseaWebhook))
if (!requestParams.TryGetValue("lunaseaWebhook", out string? lunaseaWebhook))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -478,8 +500,8 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
}else if (notificationConnectorType is NotificationConnector.NotificationConnectorType.Ntfy)
{
if (!requestVariables.TryGetValue("ntfyUrl", out string? ntfyUrl) ||
!requestVariables.TryGetValue("ntfyAuth", out string? ntfyAuth))
if (!requestParams.TryGetValue("ntfyUrl", out string? ntfyUrl) ||
!requestParams.TryGetValue("ntfyAuth", out string? ntfyAuth))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -494,7 +516,7 @@ public class Server : GlobalBase
break;
case "NotificationConnectors/Test":
NotificationConnector notificationConnector;
if (!requestVariables.TryGetValue("notificationConnector", out notificationConnectorStr) ||
if (!requestParams.TryGetValue("notificationConnector", out notificationConnectorStr) ||
!Enum.TryParse(notificationConnectorStr, out notificationConnectorType))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -503,8 +525,8 @@ public class Server : GlobalBase
if (notificationConnectorType is NotificationConnector.NotificationConnectorType.Gotify)
{
if (!requestVariables.TryGetValue("gotifyUrl", out string? gotifyUrl) ||
!requestVariables.TryGetValue("gotifyAppToken", out string? gotifyAppToken))
if (!requestParams.TryGetValue("gotifyUrl", out string? gotifyUrl) ||
!requestParams.TryGetValue("gotifyAppToken", out string? gotifyAppToken))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -512,7 +534,7 @@ public class Server : GlobalBase
notificationConnector = new Gotify(this, gotifyUrl, gotifyAppToken);
}else if (notificationConnectorType is NotificationConnector.NotificationConnectorType.LunaSea)
{
if (!requestVariables.TryGetValue("lunaseaWebhook", out string? lunaseaWebhook))
if (!requestParams.TryGetValue("lunaseaWebhook", out string? lunaseaWebhook))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -520,8 +542,8 @@ public class Server : GlobalBase
notificationConnector = new LunaSea(this, lunaseaWebhook);
}else if (notificationConnectorType is NotificationConnector.NotificationConnectorType.Ntfy)
{
if (!requestVariables.TryGetValue("ntfyUrl", out string? ntfyUrl) ||
!requestVariables.TryGetValue("ntfyAuth", out string? ntfyAuth))
if (!requestParams.TryGetValue("ntfyUrl", out string? ntfyUrl) ||
!requestParams.TryGetValue("ntfyAuth", out string? ntfyAuth))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -538,7 +560,7 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
break;
case "NotificationConnectors/Reset":
if (!requestVariables.TryGetValue("notificationConnector", out notificationConnectorStr) ||
if (!requestParams.TryGetValue("notificationConnector", out notificationConnectorStr) ||
!Enum.TryParse(notificationConnectorStr, out notificationConnectorType))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -548,7 +570,7 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
break;
case "LibraryConnectors/Update":
if (!requestVariables.TryGetValue("libraryConnector", out libraryConnectorStr) ||
if (!requestParams.TryGetValue("libraryConnector", out libraryConnectorStr) ||
!Enum.TryParse(libraryConnectorStr, out libraryConnectorType))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -557,9 +579,9 @@ public class Server : GlobalBase
if (libraryConnectorType is LibraryConnector.LibraryType.Kavita)
{
if (!requestVariables.TryGetValue("kavitaUrl", out string? kavitaUrl) ||
!requestVariables.TryGetValue("kavitaUsername", out string? kavitaUsername) ||
!requestVariables.TryGetValue("kavitaPassword", out string? kavitaPassword))
if (!requestParams.TryGetValue("kavitaUrl", out string? kavitaUrl) ||
!requestParams.TryGetValue("kavitaUsername", out string? kavitaUsername) ||
!requestParams.TryGetValue("kavitaPassword", out string? kavitaPassword))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -568,8 +590,8 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
}else if (libraryConnectorType is LibraryConnector.LibraryType.Komga)
{
if (!requestVariables.TryGetValue("komgaUrl", out string? komgaUrl) ||
!requestVariables.TryGetValue("komgaAuth", out string? komgaAuth))
if (!requestParams.TryGetValue("komgaUrl", out string? komgaUrl) ||
!requestParams.TryGetValue("komgaAuth", out string? komgaAuth))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -584,7 +606,7 @@ public class Server : GlobalBase
break;
case "LibraryConnectors/Test":
LibraryConnector libraryConnector;
if (!requestVariables.TryGetValue("libraryConnector", out libraryConnectorStr) ||
if (!requestParams.TryGetValue("libraryConnector", out libraryConnectorStr) ||
!Enum.TryParse(libraryConnectorStr, out libraryConnectorType))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -593,9 +615,9 @@ public class Server : GlobalBase
if (libraryConnectorType is LibraryConnector.LibraryType.Kavita)
{
if (!requestVariables.TryGetValue("kavitaUrl", out string? kavitaUrl) ||
!requestVariables.TryGetValue("kavitaUsername", out string? kavitaUsername) ||
!requestVariables.TryGetValue("kavitaPassword", out string? kavitaPassword))
if (!requestParams.TryGetValue("kavitaUrl", out string? kavitaUrl) ||
!requestParams.TryGetValue("kavitaUsername", out string? kavitaUsername) ||
!requestParams.TryGetValue("kavitaPassword", out string? kavitaPassword))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -603,8 +625,8 @@ public class Server : GlobalBase
libraryConnector = new Kavita(this, kavitaUrl, kavitaUsername, kavitaPassword);
}else if (libraryConnectorType is LibraryConnector.LibraryType.Komga)
{
if (!requestVariables.TryGetValue("komgaUrl", out string? komgaUrl) ||
!requestVariables.TryGetValue("komgaAuth", out string? komgaAuth))
if (!requestParams.TryGetValue("komgaUrl", out string? komgaUrl) ||
!requestParams.TryGetValue("komgaAuth", out string? komgaAuth))
{
SendResponse(HttpStatusCode.BadRequest, response);
break;
@ -620,7 +642,7 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
break;
case "LibraryConnectors/Reset":
if (!requestVariables.TryGetValue("libraryConnector", out libraryConnectorStr) ||
if (!requestParams.TryGetValue("libraryConnector", out libraryConnectorStr) ||
!Enum.TryParse(libraryConnectorStr, out libraryConnectorType))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -637,7 +659,13 @@ public class Server : GlobalBase
private void HandleDelete(HttpListenerRequest request, HttpListenerResponse response)
{
Dictionary<string, string> requestVariables = GetRequestVariables(request.Url!.Query);
Dictionary<string, string> requestVariables = GetRequestVariables(request.Url!.Query); //Variables in the URI
Dictionary<string, string> requestBody = GetRequestBody(request); //Variables in the JSON body
Dictionary<string, string> requestParams = new(); //The actual variable used for the API
//Concatenate the two dictionaries for compatibility with older versions of front-ends
requestParams = requestVariables.Concat(requestBody).ToDictionary(x => x.Key, x => x.Value);
string? connectorName, internalId;
MangaConnector connector;
Manga manga;
@ -645,7 +673,7 @@ public class Server : GlobalBase
switch (path)
{
case "Jobs":
if (!requestVariables.TryGetValue("jobId", out string? jobId) ||
if (!requestParams.TryGetValue("jobId", out string? jobId) ||
!_parent.jobBoss.TryGetJobById(jobId, out Job? job))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -655,8 +683,8 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
break;
case "Jobs/DownloadNewChapters":
if(!requestVariables.TryGetValue("connector", out connectorName) ||
!requestVariables.TryGetValue("internalId", out internalId) ||
if(!requestParams.TryGetValue("connector", out connectorName) ||
!requestParams.TryGetValue("internalId", out internalId) ||
_parent.GetConnector(connectorName) is null ||
_parent.GetPublicationById(internalId) is null)
{
@ -669,7 +697,7 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
break;
case "NotificationConnectors":
if (!requestVariables.TryGetValue("notificationConnector", out string? notificationConnectorStr) ||
if (!requestParams.TryGetValue("notificationConnector", out string? notificationConnectorStr) ||
!Enum.TryParse(notificationConnectorStr, out NotificationConnector.NotificationConnectorType notificationConnectorType))
{
SendResponse(HttpStatusCode.BadRequest, response);
@ -679,7 +707,7 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.Accepted, response);
break;
case "LibraryConnectors":
if (!requestVariables.TryGetValue("libraryConnectors", out string? libraryConnectorStr) ||
if (!requestParams.TryGetValue("libraryConnector", out string? libraryConnectorStr) ||
!Enum.TryParse(libraryConnectorStr,
out LibraryConnector.LibraryType libraryConnectoryType))
{