ACIL FM
Dark
Refresh
Current DIR:
/home/benbot/bot/server/node_modules/send
/
home
benbot
bot
server
node_modules
send
Upload
Zip Selected
Delete Selected
Pilih semua
Nama
Ukuran
Permission
Aksi
HISTORY.md
14.45 MB
chmod
View
DL
Edit
Rename
Delete
index.js
19.86 MB
chmod
View
DL
Edit
Rename
Delete
LICENSE
1.1 MB
chmod
View
DL
Edit
Rename
Delete
package.json
1.55 MB
chmod
View
DL
Edit
Rename
Delete
README.md
8.85 MB
chmod
View
DL
Edit
Rename
Delete
Edit file: /home/benbot/bot/server/node_modules/send/index.js
/*! * send * Copyright(c) 2012 TJ Holowaychuk * Copyright(c) 2014-2022 Douglas Christopher Wilson * MIT Licensed */ 'use strict' /** * Module dependencies. * @private */ var createError = require('http-errors') var debug = require('debug')('send') var encodeUrl = require('encodeurl') var escapeHtml = require('escape-html') var etag = require('etag') var fresh = require('fresh') var fs = require('fs') var mime = require('mime-types') var ms = require('ms') var onFinished = require('on-finished') var parseRange = require('range-parser') var path = require('path') var statuses = require('statuses') var Stream = require('stream') var util = require('util') /** * Path function references. * @private */ var extname = path.extname var join = path.join var normalize = path.normalize var resolve = path.resolve var sep = path.sep /** * Regular expression for identifying a bytes Range header. * @private */ var BYTES_RANGE_REGEXP = /^ *bytes=/ /** * Maximum value allowed for the max age. * @private */ var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1000 // 1 year /** * Regular expression to match a path with a directory up component. * @private */ var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/ /** * Module exports. * @public */ module.exports = send /** * Return a `SendStream` for `req` and `path`. * * @param {object} req * @param {string} path * @param {object} [options] * @return {SendStream} * @public */ function send (req, path, options) { return new SendStream(req, path, options) } /** * Initialize a `SendStream` with the given `path`. * * @param {Request} req * @param {String} path * @param {object} [options] * @private */ function SendStream (req, path, options) { Stream.call(this) var opts = options || {} this.options = opts this.path = path this.req = req this._acceptRanges = opts.acceptRanges !== undefined ? Boolean(opts.acceptRanges) : true this._cacheControl = opts.cacheControl !== undefined ? Boolean(opts.cacheControl) : true this._etag = opts.etag !== undefined ? Boolean(opts.etag) : true this._dotfiles = opts.dotfiles !== undefined ? opts.dotfiles : 'ignore' if (this._dotfiles !== 'ignore' && this._dotfiles !== 'allow' && this._dotfiles !== 'deny') { throw new TypeError('dotfiles option must be "allow", "deny", or "ignore"') } this._extensions = opts.extensions !== undefined ? normalizeList(opts.extensions, 'extensions option') : [] this._immutable = opts.immutable !== undefined ? Boolean(opts.immutable) : false this._index = opts.index !== undefined ? normalizeList(opts.index, 'index option') : ['index.html'] this._lastModified = opts.lastModified !== undefined ? Boolean(opts.lastModified) : true this._maxage = opts.maxAge || opts.maxage this._maxage = typeof this._maxage === 'string' ? ms(this._maxage) : Number(this._maxage) this._maxage = !isNaN(this._maxage) ? Math.min(Math.max(0, this._maxage), MAX_MAXAGE) : 0 this._root = opts.root ? resolve(opts.root) : null } /** * Inherits from `Stream`. */ util.inherits(SendStream, Stream) /** * Emit error with `status`. * * @param {number} status * @param {Error} [err] * @private */ SendStream.prototype.error = function error (status, err) { // emit if listeners instead of responding if (hasListeners(this, 'error')) { return this.emit('error', createHttpError(status, err)) } var res = this.res var msg = statuses.message[status] || String(status) var doc = createHtmlDocument('Error', escapeHtml(msg)) // clear existing headers clearHeaders(res) // add error headers if (err && err.headers) { setHeaders(res, err.headers) } // send basic response res.statusCode = status res.setHeader('Content-Type', 'text/html; charset=UTF-8') res.setHeader('Content-Length', Buffer.byteLength(doc)) res.setHeader('Content-Security-Policy', "default-src 'none'") res.setHeader('X-Content-Type-Options', 'nosniff') res.end(doc) } /** * Check if the pathname ends with "/". * * @return {boolean} * @private */ SendStream.prototype.hasTrailingSlash = function hasTrailingSlash () { return this.path[this.path.length - 1] === '/' } /** * Check if this is a conditional GET request. * * @return {Boolean} * @api private */ SendStream.prototype.isConditionalGET = function isConditionalGET () { return this.req.headers['if-match'] || this.req.headers['if-unmodified-since'] || this.req.headers['if-none-match'] || this.req.headers['if-modified-since'] } /** * Check if the request preconditions failed. * * @return {boolean} * @private */ SendStream.prototype.isPreconditionFailure = function isPreconditionFailure () { var req = this.req var res = this.res // if-match var match = req.headers['if-match'] if (match) { var etag = res.getHeader('ETag') return !etag || (match !== '*' && parseTokenList(match).every(function (match) { return match !== etag && match !== 'W/' + etag && 'W/' + match !== etag })) } // if-unmodified-since var unmodifiedSince = parseHttpDate(req.headers['if-unmodified-since']) if (!isNaN(unmodifiedSince)) { var lastModified = parseHttpDate(res.getHeader('Last-Modified')) return isNaN(lastModified) || lastModified > unmodifiedSince } return false } /** * Strip various content header fields for a change in entity. * * @private */ SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields () { var res = this.res res.removeHeader('Content-Encoding') res.removeHeader('Content-Language') res.removeHeader('Content-Length') res.removeHeader('Content-Range') res.removeHeader('Content-Type') } /** * Respond with 304 not modified. * * @api private */ SendStream.prototype.notModified = function notModified () { var res = this.res debug('not modified') this.removeContentHeaderFields() res.statusCode = 304 res.end() } /** * Raise error that headers already sent. * * @api private */ SendStream.prototype.headersAlreadySent = function headersAlreadySent () { var err = new Error('Can\'t set headers after they are sent.') debug('headers already sent') this.error(500, err) } /** * Check if the request is cacheable, aka * responded with 2xx or 304 (see RFC 2616 section 14.2{5,6}). * * @return {Boolean} * @api private */ SendStream.prototype.isCachable = function isCachable () { var statusCode = this.res.statusCode return (statusCode >= 200 && statusCode < 300) || statusCode === 304 } /** * Handle stat() error. * * @param {Error} error * @private */ SendStream.prototype.onStatError = function onStatError (error) { switch (error.code) { case 'ENAMETOOLONG': case 'ENOENT': case 'ENOTDIR': this.error(404, error) break default: this.error(500, error) break } } /** * Check if the cache is fresh. * * @return {Boolean} * @api private */ SendStream.prototype.isFresh = function isFresh () { return fresh(this.req.headers, { etag: this.res.getHeader('ETag'), 'last-modified': this.res.getHeader('Last-Modified') }) } /** * Check if the range is fresh. * * @return {Boolean} * @api private */ SendStream.prototype.isRangeFresh = function isRangeFresh () { var ifRange = this.req.headers['if-range'] if (!ifRange) { return true } // if-range as etag if (ifRange.indexOf('"') !== -1) { var etag = this.res.getHeader('ETag') return Boolean(etag && ifRange.indexOf(etag) !== -1) } // if-range as modified date var lastModified = this.res.getHeader('Last-Modified') return parseHttpDate(lastModified) <= parseHttpDate(ifRange) } /** * Redirect to path. * * @param {string} path * @private */ SendStream.prototype.redirect = function redirect (path) { var res = this.res if (hasListeners(this, 'directory')) { this.emit('directory', res, path) return } if (this.hasTrailingSlash()) { this.error(403) return } var loc = encodeUrl(collapseLeadingSlashes(this.path + '/')) var doc = createHtmlDocument('Redirecting', 'Redirecting to ' + escapeHtml(loc)) // redirect res.statusCode = 301 res.setHeader('Content-Type', 'text/html; charset=UTF-8') res.setHeader('Content-Length', Buffer.byteLength(doc)) res.setHeader('Content-Security-Policy', "default-src 'none'") res.setHeader('X-Content-Type-Options', 'nosniff') res.setHeader('Location', loc) res.end(doc) } /** * Pipe to `res. * * @param {Stream} res * @return {Stream} res * @api public */ SendStream.prototype.pipe = function pipe (res) { // root path var root = this._root // references this.res = res // decode the path var path = decode(this.path) if (path === -1) { this.error(400) return res } // null byte(s) if (~path.indexOf('\0')) { this.error(400) return res } var parts if (root !== null) { // normalize if (path) { path = normalize('.' + sep + path) } // malicious path if (UP_PATH_REGEXP.test(path)) { debug('malicious path "%s"', path) this.error(403) return res } // explode path parts parts = path.split(sep) // join / normalize from optional root dir path = normalize(join(root, path)) } else { // ".." is malicious without "root" if (UP_PATH_REGEXP.test(path)) { debug('malicious path "%s"', path) this.error(403) return res } // explode path parts parts = normalize(path).split(sep) // resolve the path path = resolve(path) } // dotfile handling if (containsDotFile(parts)) { debug('%s dotfile "%s"', this._dotfiles, path) switch (this._dotfiles) { case 'allow': break case 'deny': this.error(403) return res case 'ignore': default: this.error(404) return res } } // index file support if (this._index.length && this.hasTrailingSlash()) { this.sendIndex(path) return res } this.sendFile(path) return res } /** * Transfer `path`. * * @param {String} path * @api public */ SendStream.prototype.send = function send (path, stat) { var len = stat.size var options = this.options var opts = {} var res = this.res var req = this.req var ranges = req.headers.range var offset = options.start || 0 if (res.headersSent) { // impossible to send now this.headersAlreadySent() return } debug('pipe "%s"', path) // set header fields this.setHeader(path, stat) // set content-type this.type(path) // conditional GET support if (this.isConditionalGET()) { if (this.isPreconditionFailure()) { this.error(412) return } if (this.isCachable() && this.isFresh()) { this.notModified() return } } // adjust len to start/end options len = Math.max(0, len - offset) if (options.end !== undefined) { var bytes = options.end - offset + 1 if (len > bytes) len = bytes } // Range support if (this._acceptRanges && BYTES_RANGE_REGEXP.test(ranges)) { // parse ranges = parseRange(len, ranges, { combine: true }) // If-Range support if (!this.isRangeFresh()) { debug('range stale') ranges = -2 } // unsatisfiable if (ranges === -1) { debug('range unsatisfiable') // Content-Range res.setHeader('Content-Range', contentRange('bytes', len)) // 416 Requested Range Not Satisfiable return this.error(416, { headers: { 'Content-Range': res.getHeader('Content-Range') } }) } // valid (syntactically invalid/multiple ranges are treated as a regular response) if (ranges !== -2 && ranges.length === 1) { debug('range %j', ranges) // Content-Range res.statusCode = 206 res.setHeader('Content-Range', contentRange('bytes', len, ranges[0])) // adjust for requested range offset += ranges[0].start len = ranges[0].end - ranges[0].start + 1 } } // clone options for (var prop in options) { opts[prop] = options[prop] } // set read options opts.start = offset opts.end = Math.max(offset, offset + len - 1) // content-length res.setHeader('Content-Length', len) // HEAD support if (req.method === 'HEAD') { res.end() return } this.stream(path, opts) } /** * Transfer file for `path`. * * @param {String} path * @api private */ SendStream.prototype.sendFile = function sendFile (path) { var i = 0 var self = this debug('stat "%s"', path) fs.stat(path, function onstat (err, stat) { var pathEndsWithSep = path[path.length - 1] === sep if (err && err.code === 'ENOENT' && !extname(path) && !pathEndsWithSep) { // not found, check extensions return next(err) } if (err) return self.onStatError(err) if (stat.isDirectory()) return self.redirect(path) if (pathEndsWithSep) return self.error(404) self.emit('file', path, stat) self.send(path, stat) }) function next (err) { if (self._extensions.length <= i) { return err ? self.onStatError(err) : self.error(404) } var p = path + '.' + self._extensions[i++] debug('stat "%s"', p) fs.stat(p, function (err, stat) { if (err) return next(err) if (stat.isDirectory()) return next() self.emit('file', p, stat) self.send(p, stat) }) } } /** * Transfer index for `path`. * * @param {String} path * @api private */ SendStream.prototype.sendIndex = function sendIndex (path) { var i = -1 var self = this function next (err) { if (++i >= self._index.length) { if (err) return self.onStatError(err) return self.error(404) } var p = join(path, self._index[i]) debug('stat "%s"', p) fs.stat(p, function (err, stat) { if (err) return next(err) if (stat.isDirectory()) return next() self.emit('file', p, stat) self.send(p, stat) }) } next() } /** * Stream `path` to the response. * * @param {String} path * @param {Object} options * @api private */ SendStream.prototype.stream = function stream (path, options) { var self = this var res = this.res // pipe var stream = fs.createReadStream(path, options) this.emit('stream', stream) stream.pipe(res) // cleanup function cleanup () { stream.destroy() } // response finished, cleanup onFinished(res, cleanup) // error handling stream.on('error', function onerror (err) { // clean up stream early cleanup() // error self.onStatError(err) }) // end stream.on('end', function onend () { self.emit('end') }) } /** * Set content-type based on `path` * if it hasn't been explicitly set. * * @param {String} path * @api private */ SendStream.prototype.type = function type (path) { var res = this.res if (res.getHeader('Content-Type')) return var ext = extname(path) var type = mime.contentType(ext) || 'application/octet-stream' debug('content-type %s', type) res.setHeader('Content-Type', type) } /** * Set response header fields, most * fields may be pre-defined. * * @param {String} path * @param {Object} stat * @api private */ SendStream.prototype.setHeader = function setHeader (path, stat) { var res = this.res this.emit('headers', res, path, stat) if (this._acceptRanges && !res.getHeader('Accept-Ranges')) { debug('accept ranges') res.setHeader('Accept-Ranges', 'bytes') } if (this._cacheControl && !res.getHeader('Cache-Control')) { var cacheControl = 'public, max-age=' + Math.floor(this._maxage / 1000) if (this._immutable) { cacheControl += ', immutable' } debug('cache-control %s', cacheControl) res.setHeader('Cache-Control', cacheControl) } if (this._lastModified && !res.getHeader('Last-Modified')) { var modified = stat.mtime.toUTCString() debug('modified %s', modified) res.setHeader('Last-Modified', modified) } if (this._etag && !res.getHeader('ETag')) { var val = etag(stat) debug('etag %s', val) res.setHeader('ETag', val) } } /** * Clear all headers from a response. * * @param {object} res * @private */ function clearHeaders (res) { for (const header of res.getHeaderNames()) { res.removeHeader(header) } } /** * Collapse all leading slashes into a single slash * * @param {string} str * @private */ function collapseLeadingSlashes (str) { for (var i = 0; i < str.length; i++) { if (str[i] !== '/') { break } } return i > 1 ? '/' + str.substr(i) : str } /** * Determine if path parts contain a dotfile. * * @api private */ function containsDotFile (parts) { for (var i = 0; i < parts.length; i++) { var part = parts[i] if (part.length > 1 && part[0] === '.') { return true } } return false } /** * Create a Content-Range header. * * @param {string} type * @param {number} size * @param {array} [range] */ function contentRange (type, size, range) { return type + ' ' + (range ? range.start + '-' + range.end : '*') + '/' + size } /** * Create a minimal HTML document. * * @param {string} title * @param {string} body * @private */ function createHtmlDocument (title, body) { return '<!DOCTYPE html>\n' + '<html lang="en">\n' + '<head>\n' + '<meta charset="utf-8">\n' + '<title>' + title + '</title>\n' + '</head>\n' + '<body>\n' + '<pre>' + body + '</pre>\n' + '</body>\n' + '</html>\n' } /** * Create a HttpError object from simple arguments. * * @param {number} status * @param {Error|object} err * @private */ function createHttpError (status, err) { if (!err) { return createError(status) } return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err) } /** * decodeURIComponent. * * Allows V8 to only deoptimize this fn instead of all * of send(). * * @param {String} path * @api private */ function decode (path) { try { return decodeURIComponent(path) } catch (err) { return -1 } } /** * Determine if emitter has listeners of a given type. * * The way to do this check is done three different ways in Node.js >= 0.10 * so this consolidates them into a minimal set using instance methods. * * @param {EventEmitter} emitter * @param {string} type * @returns {boolean} * @private */ function hasListeners (emitter, type) { var count = typeof emitter.listenerCount !== 'function' ? emitter.listeners(type).length : emitter.listenerCount(type) return count > 0 } /** * Normalize the index option into an array. * * @param {boolean|string|array} val * @param {string} name * @private */ function normalizeList (val, name) { var list = [].concat(val || []) for (var i = 0; i < list.length; i++) { if (typeof list[i] !== 'string') { throw new TypeError(name + ' must be array of strings or false') } } return list } /** * Parse an HTTP Date into a number. * * @param {string} date * @private */ function parseHttpDate (date) { var timestamp = date && Date.parse(date) return typeof timestamp === 'number' ? timestamp : NaN } /** * Parse a HTTP token list. * * @param {string} str * @private */ function parseTokenList (str) { var end = 0 var list = [] var start = 0 // gather tokens for (var i = 0, len = str.length; i < len; i++) { switch (str.charCodeAt(i)) { case 0x20: /* */ if (start === end) { start = end = i + 1 } break case 0x2c: /* , */ if (start !== end) { list.push(str.substring(start, end)) } start = end = i + 1 break default: end = i + 1 break } } // final token if (start !== end) { list.push(str.substring(start, end)) } return list } /** * Set an object of headers on a response. * * @param {object} res * @param {object} headers * @private */ function setHeaders (res, headers) { var keys = Object.keys(headers) for (var i = 0; i < keys.length; i++) { var key = keys[i] res.setHeader(key, headers[key]) } }
Simpan
Batal
Isi Zip:
Unzip
Create
Buat Folder
Buat File
Terminal / Execute
Run
Chmod Bulk
All File
All Folder
All File dan Folder
Apply