Skip to content

Commit

Permalink
refactor: file system plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
reruin committed Jun 9, 2020
1 parent a5e5c83 commit 13fdeb7
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 183 deletions.
6 changes: 6 additions & 0 deletions app/controllers/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const cache = require('../utils/cache')

module.exports = {

/**
* Install index handler
*/
async home(ctx , next){
if(config.installed() ){
ctx.redirect('/')
Expand All @@ -16,6 +19,9 @@ module.exports = {
}
}
,
/**
* Save config handler
*/
async save(ctx){
let { token , name , path , vendor , title = 'ShareList'} = ctx.request.body
let cfg = {token , title}
Expand Down
23 changes: 23 additions & 0 deletions app/controllers/manage.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ const cache = require('../utils/cache')
const { getVendors , reload } = require('../services/plugin')
const service = require('../services/sharelist')

/**
* Hanlders hub
*
* @param {string} [a] action
* @param {object} [body] formdata
* @param {object} [ctx] ctx
* @return {object}
*/
const handlers = async (a, body , ctx) => {
let result = { status: 0, message: 'Success', data: '', a }

Expand Down Expand Up @@ -144,6 +152,9 @@ const handlers = async (a, body , ctx) => {

module.exports = {

/**
* Manage page index handler
*/
async home(ctx, next) {

let token = ctx.request.body.token
Expand All @@ -162,6 +173,9 @@ module.exports = {

},

/**
* API router handler
*/
async api(ctx) {

let body = ctx.request.body
Expand Down Expand Up @@ -210,6 +224,9 @@ module.exports = {

},

/**
* Shell page handler
*/
async shell(ctx){
let access = !!ctx.session.admin
if(access){
Expand All @@ -219,6 +236,12 @@ module.exports = {
}
},

/**
* Shell exection
*
* @param {object} [ctx]
* @return {void}
*/
async shell_exec(ctx){
let body = ctx.request.body
let { command , path = '/' } = body
Expand Down
28 changes: 26 additions & 2 deletions app/controllers/sharelist.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ const qs = require('querystring')
const { sendRedirect } = require('../utils/sendfile')
const { parsePath , pathNormalize , enablePreview, enableRange , isRelativePath , markdownParse , md5 } = require('../utils/base')

const requireAuth = (data) => !!(data.children && data.children.find(i=>(i.name == '.passwd')))

/**
* Check path
*
* @param {string} [path] current path
* @param {array} [paths] allow proxy paths
* @return [boolean]
*/
const isProxyPath = (path , paths) => {
return (
path == '' || path == '/' ||
Expand All @@ -14,6 +19,13 @@ const isProxyPath = (path , paths) => {
) ? true : false
}

/**
* Check download condition
*
* @param {object} [ctx]
* @param {object} [data] folder/file data
* @return [boolean]
*/
const enableDownload = (ctx, data) => {
if(ctx.runtime.isAdmin) return true
let result = true
Expand All @@ -29,6 +41,12 @@ const enableDownload = (ctx, data) => {
return result
}

/**
* Output handler
*
* @param {object} [ctx]
* @param {object} [data] folder/file data
*/
const output = async (ctx , data)=>{

const download = enableDownload(ctx, data)
Expand Down Expand Up @@ -131,6 +149,9 @@ const output = async (ctx , data)=>{
}

module.exports = {
/**
* Index handler
*/
async index(ctx){
let downloadLinkAge = config.getConfig('max_age_download')
let cursign = md5(config.getConfig('max_age_download_sign') + Math.floor(Date.now() / downloadLinkAge))
Expand Down Expand Up @@ -261,6 +282,9 @@ module.exports = {

},

/**
* API handler
*/
async api(ctx){
let ignoreexts = (config.getConfig('ignore_file_extensions') || '').split(',')
let ignorefiles = (config.getConfig('ignore_files') || '').split(',')
Expand Down
143 changes: 78 additions & 65 deletions app/controllers/webdav.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ var virtualFile = {

}

/**
* Webdav props default options
*/
const default_options = {
ns:{
name:'D',
Expand All @@ -24,6 +27,12 @@ const default_options = {
}
}

/**
* Conv date to GMT
*
* @param {string} [d]
* @return {mixed}
*/
const dateFormat = (d) => {
let nd = new Date(d)
if (nd instanceof Date && !isNaN(nd)) {
Expand All @@ -33,6 +42,17 @@ const dateFormat = (d) => {
}
}

/**
* Create webdav xml response
*
* @param {object} [data]
* @param {object} [options]
* @param {object} [optiosn.props]
* @param {object} [optiosn.ns]
* @param {string} [optiosn.ns.name]
* @param {string} [optiosn.ns.value]
* @return {string} XML string
*/
const propsCreate = (data, options) => {
let out = ''
let { props, ns: { name, value } } = options
Expand Down Expand Up @@ -71,6 +91,12 @@ const propsCreate = (data, options) => {
return out
}

/**
* Parse prop from webdab request
*
* @param {object} [data]
* @return {object}
*/
const propfindParse = (data, ns) => {
if(!data){
return default_options
Expand Down Expand Up @@ -98,6 +124,12 @@ const propfindParse = (data, ns) => {
}
}

/**
* Parse props from webdav request
*
* @param {object} [data]
* @return {object|boolean}
*/
const nsParse = (data) => {
if(!data) return false

Expand All @@ -116,8 +148,16 @@ const nsParse = (data) => {
return false
}


//<?xml version="1.0" encoding="utf-8" ?> <D:multistatus xmlns:D='DAV:'> <D:response> <D:href>http://www.domain.example.com/public/</D:href> <D:propstat> <D:prop> <D:lockdiscovery> <D:activelock> <D:locktype><D:write/></D:locktype> <D:lockscope><D:exclusive/></D:lockscope> <D:depth>0</D:depth> <D:owner>James Smith</D:owner> <D:timeout>Infinite</D:timeout> <D:locktoken> <D:href>opaquelocktoken:f81de2ad-7f3d-a1b3-4f3c-00a0c91a9d76</D:href> </D:locktoken> </D:activelock> </D:lockdiscovery> </D:prop> <D:status>HTTP/1.1 200 OK</D:status> </D:propstat> </D:response> </D:multistatus>
/**
* Create webdav responese xml by data and props options
*
* @param {object} [data] file data
* @param {object} [options]
* @param {object} [options.props] Available props
* @param {object} [options.path] Current folder path
* @param {object} [options.ns]
* @return {string} XML string
*/
const respCreate = (data, options) => {
let { props, path, ns: { name, value } } = options

Expand All @@ -136,51 +176,27 @@ const respCreate = (data, options) => {

body += `</${xmlns}multistatus>`
body = body.replace(/^\s+/g,'').replace(/[\r\n]/g,'')
// console.log(body)
/*return `<?xml version="1.0" encoding="utf-8" ?>
<D:multistatus xmlns:D="DAV:">
<D:response>
<D:href>/%E6%BC%94%E7%A4%BA%E7%9B%AE%E5%BD%95/example/filesystem_windows_disk_c/Users/abcdef</D:href>
<D:propstat>
<D:status>HTTP/1.1 200 OK</D:status>
<D:prop>
<D:getlastmodified>Mon, 25 Feb 2019 12:20:01 GMT</D:getlastmodified>
<D:getcontentlength>100</D:getcontentlength>
<D:creationdate>Mon, 25 Feb 2019 12:20:01 GMT</D:creationdate>
<D:resourcetype>
<D:collection />
</D:resourcetype>
<D:displayname>你好</D:displayname>
</D:prop>
</D:propstat>
</D:response>
<D:response>
<D:href>/%E6%BC%94%E7%A4%BA%E7%9B%AE%E5%BD%95/example/filesystem_windows_disk_c/Users/abcdef2</D:href>
<D:propstat>
<D:status>HTTP/1.1 200 OK</D:status>
<D:prop>
<D:getlastmodified>Mon, 25 Feb 2019 12:20:01 GMT</D:getlastmodified>
<D:getcontentlength>100</D:getcontentlength>
<D:creationdate>Mon, 25 Feb 2019 12:20:01 GMT</D:creationdate>
<D:resourcetype>
<D:collection />
</D:resourcetype>
<D:displayname>你好2</D:displayname>
</D:prop>
</D:propstat>
</D:response>
</D:multistatus>`*/
return body
}

class Request {
/**
* Initialize a new Request for WebDAV
*
* @param {Object} ctx
*/
constructor(ctx) {
this.ctx = ctx
this.davPoweredBy = null
this.httpAuthRealm = "ShareList WebDAV"
this.allows = ['GET', 'PUT', 'HEAD', 'OPTIONS', 'PROPFIND']
}

/**
* Execute handler
*
* @api private
*/
async exec(){
let { ctx } = this

Expand All @@ -205,16 +221,36 @@ class Request {
return false
}
}

/**
* Set header
*
* @param {string} [k] key
* @param {string} [v] value
* @return void
*/
setHeader(k, v) {
this.ctx.set(k, v)
}

/**
* Set body
*
* @param {mixed} [body]
* @return void
*/
setBody(body) {
this.ctx.type = 'text/xml; charset="utf-8"'
this.setHeader('Content-Length', body.length);
this.ctx.body = body
}

/**
* Set body status
*
* @param {string|boolean} [status]
* @return void
*/
setStatus(status) {
if (status === true) {
status = "200 OK"
Expand All @@ -225,6 +261,12 @@ class Request {
this.setHeader('X-WebDAV-Status', status)
}

/**
* OPTIONS method
*
* @param void
* @return void
*/
async http_options() {

const allows = this.allows
Expand Down Expand Up @@ -308,35 +350,6 @@ class Request {
async http_get() {
await api(this.ctx)
}
/*
//create
async http_put() {
let ret = await api(this.ctx)
this.setStatus("200 Success")
}
// put时 webdav 将lock文件 此方法没有实现
async http_lock(){
if( !virtualFile[this.ctx.path] ){
virtualFile[this.ctx.path] = {}
}
virtualFile[this.ctx.path]['locked'] = true
this.setStatus("200 Success")
this.setBody(`<?xml version="1.0" encoding="utf-8" ?> <D:multistatus xmlns:D='DAV:'> <D:response> <D:href>${this.ctx.path}</D:href> <D:propstat> <D:prop> <D:lockdiscovery> <D:activelock> <D:locktype><D:write/></D:locktype> <D:lockscope><D:exclusive/></D:lockscope> <D:depth>0</D:depth> <D:owner>ShareList</D:owner> <D:timeout>Infinite</D:timeout> <D:locktoken> <D:href>opaquelocktoken:f81de2ad-7f3d-a1b3-4f3c-00a0c91a9d76</D:href> </D:locktoken> </D:activelock> </D:lockdiscovery> </D:prop> <D:status>HTTP/1.1 200 OK</D:status> </D:propstat> </D:response> </D:multistatus>`)
}
async http_unlock(){
if( !virtualFile[this.ctx.path] ){
virtualFile[this.ctx.path] = {}
}
virtualFile[this.ctx.path]['locked'] = false
this.setStatus("200 Success")
}
*/

/*
http_head() {}
Expand Down
Loading

0 comments on commit 13fdeb7

Please sign in to comment.