mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-07-18 11:34:46 +01:00
Various fixups
This commit is contained in:
@@ -375,3 +375,33 @@ To get a specific compile job use:
|
||||
I GET "/DreamMaker/{CompileJobId}" => @ref Tgstation.Server.Api.Models.CompileJob
|
||||
|
||||
*/
|
||||
|
||||
@subsection api_config Static Files
|
||||
|
||||
Static files can be both read and written.
|
||||
|
||||
To get the contents of a static file directory use the following method
|
||||
|
||||
I GET "/Config/List/<path to directory>" => Array of @ref Tgstation.Server.Api.Models.ConfigurationFile
|
||||
|
||||
Where the path is formatted as: directory/inner_directory/more_directories
|
||||
|
||||
If the path is empty, the root directory will be retrieved. The @ref Tgstation.Server.Api.Models.ConfigurationFile.Content and @ref Tgstation.Server.Api.Models.ConfigurationFile.LastReadHash fields will not be populated for this response
|
||||
|
||||
If you do not have access to list the requested directory, a 403 response will be returned. If the path actually represents a file or the directory no longer exists a 410 response will be returned.
|
||||
|
||||
To get the content of a static file use the following method
|
||||
|
||||
I GET "/Config/File/<path to file>" => @ref Tgstation.Server.Api.Models.ConfigurationFile
|
||||
|
||||
410 will be returned if the path doesn't exist. @ref Tgstation.Server.Api.Models.ConfigurationFile.Content will only be populated if the path is a file the user has access to, otherwise the other fields will be populated appropriately.
|
||||
|
||||
To create, write, and delete files use the following request
|
||||
|
||||
I POST "/Config" @ref Tgstation.Server.Api.Models.ConfigurationFile => @ref Tgstation.Server.Api.Models.ConfigurationFile
|
||||
|
||||
When creating a file, only @ref Tgstation.Server.Api.Models.ConfigurationFile.Path and @ref Tgstation.Server.Api.Models.ConfigurationFile.Content should be specified. Any necessary preceeding directories will be created if possible.
|
||||
|
||||
If the file already exists, the @ref Tgstation.Server.Api.Models.ConfigurationFile.LastReadHash field must also be present with the last version recieved from the server for that file. If this does not match at the time of the request, 409 will be returned, indicating the file has changed since it was last viewed by the client.
|
||||
|
||||
To delete a file set @ref Tgstation.Server.Api.Models.ConfigurationFile.Content to null in the request. If deleting a file leaves a directory empty, they too will be deleted.
|
||||
@@ -372,6 +372,14 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
/// <inheritdoc />
|
||||
public async Task Sychronize(string username, string password, bool synchronizeTrackedBranch, CancellationToken cancellationToken)
|
||||
{
|
||||
if (username == null && password == null)
|
||||
return;
|
||||
|
||||
if (username == null)
|
||||
throw new ArgumentNullException(nameof(username));
|
||||
if (password == null)
|
||||
throw new ArgumentNullException(nameof(password));
|
||||
|
||||
var startHead = Head;
|
||||
|
||||
if (!await eventConsumer.HandleEvent(EventType.RepoPreSynchronize, new List<string> { ioMananger.ResolvePath(".") }, cancellationToken).ConfigureAwait(false))
|
||||
|
||||
@@ -166,13 +166,9 @@ namespace Tgstation.Server.Host.Components.StaticFiles
|
||||
Path = ioManager.ConcatPath(path, x),
|
||||
}));
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
result = null;
|
||||
return;
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
catch (IOException e)
|
||||
{
|
||||
logger.LogDebug("IOException while writing {0}: {1}", path, e);
|
||||
result = null;
|
||||
return;
|
||||
}
|
||||
@@ -222,7 +218,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
logger.LogWarning("IOException while reading {0}: {1}", path, e);
|
||||
logger.LogDebug("IOException while reading {0}: {1}", path, e);
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
@@ -299,30 +295,22 @@ namespace Tgstation.Server.Host.Components.StaticFiles
|
||||
lock (this)
|
||||
try
|
||||
{
|
||||
var success = synchronousIOManager.WriteFileChecked(path, data, previousHash, cancellationToken);
|
||||
var fileHash = previousHash;
|
||||
var success = synchronousIOManager.WriteFileChecked(path, data, ref fileHash, cancellationToken);
|
||||
if (!success)
|
||||
return;
|
||||
string sha1String = null;
|
||||
if (data != null)
|
||||
{
|
||||
postWriteHandler.HandleWrite(path);
|
||||
#pragma warning disable CA5350 // Do not use insecure cryptographic algorithm SHA1.
|
||||
using (var sha1 = new SHA1Managed())
|
||||
#pragma warning restore CA5350 // Do not use insecure cryptographic algorithm SHA1.
|
||||
sha1String = String.Join("", sha1.ComputeHash(data).Select(b => b.ToString("x2", CultureInfo.InvariantCulture)));
|
||||
}
|
||||
result = new ConfigurationFile
|
||||
{
|
||||
Content = data,
|
||||
IsDirectory = false,
|
||||
LastReadHash = sha1String,
|
||||
LastReadHash = fileHash,
|
||||
AccessDenied = false,
|
||||
Path = configurationRelativePath
|
||||
};
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
logger.LogWarning("IOException while writing {0}: {1}", path, e);
|
||||
logger.LogDebug("IOException while writing {0}: {1}", path, e);
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
|
||||
@@ -36,10 +36,10 @@ namespace Tgstation.Server.Host.IO
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the file to write</param>
|
||||
/// <param name="data">The new contents of the file</param>
|
||||
/// <param name="previousSha1">If the file exists, this function only succeeds if this parameter matches the SHA-1 hash of the contents of the current file</param>
|
||||
/// <param name="sha1InOut">The function only succeeds if this parameter matches the SHA-1 hash of the contents of the current file. Contains the SHA1 of the file on disk once the function returns</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
|
||||
/// <returns><see langword="true"/> on success, <see langword="false"/> if the operation failed due to <paramref name="previousSha1"/> not matching the file's contents</returns>
|
||||
bool WriteFileChecked(string path, byte[] data, string previousSha1, CancellationToken cancellationToken);
|
||||
bool WriteFileChecked(string path, byte[] data, ref string sha1InOut, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a given <paramref name="path"/> is a directory
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Tgstation.Server.Host.IO
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool WriteFileChecked(string path, byte[] data, string previousSha1, CancellationToken cancellationToken)
|
||||
public bool WriteFileChecked(string path, byte[] data, ref string sha1InOut, CancellationToken cancellationToken)
|
||||
{
|
||||
if (path == null)
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
@@ -69,7 +69,7 @@ namespace Tgstation.Server.Host.IO
|
||||
file.CopyTo(readMs);
|
||||
originalBytes = readMs.ToArray();
|
||||
}
|
||||
if (originalBytes.Length != 0 && previousSha1 == null)
|
||||
if (originalBytes.Length != 0 && sha1InOut == null)
|
||||
//no sha1? no write
|
||||
return false;
|
||||
|
||||
@@ -78,9 +78,14 @@ namespace Tgstation.Server.Host.IO
|
||||
using (var sha1 = new SHA1Managed())
|
||||
#pragma warning restore CA5350 // Do not use insecure cryptographic algorithm SHA1.
|
||||
{
|
||||
var sha1String = originalBytes.Length != 0 ? String.Join("", sha1.ComputeHash(originalBytes).Select(b => b.ToString("x2", CultureInfo.InvariantCulture))) : null;
|
||||
if (sha1String != previousSha1)
|
||||
string GetSha1(byte[] dataToHash) => dataToHash.Length != 0 ? String.Join("", sha1.ComputeHash(dataToHash).Select(b => b.ToString("x2", CultureInfo.InvariantCulture))) : null;
|
||||
var originalSha1 = GetSha1(originalBytes);
|
||||
if (originalSha1 != sha1InOut)
|
||||
{
|
||||
sha1InOut = originalSha1;
|
||||
return false;
|
||||
}
|
||||
sha1InOut = GetSha1(data);
|
||||
}
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user