forked from reruin/sharelist
-
Notifications
You must be signed in to change notification settings - Fork 2
/
drive.webdav.js
146 lines (115 loc) · 3.45 KB
/
drive.webdav.js
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
* WebDAV
* http(s)://username:password@host.com:port/?acceptRanges=none
* 如果webdav server 不支持 206,需要带上acceptRanges=none 标识
*/
const name = 'WebDAV'
const version = '1.0'
const protocols = ['webdav']
const defaultProtocol = 'webdav'
const path = require('path')
const { createClient } = require("webdav");
const { URL } = require("url")
const urlFormat = require('url').format
const { Writable } = require('stream')
const clientMap = {}
module.exports = ({ getConfig, cache, base64, extname }) => {
const getClient = async (url, cd = false) => {
let { protocol , username, password, host, port, pathname , searchParams } = new URL(url);
let remote_url = protocol + '//' + host + pathname
let hit = clientMap[remote_url]
if (!hit) {
let client = createClient(remote_url,{
username:decodeURIComponent(username),password:decodeURIComponent(password)
});
let options = {}
searchParams.forEach((value, name) => {
options[name] = value
})
clientMap[remote_url] = hit = { client , options }
}
return { ...hit , path:searchParams.get('path') || '/' };
}
const createId = (id , path) => {
let obj = new URL(id)
let searchParams = obj.searchParams
// let basepath = searchParams.get('path') || ''
searchParams.set('path' , path)
obj.search = searchParams.toString()
return obj.href
}
const folder = async (id) => {
let resp = { id : id, type: 'folder', protocol: defaultProtocol }
/*
let resid = `${defaultProtocol}:${id}`
let r = cache.get(resid)
if (r) {
resp = r
if (
resp.$cached_at &&
resp.children &&
(Date.now() - resp.$cached_at < getConfig('max_age_dir'))
) {
console.log('get webdav folder from cache')
return resp
}
}
*/
let { client , path } = await getClient(id)
if (client) {
let data = await client.getDirectoryContents(path);
let children = [];
data.forEach(i => {
let fid = createId(id , i.filename)
let obj = {
id: fid,
name: i.basename,
protocol: defaultProtocol,
size: i.size,
created_at: i.lastmod,
updated_at: i.lastmod,
ext: extname(i.basename),
mime:i.mime,
type: i.type == 'directory' ? 'folder' : 'other'
}
children.push(obj)
})
resp.$cached_at = Date.now()
resp.children = children
//cache.set(resid, resp)
return resp
} else {
return false
}
}
const file = async (id , { data = {} }) => {
let { client , path } = await getClient(id)
if(client){
data.url = client.getFileDownloadLink(path)
}
data.outputType = 'url'
data.proxy = 'stream'
return data
}
const stream = async (id, options = {}) => {
let { client , options:clientOptions , path} = await getClient(id)
if (client) {
if(options.contentFormat){
return await client.getFileContents(path , { format : 'text'})
}else{
let range = options.range
let opts = {}
if(clientOptions.acceptRanges != 'none' && options.range){
opts.range = options.range
}
return {
stream: client.createReadStream(path, opts),
acceptRanges: false
}
}
} else {
return null
}
}
return { name, version, drive: { protocols, folder, file, stream } }
}