112 lines
4.0 KiB
TypeScript
112 lines
4.0 KiB
TypeScript
import { IncomingMessage, ServerResponse } from 'http'
|
|
import { FileAPI, FileType } from '@/client/api'
|
|
import { Token } from '@/client/idp'
|
|
import { handleError } from '@/infra/error'
|
|
|
|
/*
|
|
This method retrieves properties and metadata of a resource.
|
|
|
|
Example implementation:
|
|
|
|
- Extract the file path from the URL.
|
|
- Use fs.stat() to retrieve the file metadata.
|
|
- Format the response body in the desired XML format with the properties and metadata.
|
|
- Set the response status code to 207 if successful or an appropriate error code if the file is not found or encountered an error.
|
|
- Set the Content-Type header to indicate the XML format.
|
|
- Return the response.
|
|
*/
|
|
async function handlePropfind(
|
|
req: IncomingMessage,
|
|
res: ServerResponse,
|
|
token: Token
|
|
) {
|
|
try {
|
|
const api = new FileAPI(token)
|
|
const file = await api.getByPath(decodeURIComponent(req.url))
|
|
if (file.type === FileType.File) {
|
|
const responseXml = `
|
|
<D:multistatus xmlns:D="DAV:">
|
|
<D:response>
|
|
<D:href>${encodeURIComponent(file.name)}</D:href>
|
|
<D:propstat>
|
|
<D:prop>
|
|
<D:resourcetype></D:resourcetype>
|
|
${
|
|
file.original
|
|
? `<D:getcontentlength>${file.original.size}</D:getcontentlength>`
|
|
: ''
|
|
}
|
|
<D:creationdate>${new Date(
|
|
file.createTime
|
|
).toUTCString()}</D:creationdate>
|
|
<D:getlastmodified>${new Date(
|
|
file.updateTime
|
|
).toUTCString()}</D:getlastmodified>
|
|
</D:prop>
|
|
<D:status>HTTP/1.1 200 OK</D:status>
|
|
</D:propstat>
|
|
</D:response>
|
|
</D:multistatus>`
|
|
res.statusCode = 207
|
|
res.setHeader('Content-Type', 'application/xml; charset=utf-8')
|
|
res.end(responseXml)
|
|
} else if (file.type === FileType.Folder) {
|
|
const list = await api.listByPath(decodeURIComponent(req.url))
|
|
const responseXml = `
|
|
<D:multistatus xmlns:D="DAV:">
|
|
<D:response>
|
|
<D:href>${req.url}</D:href>
|
|
<D:propstat>
|
|
<D:prop>
|
|
<D:resourcetype><D:collection/></D:resourcetype>
|
|
<D:getcontentlength>0</D:getcontentlength>
|
|
<D:getlastmodified>${new Date(
|
|
file.updateTime
|
|
).toUTCString()}</D:getlastmodified>
|
|
<D:creationdate>${new Date(
|
|
file.createTime
|
|
).toUTCString()}</D:creationdate>
|
|
</D:prop>
|
|
<D:status>HTTP/1.1 200 OK</D:status>
|
|
</D:propstat>
|
|
</D:response>
|
|
${list
|
|
.map((item) => {
|
|
return `
|
|
<D:response>
|
|
<D:href>${req.url}${encodeURIComponent(item.name)}</D:href>
|
|
<D:propstat>
|
|
<D:prop>
|
|
<D:resourcetype>${
|
|
item.type === FileType.Folder ? '<D:collection/>' : ''
|
|
}</D:resourcetype>
|
|
${
|
|
item.type === FileType.File && item.original
|
|
? `<D:getcontentlength>${item.original.size}</D:getcontentlength>`
|
|
: ''
|
|
}
|
|
<D:getlastmodified>${new Date(
|
|
item.updateTime
|
|
).toUTCString()}</D:getlastmodified>
|
|
<D:creationdate>${new Date(
|
|
item.createTime
|
|
).toUTCString()}</D:creationdate>
|
|
</D:prop>
|
|
<D:status>HTTP/1.1 200 OK</D:status>
|
|
</D:propstat>
|
|
</D:response>
|
|
`
|
|
})
|
|
.join('')}
|
|
</D:multistatus>`
|
|
res.statusCode = 207
|
|
res.setHeader('Content-Type', 'application/xml; charset=utf-8')
|
|
res.end(responseXml)
|
|
}
|
|
} catch (err) {
|
|
handleError(err, res)
|
|
}
|
|
}
|
|
|
|
export default handlePropfind
|