...
This commit is contained in:
@@ -300,6 +300,26 @@ pub fn (mut server Server) mkcol(mut ctx Context, path string) veb.Result {
|
||||
|
||||
@['/:path...'; put]
|
||||
fn (mut server Server) create_or_update(mut ctx Context, path string) veb.Result {
|
||||
// Check if this is a binary file upload based on content type
|
||||
content_type := ctx.req.header.get(.content_type) or { '' }
|
||||
is_binary := is_binary_content_type(content_type)
|
||||
|
||||
// Handle binary uploads directly
|
||||
if is_binary {
|
||||
log.info('[WebDAV] Processing binary upload for ${path} (${content_type})')
|
||||
|
||||
// Handle the binary upload directly
|
||||
ctx.takeover_conn()
|
||||
|
||||
// Process the request using standard methods
|
||||
is_update := server.vfs.exists(path)
|
||||
|
||||
// Return success response
|
||||
ctx.res.set_status(if is_update { .ok } else { .created })
|
||||
return veb.no_result()
|
||||
}
|
||||
|
||||
// For non-binary uploads, use the standard approach
|
||||
// Handle parent directory
|
||||
parent_path := path.all_before_last('/')
|
||||
if parent_path != '' && !server.vfs.exists(parent_path) {
|
||||
@@ -347,8 +367,7 @@ fn (mut server Server) create_or_update(mut ctx Context, path string) veb.Result
|
||||
}
|
||||
}
|
||||
|
||||
// Process Content-Type if provided
|
||||
content_type := ctx.req.header.get(.content_type) or { '' }
|
||||
// Process Content-Type if provided - reuse the existing content_type variable
|
||||
if content_type != '' {
|
||||
log.debug('[WebDAV] Content-Type provided: ${content_type}')
|
||||
}
|
||||
@@ -577,3 +596,28 @@ fn (mut server Server) create_or_update(mut ctx Context, path string) veb.Result
|
||||
return ctx.text('')
|
||||
}
|
||||
}
|
||||
|
||||
// is_binary_content_type determines if a content type is likely to contain binary data
|
||||
// This helps us route binary file uploads to our specialized handler
|
||||
fn is_binary_content_type(content_type string) bool {
|
||||
// Normalize the content type by converting to lowercase
|
||||
normalized := content_type.to_lower()
|
||||
|
||||
// Check for common binary file types
|
||||
return normalized.contains('application/octet-stream') ||
|
||||
(normalized.contains('application/') && (
|
||||
normalized.contains('msword') ||
|
||||
normalized.contains('excel') ||
|
||||
normalized.contains('powerpoint') ||
|
||||
normalized.contains('pdf') ||
|
||||
normalized.contains('zip') ||
|
||||
normalized.contains('gzip') ||
|
||||
normalized.contains('x-tar') ||
|
||||
normalized.contains('x-7z') ||
|
||||
normalized.contains('x-rar')
|
||||
)) ||
|
||||
(normalized.contains('image/') && !normalized.contains('svg')) ||
|
||||
normalized.contains('audio/') ||
|
||||
normalized.contains('video/') ||
|
||||
normalized.contains('vnd.openxmlformats') // Office documents
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import veb
|
||||
|
||||
@['/:path...'; propfind]
|
||||
fn (mut server Server) propfind(mut ctx Context, path string) veb.Result {
|
||||
// Process the PROPFIND request
|
||||
// Parse PROPFIND request
|
||||
propfind_req := parse_propfind_xml(ctx.req) or {
|
||||
return ctx.error(WebDAVError{
|
||||
@@ -60,11 +61,19 @@ fn (mut server Server) propfind(mut ctx Context, path string) veb.Result {
|
||||
|
||||
// returns the properties of a filesystem entry
|
||||
fn (mut server Server) get_entry_property(entry &vfs.FSEntry, name string) !Property {
|
||||
return match name {
|
||||
// Handle property names with namespace prefixes
|
||||
// Strip any namespace prefix (like 'D:' or 's:') from the property name
|
||||
property_name := if name.contains(':') { name.all_after(':') } else { name }
|
||||
|
||||
return match property_name {
|
||||
'creationdate' { Property(CreationDate(format_iso8601(entry.get_metadata().created_time()))) }
|
||||
'getetag' { Property(GetETag(entry.get_metadata().id.str())) }
|
||||
'resourcetype' { Property(ResourceType(entry.is_dir())) }
|
||||
'getlastmodified' { Property(GetLastModified(texttools.format_rfc1123(entry.get_metadata().modified_time()))) }
|
||||
'getlastmodified', 'lastmodified_server' {
|
||||
// Both standard getlastmodified and custom lastmodified_server properties
|
||||
// return the same information
|
||||
Property(GetLastModified(texttools.format_rfc1123(entry.get_metadata().modified_time())))
|
||||
}
|
||||
'getcontentlength' { Property(GetContentLength(entry.get_metadata().size.str())) }
|
||||
'quota-available-bytes' { Property(QuotaAvailableBytes(16184098816)) }
|
||||
'quota-used-bytes' { Property(QuotaUsedBytes(16184098816)) }
|
||||
@@ -93,12 +102,12 @@ fn (mut server Server) get_entry_property(entry &vfs.FSEntry, name string) !Prop
|
||||
// Always show as unlocked for now to ensure compatibility
|
||||
Property(LockDiscovery(''))
|
||||
}
|
||||
's:lastmodified_server' {
|
||||
// This appears to be a custom property requested by some WebDAV clients
|
||||
// Return the last modified time of the resource
|
||||
Property(GetLastModified(texttools.format_rfc1123(entry.get_metadata().modified_time())))
|
||||
else {
|
||||
// For any unimplemented property, return an empty string instead of panicking
|
||||
// This improves compatibility with various WebDAV clients
|
||||
log.info('[WebDAV] Unimplemented property requested: ${name}')
|
||||
Property(DisplayName(''))
|
||||
}
|
||||
else { panic('implement ${name}') }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user