Skip to content

Commit

Permalink
Create item and upload the stream data in a single call
Browse files Browse the repository at this point in the history
  • Loading branch information
ramondeklein committed Jan 19, 2024
1 parent d086117 commit 0ae1984
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 46 deletions.
14 changes: 2 additions & 12 deletions NWebDav.Server/Handlers/PutHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,8 @@ public async Task<bool> HandleRequestAsync(HttpContext httpContext)
}

// Obtain the item
var result = await collection.CreateItemAsync(splitUri.Name, true, httpContext.RequestAborted).ConfigureAwait(false);
var status = result.Result;
if (status == DavStatusCode.Created || status == DavStatusCode.NoContent)
{
// Upload the information to the item
var uploadStatus = await result.Item.UploadFromStreamAsync(request.Body, httpContext.RequestAborted).ConfigureAwait(false);
if (uploadStatus != DavStatusCode.Ok)
status = uploadStatus;
}

// Finished writing
response.SetStatus(status);
var result = await collection.CreateItemAsync(splitUri.Name, request.Body, true, httpContext.RequestAborted).ConfigureAwait(false);
response.SetStatus(result.Result);
return true;
}
}
32 changes: 12 additions & 20 deletions NWebDav.Server/Stores/DiskStoreCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,47 +58,39 @@ public async IAsyncEnumerable<IStoreItem> GetItemsAsync([EnumeratorCancellation]
yield return _store.CreateItem(file);
}

public Task<StoreItemResult> CreateItemAsync(string name, bool overwrite, CancellationToken cancellationToken)
public async Task<StoreItemResult> CreateItemAsync(string name, Stream stream, bool overwrite, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();

// Return error
if (!IsWritable)
return Task.FromResult(new StoreItemResult(DavStatusCode.PreconditionFailed));
return new StoreItemResult(DavStatusCode.PreconditionFailed);

// Determine the destination path
var destinationPath = Path.Combine(FullPath, name);

// Determine result
DavStatusCode result;

// Check if the file can be overwritten
if (File.Exists(name))
{
if (!overwrite)
return Task.FromResult(new StoreItemResult(DavStatusCode.PreconditionFailed));

result = DavStatusCode.NoContent;
}
else
{
result = DavStatusCode.Created;
}
if (File.Exists(name) && !overwrite)
return new StoreItemResult(DavStatusCode.PreconditionFailed);

try
{
// Create a new file
File.Create(destinationPath).Dispose();
var file = File.Create(destinationPath);
await using (file.ConfigureAwait(false))
{
await stream.CopyToAsync(file, cancellationToken).ConfigureAwait(false);
}
}
catch (Exception exc)
{
// Log exception
_logger.LogError(exc, "Unable to create '{Path}' file.", destinationPath);
return Task.FromResult(new StoreItemResult(DavStatusCode.InternalServerError));
return new StoreItemResult(DavStatusCode.InternalServerError);
}

// Return result
return Task.FromResult(new StoreItemResult(result, _store.CreateItem(new FileInfo(destinationPath))));
var item = _store.CreateItem(new FileInfo(destinationPath));
return new StoreItemResult(DavStatusCode.Created, item);
}

public Task<StoreCollectionResult> CreateCollectionAsync(string name, bool overwrite, CancellationToken cancellationToken)
Expand Down
15 changes: 2 additions & 13 deletions NWebDav.Server/Stores/DiskStoreItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,11 @@ public async Task<StoreItemResult> CopyAsync(IStoreCollection destination, strin
else
{
// Create the item in the destination collection
var result = await destination.CreateItemAsync(name, overwrite, cancellationToken).ConfigureAwait(false);

// Check if the item could be created
if (result.Item != null)
{
var sourceStream = await GetReadableStreamAsync(cancellationToken).ConfigureAwait(false);
await using (sourceStream.ConfigureAwait(false))
{
var copyResult = await result.Item.UploadFromStreamAsync(sourceStream, cancellationToken).ConfigureAwait(false);
if (copyResult != DavStatusCode.Ok)
return new StoreItemResult(copyResult, result.Item);
}
{
return await destination.CreateItemAsync(name, sourceStream, overwrite, cancellationToken).ConfigureAwait(false);
}

// Return result
return new StoreItemResult(result.Result, result.Item);
}
}
catch (Exception exc)
Expand Down
3 changes: 2 additions & 1 deletion NWebDav.Server/Stores/IStoreCollection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -12,7 +13,7 @@ public interface IStoreCollection : IStoreItem
IAsyncEnumerable<IStoreItem> GetItemsAsync(CancellationToken cancellationToken);

// Create items and collections and add to the collection
Task<StoreItemResult> CreateItemAsync(string name, bool overwrite, CancellationToken cancellationToken);
Task<StoreItemResult> CreateItemAsync(string name, Stream stream, bool overwrite, CancellationToken cancellationToken);
Task<StoreCollectionResult> CreateCollectionAsync(string name, bool overwrite, CancellationToken cancellationToken);

// Checks if the collection can be moved directly to the destination
Expand Down

0 comments on commit 0ae1984

Please sign in to comment.