!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache/2.4.41 (Ubuntu). PHP/8.0.30 

uname -a: Linux apirnd 5.4.0-204-generic #224-Ubuntu SMP Thu Dec 5 13:38:28 UTC 2024 x86_64 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/usr/local/lib/node_modules/homebridge-config-ui-x/node_modules/fastify/lib/   drwxr-xr-x
Free 13.09 GB of 57.97 GB (22.58%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     reply.js (20.15 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
'use strict'

const eos = require('stream').finished
const statusCodes = require('http').STATUS_CODES
const flatstr = require('flatstr')
const FJS = require('fast-json-stringify')
const {
  kSchemaResponse,
  kFourOhFourContext,
  kReplyErrorHandlerCalled,
  kReplySent,
  kReplySentOverwritten,
  kReplyStartTime,
  kReplyEndTime,
  kReplySerializer,
  kReplySerializerDefault,
  kReplyIsError,
  kReplyHeaders,
  kReplyHasStatusCode,
  kReplyIsRunningOnErrorHook,
  kDisableRequestLogging
} = require('./symbols.js')
const { hookRunner, hookIterator, onSendHookRunner } = require('./hooks')

const internals = require('./handleRequest')[Symbol.for('internals')]
const loggerUtils = require('./logger')
const now = loggerUtils.now
const wrapThenable = require('./wrapThenable')

const serializeError = FJS({
  type: 'object',
  properties: {
    statusCode: { type: 'number' },
    code: { type: 'string' },
    error: { type: 'string' },
    message: { type: 'string' }
  }
})

const CONTENT_TYPE = {
  JSON: 'application/json; charset=utf-8',
  PLAIN: 'text/plain; charset=utf-8',
  OCTET: 'application/octet-stream'
}
const {
  FST_ERR_REP_INVALID_PAYLOAD_TYPE,
  FST_ERR_REP_ALREADY_SENT,
  FST_ERR_REP_SENT_VALUE,
  FST_ERR_SEND_INSIDE_ONERR,
  FST_ERR_BAD_STATUS_CODE
} = require('./errors')
const warning = require('./warnings')

function Reply (res, request, log) {
  this.raw = res
  this[kReplySent] = false
  this[kReplySerializer] = null
  this[kReplyErrorHandlerCalled] = false
  this[kReplyIsError] = false
  this[kReplyIsRunningOnErrorHook] = false
  this.request = request
  this[kReplyHeaders] = {}
  this[kReplyHasStatusCode] = false
  this[kReplyStartTime] = undefined
  this.log = log
}
Reply.props = []

Object.defineProperties(Reply.prototype, {
  context: {
    get () {
      return this.request.context
    }
  },
  res: {
    get () {
      warning.emit('FSTDEP002')
      return this.raw
    }
  },
  sent: {
    enumerable: true,
    get () {
      return this[kReplySent]
    },
    set (value) {
      if (value !== true) {
        throw new FST_ERR_REP_SENT_VALUE()
      }

      if (this[kReplySent]) {
        throw new FST_ERR_REP_ALREADY_SENT()
      }

      this[kReplySentOverwritten] = true
      this[kReplySent] = true
    }
  },
  statusCode: {
    get () {
      return this.raw.statusCode
    },
    set (value) {
      this.code(value)
    }
  },
  server: {
    value: null,
    writable: true
  }
})

Reply.prototype.hijack = function () {
  this[kReplySent] = true
  return this
}

Reply.prototype.send = function (payload) {
  if (this[kReplyIsRunningOnErrorHook] === true) {
    throw new FST_ERR_SEND_INSIDE_ONERR()
  }

  if (this[kReplySent]) {
    this.log.warn({ err: new FST_ERR_REP_ALREADY_SENT() }, 'Reply already sent')
    return this
  }

  if (payload instanceof Error || this[kReplyIsError] === true) {
    onErrorHook(this, payload, onSendHook)
    return this
  }

  if (payload === undefined) {
    onSendHook(this, payload)
    return this
  }

  const contentType = this.getHeader('content-type')
  const hasContentType = contentType !== undefined

  if (payload !== null) {
    if (Buffer.isBuffer(payload) || typeof payload.pipe === 'function') {
      if (hasContentType === false) {
        this[kReplyHeaders]['content-type'] = CONTENT_TYPE.OCTET
      }
      onSendHook(this, payload)
      return this
    }

    if (hasContentType === false && typeof payload === 'string') {
      this[kReplyHeaders]['content-type'] = CONTENT_TYPE.PLAIN
      onSendHook(this, payload)
      return this
    }
  }

  if (this[kReplySerializer] !== null) {
    if (typeof payload !== 'string') {
      preserializeHook(this, payload)
      return this
    } else {
      payload = this[kReplySerializer](payload)
    }

  // The indexOf below also matches custom json mimetypes such as 'application/hal+json' or 'application/ld+json'
  } else if (hasContentType === false || contentType.indexOf('json') > -1) {
    if (hasContentType === false) {
      this[kReplyHeaders]['content-type'] = CONTENT_TYPE.JSON
    } else {
      // If hasContentType === true, we have a JSON mimetype
      if (contentType.indexOf('charset') === -1) {
        // If we have simply application/json instead of a custom json mimetype
        if (contentType.indexOf('/json') > -1) {
          this[kReplyHeaders]['content-type'] = CONTENT_TYPE.JSON
        } else {
          const currContentType = this[kReplyHeaders]['content-type']
          // We extract the custom mimetype part (e.g. 'hal+' from 'application/hal+json')
          const customJsonType = currContentType.substring(
            currContentType.indexOf('/'),
            currContentType.indexOf('json') + 4
          )

          // We ensure we set the header to the proper JSON content-type if necessary
          // (e.g. 'application/hal+json' instead of 'application/json')
          this[kReplyHeaders]['content-type'] = CONTENT_TYPE.JSON.replace('/json', customJsonType)
        }
      }
    }
    if (typeof payload !== 'string') {
      preserializeHook(this, payload)
      return this
    }
  }

  onSendHook(this, payload)

  return this
}

Reply.prototype.getHeader = function (key) {
  key = key.toLowerCase()
  const res = this.raw
  let value = this[kReplyHeaders][key]
  if (value === undefined && res.hasHeader(key)) {
    value = res.getHeader(key)
  }
  return value
}

Reply.prototype.getHeaders = function () {
  return {
    ...this.raw.getHeaders(),
    ...this[kReplyHeaders]
  }
}

Reply.prototype.hasHeader = function (key) {
  key = key.toLowerCase()
  if (this[kReplyHeaders][key] !== undefined) {
    return true
  }
  return this.raw.hasHeader(key)
}

Reply.prototype.removeHeader = function (key) {
  // Node.js does not like headers with keys set to undefined,
  // so we have to delete the key.
  delete this[kReplyHeaders][key.toLowerCase()]
  return this
}

Reply.prototype.header = function (key, value) {
  const _key = key.toLowerCase()

  // default the value to ''
  value = value === undefined ? '' : value

  if (this[kReplyHeaders][_key] && _key === 'set-cookie') {
    // https://tools.ietf.org/html/rfc7230#section-3.2.2
    if (typeof this[kReplyHeaders][_key] === 'string') {
      this[kReplyHeaders][_key] = [this[kReplyHeaders][_key]]
    }
    if (Array.isArray(value)) {
      Array.prototype.push.apply(this[kReplyHeaders][_key], value)
    } else {
      this[kReplyHeaders][_key].push(value)
    }
  } else {
    this[kReplyHeaders][_key] = value
  }
  return this
}

Reply.prototype.headers = function (headers) {
  const keys = Object.keys(headers)
  /* eslint-disable no-var */
  for (var i = 0; i !== keys.length; ++i) {
    const key = keys[i]
    this.header(key, headers[key])
  }
  return this
}

Reply.prototype.code = function (code) {
  const intValue = parseInt(code)
  if (isNaN(intValue) || intValue < 100 || intValue > 600) {
    throw new FST_ERR_BAD_STATUS_CODE(code || String(code))
  }

  this.raw.statusCode = intValue
  this[kReplyHasStatusCode] = true
  return this
}

Reply.prototype.status = Reply.prototype.code

Reply.prototype.serialize = function (payload) {
  if (this[kReplySerializer] !== null) {
    return this[kReplySerializer](payload)
  } else {
    if (this.context && this.context[kReplySerializerDefault]) {
      return this.context[kReplySerializerDefault](payload, this.raw.statusCode)
    } else {
      return serialize(this.context, payload, this.raw.statusCode)
    }
  }
}

Reply.prototype.serializer = function (fn) {
  this[kReplySerializer] = fn
  return this
}

Reply.prototype.type = function (type) {
  this[kReplyHeaders]['content-type'] = type
  return this
}

Reply.prototype.redirect = function (code, url) {
  if (typeof code === 'string') {
    url = code
    code = this[kReplyHasStatusCode] ? this.raw.statusCode : 302
  }

  this.header('location', url).code(code).send()
}

Reply.prototype.callNotFound = function () {
  notFound(this)
}

Reply.prototype.getResponseTime = function () {
  let responseTime = 0

  if (this[kReplyStartTime] !== undefined) {
    responseTime = (this[kReplyEndTime] || now()) - this[kReplyStartTime]
  }

  return responseTime
}

// Make reply a thenable, so it could be used with async/await.
// See
// - https://github.com/fastify/fastify/issues/1864 for the discussions
// - https://promisesaplus.com/ for the definition of thenable
// - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then for the signature
Reply.prototype.then = function (fulfilled, rejected) {
  if (this.sent) {
    fulfilled()
    return
  }

  eos(this.raw, (err) => {
    // We must not treat ERR_STREAM_PREMATURE_CLOSE as
    // an error because it is created by eos, not by the stream.
    if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {
      if (rejected) {
        rejected(err)
      } else {
        this.log && this.log.warn('unhandled rejection on reply.then')
      }
    } else {
      fulfilled()
    }
  })
}

function preserializeHook (reply, payload) {
  if (reply.context.preSerialization !== null) {
    onSendHookRunner(
      reply.context.preSerialization,
      reply.request,
      reply,
      payload,
      preserializeHookEnd
    )
  } else {
    preserializeHookEnd(null, reply.request, reply, payload)
  }
}

function preserializeHookEnd (err, request, reply, payload) {
  if (err != null) {
    onErrorHook(reply, err)
    return
  }

  if (reply[kReplySerializer] !== null) {
    payload = reply[kReplySerializer](payload)
  } else if (reply.context && reply.context[kReplySerializerDefault]) {
    payload = reply.context[kReplySerializerDefault](payload, reply.raw.statusCode)
  } else {
    payload = serialize(reply.context, payload, reply.raw.statusCode)
  }

  flatstr(payload)

  onSendHook(reply, payload)
}

function onSendHook (reply, payload) {
  if (reply.context.onSend !== null) {
    reply[kReplySent] = true
    onSendHookRunner(
      reply.context.onSend,
      reply.request,
      reply,
      payload,
      wrapOnSendEnd
    )
  } else {
    onSendEnd(reply, payload)
  }
}

function wrapOnSendEnd (err, request, reply, payload) {
  if (err != null) {
    onErrorHook(reply, err)
  } else {
    onSendEnd(reply, payload)
  }
}

function onSendEnd (reply, payload) {
  const res = reply.raw
  const req = reply.request
  const statusCode = res.statusCode

  if (payload === undefined || payload === null) {
    reply[kReplySent] = true

    // according to https://tools.ietf.org/html/rfc7230#section-3.3.2
    // we cannot send a content-length for 304 and 204, and all status code
    // < 200.
    // For HEAD we don't overwrite the `content-length`
    if (statusCode >= 200 && statusCode !== 204 && statusCode !== 304 && req.method !== 'HEAD') {
      reply[kReplyHeaders]['content-length'] = '0'
    }

    res.writeHead(statusCode, reply[kReplyHeaders])
    // avoid ArgumentsAdaptorTrampoline from V8
    res.end(null, null, null)
    return
  }

  if (typeof payload.pipe === 'function') {
    reply[kReplySent] = true

    sendStream(payload, res, reply)
    return
  }

  if (typeof payload !== 'string' && !Buffer.isBuffer(payload)) {
    throw new FST_ERR_REP_INVALID_PAYLOAD_TYPE(typeof payload)
  }

  if (!reply[kReplyHeaders]['content-length']) {
    reply[kReplyHeaders]['content-length'] = '' + Buffer.byteLength(payload)
  } else if (req.raw.method !== 'HEAD' && reply[kReplyHeaders]['content-length'] !== Buffer.byteLength(payload)) {
    reply[kReplyHeaders]['content-length'] = '' + Buffer.byteLength(payload)
  }

  reply[kReplySent] = true

  res.writeHead(statusCode, reply[kReplyHeaders])

  // avoid ArgumentsAdaptorTrampoline from V8
  res.end(payload, null, null)
}

function logStreamError (logger, err, res) {
  if (err.code === 'ERR_STREAM_PREMATURE_CLOSE') {
    if (!logger[kDisableRequestLogging]) {
      logger.info({ res }, 'stream closed prematurely')
    }
  } else {
    logger.warn({ err }, 'response terminated with an error with headers already sent')
  }
}

function sendStream (payload, res, reply) {
  let sourceOpen = true
  let errorLogged = false

  eos(payload, { readable: true, writable: false }, function (err) {
    sourceOpen = false
    if (err != null) {
      if (res.headersSent) {
        if (!errorLogged) {
          errorLogged = true
          logStreamError(reply.log, err, res)
        }
        res.destroy()
      } else {
        onErrorHook(reply, err)
      }
    }
    // there is nothing to do if there is not an error
  })

  eos(res, function (err) {
    if (sourceOpen) {
      if (err != null && res.headersSent && !errorLogged) {
        errorLogged = true
        logStreamError(reply.log, err, res)
      }
      if (typeof payload.destroy === 'function') {
        payload.destroy()
      } else if (typeof payload.close === 'function') {
        payload.close(noop)
      } else if (typeof payload.abort === 'function') {
        payload.abort()
      } else {
        reply.log.warn('stream payload does not end properly')
      }
    }
  })

  // streams will error asynchronously, and we want to handle that error
  // appropriately, e.g. a 404 for a missing file. So we cannot use
  // writeHead, and we need to resort to setHeader, which will trigger
  // a writeHead when there is data to send.
  if (!res.headersSent) {
    for (const key in reply[kReplyHeaders]) {
      res.setHeader(key, reply[kReplyHeaders][key])
    }
  } else {
    reply.log.warn('response will send, but you shouldn\'t use res.writeHead in stream mode')
  }
  payload.pipe(res)
}

function onErrorHook (reply, error, cb) {
  reply[kReplySent] = true
  if (reply.context.onError !== null && reply[kReplyErrorHandlerCalled] === true) {
    reply[kReplyIsRunningOnErrorHook] = true
    onSendHookRunner(
      reply.context.onError,
      reply.request,
      reply,
      error,
      () => handleError(reply, error, cb)
    )
  } else {
    handleError(reply, error, cb)
  }
}

function handleError (reply, error, cb) {
  reply[kReplyIsRunningOnErrorHook] = false
  const res = reply.raw
  let statusCode = res.statusCode
  statusCode = (statusCode >= 400) ? statusCode : 500
  // treat undefined and null as same
  if (error != null) {
    if (error.headers !== undefined) {
      reply.headers(error.headers)
    }
    if (error.status >= 400) {
      statusCode = error.status
    } else if (error.statusCode >= 400) {
      statusCode = error.statusCode
    }
  }

  res.statusCode = statusCode

  const errorHandler = reply.context.errorHandler
  if (errorHandler && reply[kReplyErrorHandlerCalled] === false) {
    reply[kReplySent] = false
    reply[kReplyIsError] = false
    reply[kReplyErrorHandlerCalled] = true
    // remove header is needed in here, because when we pipe to a stream
    // `undefined` value header will directly passed to node response
    reply.removeHeader('content-length')
    const result = errorHandler(error, reply.request, reply)
    if (result !== undefined) {
      if (result !== null && typeof result.then === 'function') {
        wrapThenable(result, reply)
      } else {
        reply.send(result)
      }
    }
    return
  }

  let payload
  try {
    const serializerFn = getSchemaSerializer(reply.context, statusCode)
    payload = (serializerFn === false)
      ? serializeError({
          error: statusCodes[statusCode + ''],
          code: error.code,
          message: error.message || '',
          statusCode: statusCode
        })
      : serializerFn(Object.create(error, {
        error: { value: statusCodes[statusCode + ''] },
        message: { value: error.message || '' },
        statusCode: { value: statusCode }
      }))

    if (serializerFn !== false && typeof payload !== 'string') {
      throw new FST_ERR_REP_INVALID_PAYLOAD_TYPE(typeof payload)
    }
  } catch (err) {
    // error is always FST_ERR_SCH_SERIALIZATION_BUILD because this is called from route/compileSchemasForSerialization
    reply.log.error({ err, statusCode: res.statusCode }, 'The serializer for the given status code failed')
    res.statusCode = 500
    payload = serializeError({
      error: statusCodes['500'],
      code: err.code,
      message: err.message,
      statusCode: 500
    })
  }

  flatstr(payload)
  reply[kReplyHeaders]['content-type'] = CONTENT_TYPE.JSON
  reply[kReplyHeaders]['content-length'] = '' + Buffer.byteLength(payload)

  if (cb) {
    cb(reply, payload)
    return
  }

  reply[kReplySent] = true
  res.writeHead(res.statusCode, reply[kReplyHeaders])
  res.end(payload)
}

function setupResponseListeners (reply) {
  reply[kReplyStartTime] = now()

  const onResFinished = err => {
    reply[kReplyEndTime] = now()
    reply.raw.removeListener('finish', onResFinished)
    reply.raw.removeListener('error', onResFinished)

    const ctx = reply.context

    if (ctx && ctx.onResponse !== null) {
      hookRunner(
        ctx.onResponse,
        onResponseIterator,
        reply.request,
        reply,
        onResponseCallback
      )
    } else {
      onResponseCallback(err, reply.request, reply)
    }
  }

  reply.raw.on('finish', onResFinished)
  reply.raw.on('error', onResFinished)
}

function onResponseIterator (fn, request, reply, next) {
  return fn(request, reply, next)
}

function onResponseCallback (err, request, reply) {
  if (reply.log[kDisableRequestLogging]) {
    return
  }

  const responseTime = reply.getResponseTime()

  if (err != null) {
    reply.log.error({
      res: reply,
      err,
      responseTime
    }, 'request errored')
    return
  }

  reply.log.info({
    res: reply,
    responseTime
  }, 'request completed')
}

function buildReply (R) {
  const props = [...R.props]

  function _Reply (res, request, log) {
    this.raw = res
    this[kReplyIsError] = false
    this[kReplyErrorHandlerCalled] = false
    this[kReplySent] = false
    this[kReplySentOverwritten] = false
    this[kReplySerializer] = null
    this.request = request
    this[kReplyHeaders] = {}
    this[kReplyStartTime] = undefined
    this[kReplyEndTime] = undefined
    this.log = log

    // eslint-disable-next-line no-var
    var prop
    // eslint-disable-next-line no-var
    for (var i = 0; i < props.length; i++) {
      prop = props[i]
      this[prop.key] = prop.value
    }
  }
  _Reply.prototype = new R()
  _Reply.props = props
  return _Reply
}

function notFound (reply) {
  reply[kReplySent] = false
  reply[kReplyIsError] = false

  if (reply.context[kFourOhFourContext] === null) {
    reply.log.warn('Trying to send a NotFound error inside a 404 handler. Sending basic 404 response.')
    reply.code(404).send('404 Not Found')
    return
  }

  reply.request.context = reply.context[kFourOhFourContext]

  // preHandler hook
  if (reply.context.preHandler !== null) {
    hookRunner(
      reply.context.preHandler,
      hookIterator,
      reply.request,
      reply,
      internals.preHandlerCallback
    )
  } else {
    internals.preHandlerCallback(null, reply.request, reply)
  }
}

/**
 * This function runs when a payload that is not a string|buffer|stream or null
 * should be serialized to be streamed to the response.
 * This is the default serializer that can be customized by the user using the replySerializer
 *
 * @param {object} context the request context
 * @param {object} data the JSON payload to serialize
 * @param {number} statusCode the http status code
 * @returns {string} the serialized payload
 */
function serialize (context, data, statusCode) {
  const fnSerialize = getSchemaSerializer(context, statusCode)
  if (fnSerialize) {
    return fnSerialize(data)
  }
  return JSON.stringify(data)
}

/**
 * Search for the right JSON schema compiled function in the request context
 * setup by the route configuration `schema.response`.
 * It will look for the exact match (eg 200) or generic (eg 2xx)
 *
 * @param {object} context the request context
 * @param {number} statusCode the http status code
 * @returns {function|boolean} the right JSON Schema function to serialize
 * the reply or false if it is not set
 */
function getSchemaSerializer (context, statusCode) {
  const responseSchemaDef = context[kSchemaResponse]
  if (!responseSchemaDef) {
    return false
  }
  if (responseSchemaDef[statusCode]) {
    return responseSchemaDef[statusCode]
  }
  const fallbackStatusCode = (statusCode + '')[0] + 'xx'
  if (responseSchemaDef[fallbackStatusCode]) {
    return responseSchemaDef[fallbackStatusCode]
  }
  return false
}

function noop () { }

module.exports = Reply
module.exports.buildReply = buildReply
module.exports.setupResponseListeners = setupResponseListeners

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0057 ]--