...
This commit is contained in:
@@ -300,6 +300,26 @@ pub fn (mut server Server) mkcol(mut ctx Context, path string) veb.Result {
|
|||||||
|
|
||||||
@['/:path...'; put]
|
@['/:path...'; put]
|
||||||
fn (mut server Server) create_or_update(mut ctx Context, path string) veb.Result {
|
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
|
// Handle parent directory
|
||||||
parent_path := path.all_before_last('/')
|
parent_path := path.all_before_last('/')
|
||||||
if parent_path != '' && !server.vfs.exists(parent_path) {
|
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
|
// Process Content-Type if provided - reuse the existing content_type variable
|
||||||
content_type := ctx.req.header.get(.content_type) or { '' }
|
|
||||||
if content_type != '' {
|
if content_type != '' {
|
||||||
log.debug('[WebDAV] Content-Type provided: ${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('')
|
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]
|
@['/:path...'; propfind]
|
||||||
fn (mut server Server) propfind(mut ctx Context, path string) veb.Result {
|
fn (mut server Server) propfind(mut ctx Context, path string) veb.Result {
|
||||||
|
// Process the PROPFIND request
|
||||||
// Parse PROPFIND request
|
// Parse PROPFIND request
|
||||||
propfind_req := parse_propfind_xml(ctx.req) or {
|
propfind_req := parse_propfind_xml(ctx.req) or {
|
||||||
return ctx.error(WebDAVError{
|
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
|
// returns the properties of a filesystem entry
|
||||||
fn (mut server Server) get_entry_property(entry &vfs.FSEntry, name string) !Property {
|
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()))) }
|
'creationdate' { Property(CreationDate(format_iso8601(entry.get_metadata().created_time()))) }
|
||||||
'getetag' { Property(GetETag(entry.get_metadata().id.str())) }
|
'getetag' { Property(GetETag(entry.get_metadata().id.str())) }
|
||||||
'resourcetype' { Property(ResourceType(entry.is_dir())) }
|
'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())) }
|
'getcontentlength' { Property(GetContentLength(entry.get_metadata().size.str())) }
|
||||||
'quota-available-bytes' { Property(QuotaAvailableBytes(16184098816)) }
|
'quota-available-bytes' { Property(QuotaAvailableBytes(16184098816)) }
|
||||||
'quota-used-bytes' { Property(QuotaUsedBytes(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
|
// Always show as unlocked for now to ensure compatibility
|
||||||
Property(LockDiscovery(''))
|
Property(LockDiscovery(''))
|
||||||
}
|
}
|
||||||
's:lastmodified_server' {
|
else {
|
||||||
// This appears to be a custom property requested by some WebDAV clients
|
// For any unimplemented property, return an empty string instead of panicking
|
||||||
// Return the last modified time of the resource
|
// This improves compatibility with various WebDAV clients
|
||||||
Property(GetLastModified(texttools.format_rfc1123(entry.get_metadata().modified_time())))
|
log.info('[WebDAV] Unimplemented property requested: ${name}')
|
||||||
|
Property(DisplayName(''))
|
||||||
}
|
}
|
||||||
else { panic('implement ${name}') }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user