-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathweb-dav.ts
More file actions
111 lines (102 loc) · 3.54 KB
/
web-dav.ts
File metadata and controls
111 lines (102 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* WebDAV client api
*
* Testing with server implemented by https://github.com/svtslv/webdav-cli
*/
import { encode } from 'js-base64'
import { fetchDelete, fetchGet } from './http'
// Only support password for now
export type WebDAVAuth = {
type: 'password'
username: string
password: string
}
export type WebDAVContext = {
auth: WebDAVAuth
endpoint: string
}
const authHeaders = (auth: WebDAVAuth): Headers => {
const type = auth?.type
const headers = new Headers()
if (type === 'password') {
headers.set('Authorization', `Basic ${encode(`${auth?.username}:${auth?.password}`)}`)
}
return headers
}
export async function judgeDirExist(context: WebDAVContext, dirPath: string): Promise<boolean> {
const { auth, endpoint } = context || {}
const headers = authHeaders(auth)
const url = `${endpoint}/${dirPath}`
const method = 'PROPFIND'
headers.append('Accept', 'text/plain,application/xml')
headers.append('Depth', '1')
const response = await fetch(url, { method, headers })
const status = response?.status
if (status == 207) {
return true
} else if (status === 300) {
throw new Error("Your server does't support PROPFIND method!")
} else if (status == 404) {
return false
} else if (status == 401) {
throw new Error("Authorization is invalid!")
} else {
throw new Error("Unknown directory status")
}
}
export async function makeDir(context: WebDAVContext, dirPath: string) {
const { auth, endpoint } = context || {}
const url = `${endpoint}/${dirPath}`
const headers = authHeaders(auth)
const response = await fetch(url, { method: 'MKCOL', headers })
handleWriteResponse(response)
}
export async function deleteDir(context: WebDAVContext, dirPath: string) {
const { auth, endpoint } = context || {}
const url = `${endpoint}/${dirPath}`
const headers = authHeaders(auth)
const response = await fetchDelete(url, { headers })
const status = response.status
if (status === 403) {
throw new Error("Unauthorized to delete directory")
}
if (status !== 201 && status !== 200) {
throw new Error("Failed to delete directory: " + status)
}
}
export async function writeFile(context: WebDAVContext, filePath: string, content: string): Promise<void> {
const { auth, endpoint } = context || {}
const headers = authHeaders(auth)
headers.set("Content-Type", "application/octet-stream")
const url = `${endpoint}/${filePath}`
const response = await fetch(url, { headers, method: 'put', body: content })
handleWriteResponse(response)
}
function handleWriteResponse(response: Response) {
const status = response.status
if (status === 403) {
throw new Error("Unauthorized to write file or create directory")
}
if (status !== 201 && status !== 200) {
throw new Error("Failed to write file or create directory: " + status)
}
}
export async function readFile(context: WebDAVContext, filePath: string): Promise<string | null> {
const { auth, endpoint } = context || {}
const headers = authHeaders(auth)
const url = `${endpoint}/${filePath}`
try {
const response = await fetchGet(url, { headers })
const status = response?.status
if (status === 200) {
return response.text()
}
if (status !== 404) {
console.warn("Unexpected status: " + status)
}
return null
} catch (e) {
console.error("Failed to read WebDAV content", e)
return null
}
}