mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 15:42:48 -05:00
support for attachments keys
load existing items and set attachments on key update
This commit is contained in:
@ -13,40 +13,54 @@ namespace Bit.Api.Utilities
|
||||
{
|
||||
private static readonly FormOptions _defaultFormOptions = new FormOptions();
|
||||
|
||||
public static async Task GetFileAsync(this HttpRequest request, Func<Stream, string, Task> callback)
|
||||
{
|
||||
await request.GetFilesAsync(1, callback);
|
||||
}
|
||||
|
||||
private static async Task GetFilesAsync(this HttpRequest request, int? fileCount, Func<Stream, string, Task> callback)
|
||||
public static async Task GetFileAsync(this HttpRequest request, Func<Stream, string, string, Task> callback)
|
||||
{
|
||||
var boundary = GetBoundary(MediaTypeHeaderValue.Parse(request.ContentType),
|
||||
_defaultFormOptions.MultipartBoundaryLengthLimit);
|
||||
var reader = new MultipartReader(boundary, request.Body);
|
||||
|
||||
var section = await reader.ReadNextSectionAsync();
|
||||
var fileNumber = 1;
|
||||
while(section != null && fileNumber <= fileCount)
|
||||
var firstSection = await reader.ReadNextSectionAsync();
|
||||
if(firstSection != null)
|
||||
{
|
||||
if(ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var content) &&
|
||||
HasFileContentDisposition(content))
|
||||
if(ContentDispositionHeaderValue.TryParse(firstSection.ContentDisposition, out var firstContent))
|
||||
{
|
||||
var fileName = HeaderUtilities.RemoveQuotes(content.FileName).ToString();
|
||||
using(section.Body)
|
||||
if(HasFileContentDisposition(firstContent))
|
||||
{
|
||||
await callback(section.Body, fileName);
|
||||
// Old style with just data
|
||||
var fileName = HeaderUtilities.RemoveQuotes(firstContent.FileName).ToString();
|
||||
using(firstSection.Body)
|
||||
{
|
||||
await callback(firstSection.Body, fileName, null);
|
||||
}
|
||||
}
|
||||
else if(HasKeyDisposition(firstContent))
|
||||
{
|
||||
// New style with key, then data
|
||||
string key = null;
|
||||
using(var sr = new StreamReader(firstSection.Body))
|
||||
{
|
||||
key = await sr.ReadToEndAsync();
|
||||
}
|
||||
|
||||
var secondSection = await reader.ReadNextSectionAsync();
|
||||
if(secondSection != null)
|
||||
{
|
||||
if(ContentDispositionHeaderValue.TryParse(secondSection.ContentDisposition,
|
||||
out var secondContent) && HasFileContentDisposition(secondContent))
|
||||
{
|
||||
var fileName = HeaderUtilities.RemoveQuotes(secondContent.FileName).ToString();
|
||||
using(secondSection.Body)
|
||||
{
|
||||
await callback(secondSection.Body, fileName, key);
|
||||
}
|
||||
}
|
||||
|
||||
secondSection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(fileNumber >= fileCount)
|
||||
{
|
||||
section = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
section = await reader.ReadNextSectionAsync();
|
||||
fileNumber++;
|
||||
}
|
||||
firstSection = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,9 +82,15 @@ namespace Bit.Api.Utilities
|
||||
|
||||
private static bool HasFileContentDisposition(ContentDispositionHeaderValue content)
|
||||
{
|
||||
// Content-Disposition: form-data; name="myfile1"; filename="Misc 002.jpg"
|
||||
// Content-Disposition: form-data; name="data"; filename="Misc 002.jpg"
|
||||
return content != null && content.DispositionType.Equals("form-data") &&
|
||||
(!StringSegment.IsNullOrEmpty(content.FileName) || !StringSegment.IsNullOrEmpty(content.FileNameStar));
|
||||
}
|
||||
|
||||
private static bool HasKeyDisposition(ContentDispositionHeaderValue content)
|
||||
{
|
||||
// Content-Disposition: form-data; name="key";
|
||||
return content != null && content.DispositionType.Equals("form-data") && content.Name == "key";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user