stash
This commit is contained in:
parent
7e8f984ee2
commit
a1fd49c5d1
11 changed files with 406 additions and 214 deletions
|
|
@ -6,14 +6,50 @@ class ServerSet {
|
|||
if (!unreachable_neighbors || typeof unreachable_neighbors.queryUnreachable !== 'function' || typeof unreachable_neighbors.unreachable !== 'function') {
|
||||
throw new Error('no unreachable_neighbors')
|
||||
}
|
||||
this.servers = servers;
|
||||
this.servers = [... new Set(servers)] // deduplicate
|
||||
this.unreachable_neighbors = unreachable_neighbors;
|
||||
}
|
||||
|
||||
add(server) {
|
||||
console.log('adding server', server)
|
||||
if (!server || typeof server !== 'string') {
|
||||
throw new Error('server must be a string')
|
||||
}
|
||||
if (server in this.servers) {
|
||||
console.log('server already in set', server)
|
||||
return
|
||||
}
|
||||
this.servers.push(server);
|
||||
}
|
||||
|
||||
async get(auth, target) {
|
||||
if (!auth || typeof auth.buildAuthHeader !== 'function') {
|
||||
throw new Error('no auth')
|
||||
}
|
||||
for (const server of this.servers) {
|
||||
try {
|
||||
if (this.unreachable_neighbors.queryUnreachable(server)) {
|
||||
continue
|
||||
}
|
||||
const url = "http://" + server + target // TODO https
|
||||
return await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
...auth.buildAuthHeader(url)
|
||||
},
|
||||
credentials: 'omit'
|
||||
}).catch(err => {
|
||||
console.error('get from server failed', server, err)
|
||||
this.unreachable_neighbors.unreachable(server)
|
||||
}
|
||||
).then(response => response.json())
|
||||
} catch (e) {
|
||||
console.error('get from server failed', server, e)
|
||||
}
|
||||
}
|
||||
throw new Error('all servers failed')
|
||||
}
|
||||
|
||||
async post(auth, target, data) {
|
||||
if (!auth || typeof auth.buildAuthHeader !== 'function') {
|
||||
throw new Error('no auth')
|
||||
|
|
@ -32,7 +68,10 @@ class ServerSet {
|
|||
},
|
||||
credentials: 'omit',
|
||||
body: JSON.stringify(data)
|
||||
}).catch(err => this.unreachable_neighbors.unreachable(server)
|
||||
}).catch(err => {
|
||||
console.error('post to server failed', server, err)
|
||||
this.unreachable_neighbors.unreachable(server)
|
||||
}
|
||||
).then(response => response.json())
|
||||
} catch (e) {
|
||||
console.error('post to server failed', server, e)
|
||||
|
|
@ -59,7 +98,10 @@ class ServerSet {
|
|||
},
|
||||
credentials: 'omit',
|
||||
body: JSON.stringify(data)
|
||||
}).catch(err => this.unreachable_neighbors.unreachable(server)
|
||||
}).catch(err => {
|
||||
console.error('patch to server failed', server, err)
|
||||
this.unreachable_neighbors.unreachable(server)
|
||||
}
|
||||
).then(response => response.json())
|
||||
} catch (e) {
|
||||
console.error('patch to server failed', server, e)
|
||||
|
|
@ -68,56 +110,6 @@ class ServerSet {
|
|||
throw new Error('all servers failed')
|
||||
}
|
||||
|
||||
async get(auth, target) {
|
||||
if (!auth || typeof auth.buildAuthHeader !== 'function') {
|
||||
throw new Error('no auth')
|
||||
}
|
||||
for (const server of this.servers) {
|
||||
try {
|
||||
if (this.unreachable_neighbors.queryUnreachable(server)) {
|
||||
continue
|
||||
}
|
||||
const url = "http://" + server + target // TODO https
|
||||
return await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
...auth.buildAuthHeader(url)
|
||||
},
|
||||
credentials: 'omit'
|
||||
}).catch(err => this.unreachable_neighbors.unreachable(server)
|
||||
).then(response => response.json())
|
||||
} catch (e) {
|
||||
console.error('get from server failed', server, e)
|
||||
}
|
||||
}
|
||||
throw new Error('all servers failed')
|
||||
}
|
||||
|
||||
async delete(auth, target) {
|
||||
if (!auth || typeof auth.buildAuthHeader !== 'function') {
|
||||
throw new Error('no auth')
|
||||
}
|
||||
for (const server of this.servers) {
|
||||
try {
|
||||
if (this.unreachable_neighbors.queryUnreachable(server)) {
|
||||
continue
|
||||
}
|
||||
const url = "http://" + server + target // TODO https
|
||||
return await fetch(url, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
...auth.buildAuthHeader(url)
|
||||
},
|
||||
credentials: 'omit'
|
||||
}).catch(err => this.unreachable_neighbors.unreachable(server)
|
||||
).then(response => response.json())
|
||||
} catch (e) {
|
||||
console.error('delete from server failed', server, e)
|
||||
}
|
||||
}
|
||||
throw new Error('all servers failed')
|
||||
}
|
||||
|
||||
async put(auth, target, data) {
|
||||
if (!auth || typeof auth.buildAuthHeader !== 'function') {
|
||||
throw new Error('no auth')
|
||||
|
|
@ -136,7 +128,10 @@ class ServerSet {
|
|||
},
|
||||
credentials: 'omit',
|
||||
body: JSON.stringify(data)
|
||||
}).catch(err => this.unreachable_neighbors.unreachable(server)
|
||||
}).catch(err => {
|
||||
console.error('put to server failed', server, err)
|
||||
this.unreachable_neighbors.unreachable(server)
|
||||
}
|
||||
).then(response => response.json())
|
||||
} catch (e) {
|
||||
console.error('put to server failed', server, e)
|
||||
|
|
@ -144,8 +139,107 @@ class ServerSet {
|
|||
}
|
||||
throw new Error('all servers failed')
|
||||
}
|
||||
|
||||
async delete(auth, target) {
|
||||
if (!auth || typeof auth.buildAuthHeader !== 'function') {
|
||||
throw new Error('no auth')
|
||||
}
|
||||
for (const server of this.servers) {
|
||||
try {
|
||||
if (this.unreachable_neighbors.queryUnreachable(server)) {
|
||||
continue
|
||||
}
|
||||
const url = "http://" + server + target // TODO https
|
||||
return await fetch(url, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
...auth.buildAuthHeader(url)
|
||||
},
|
||||
credentials: 'omit'
|
||||
}).catch(err => {
|
||||
console.error('delete from server failed', server, err)
|
||||
this.unreachable_neighbors.unreachable(server)
|
||||
}
|
||||
)
|
||||
} catch (e) {
|
||||
console.error('delete from server failed', server, e)
|
||||
}
|
||||
}
|
||||
throw new Error('all servers failed')
|
||||
}
|
||||
}
|
||||
|
||||
class ServerSetUnion {
|
||||
constructor(serverSets) {
|
||||
if (!serverSets || !Array.isArray(serverSets)) {
|
||||
throw new Error('no serverSets')
|
||||
}
|
||||
this.serverSets = serverSets;
|
||||
}
|
||||
|
||||
add(serverset) {
|
||||
if (!serverset || !(serverset instanceof ServerSet)) {
|
||||
throw new Error('no serverset')
|
||||
}
|
||||
if (this.serverSets.find(s => serverset.servers.every(s2 => s.servers.includes(s2)))) {
|
||||
console.warn('serverset already in union', serverset)
|
||||
return
|
||||
}
|
||||
this.serverSets.push(serverset)
|
||||
}
|
||||
|
||||
async post(auth, target, data) {
|
||||
try {
|
||||
return await this.serverSets.reduce(async (acc, serverset) => {
|
||||
return await serverset.post(auth, target, data)
|
||||
}, Promise.resolve())
|
||||
} catch (e) {
|
||||
throw new Error('all servers failed')
|
||||
}
|
||||
}
|
||||
|
||||
async patch(auth, target, data) {
|
||||
try {
|
||||
return await this.serverSets.reduce(async (acc, serverset) => {
|
||||
return await serverset.patch(auth, target, data)
|
||||
}, Promise.resolve())
|
||||
} catch (e) {
|
||||
throw new Error('all servers failed')
|
||||
}
|
||||
}
|
||||
|
||||
async get(auth, target) {
|
||||
try {
|
||||
return await this.serverSets.reduce(async (acc, serverset) => {
|
||||
return await serverset.get(auth, target)
|
||||
}, Promise.resolve())
|
||||
} catch (e) {
|
||||
throw new Error('all servers failed')
|
||||
}
|
||||
}
|
||||
|
||||
async delete(auth, target) {
|
||||
try {
|
||||
return await this.serverSets.reduce(async (acc, serverset) => {
|
||||
return await serverset.delete(auth, target)
|
||||
}, Promise.resolve())
|
||||
} catch (e) {
|
||||
throw new Error('all servers failed')
|
||||
}
|
||||
}
|
||||
|
||||
async put(auth, target, data) {
|
||||
try {
|
||||
return await this.serverSets.reduce(async (acc, serverset) => {
|
||||
return await serverset.put(auth, target, data)
|
||||
}, Promise.resolve())
|
||||
} catch (e) {
|
||||
throw new Error('all servers failed')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class authMethod {
|
||||
constructor(method, auth) {
|
||||
this.method = method;
|
||||
|
|
@ -167,7 +261,6 @@ function createSignAuth(username, signKey) {
|
|||
return new authMethod(({signKey, username}, {url, data}) => {
|
||||
const json = JSON.stringify(data)
|
||||
const signature = nacl.crypto_sign_detached(nacl.encode_utf8(url + (data ? json : "")), signKey)
|
||||
console.log('sign', nacl.to_hex(signature), url, json)
|
||||
return {'Authorization': 'Signature ' + username + ':' + nacl.to_hex(signature)}
|
||||
}, context)
|
||||
}
|
||||
|
|
@ -188,6 +281,6 @@ function createNullAuth() {
|
|||
}, {})
|
||||
}
|
||||
|
||||
export {ServerSet, createSignAuth, createTokenAuth, createNullAuth};
|
||||
export {ServerSet, ServerSetUnion, createSignAuth, createTokenAuth, createNullAuth};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue