{"version":3,"sources":["jsdelivr-header.js","/npm/fortune-http@1.2.28/lib/index.js"],"names":[],"mappings":"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","file":"/npm/fortune-http@1.2.28/lib/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.19.2.\n * Original file: /npm/fortune-http@1.2.28/lib/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","'use strict'\n\nvar zlib = require('zlib')\nvar crc32 = (require('@node-rs/crc32')).crc32\nvar Negotiator = require('negotiator')\n\nvar HttpSerializer = require('./serializer')\nvar jsonSerializer = require('./json_serializer')\nvar htmlSerializer = require('./html_serializer')\nvar HttpFormSerializer = require('./form_serializer')\nvar statusMapFn = require('./status_map')\nvar instantiateSerializer = require('./instantiate_serializer')\n\nvar beforeSemicolon = /[^;]*/\nvar availableEncodings = [ 'gzip', 'deflate' ]\nvar payloadMethods = [ 'POST', 'PATCH', 'PUT' ]\nvar buffer = Buffer.from || Buffer\n\n\n/**\n * **Node.js only**: This function implements a HTTP server for Fortune.\n *\n * ```js\n * const http = require('http')\n * const fortuneHTTP = require('fortune-http')\n *\n * const listener = fortuneHTTP(fortuneInstance, options)\n * const server = http.createServer((request, response) =>\n *   listener(request, response)\n *   .catch(error => {\n *     // error logging\n *   }))\n * ```\n *\n * It determines which serializer to use, assigns request headers\n * to the `meta` object, reads the request body, and maps the response from\n * the `request` method on to the HTTP response. The listener function ends the\n * response and returns a promise that is resolved when the response is ended.\n * The returned promise may be rejected with the error response, providing a\n * hook for error logging.\n *\n * The options object may be formatted as follows:\n *\n * ```js\n * {\n *   // An array of HTTP serializers, ordered by priority. Defaults to ad hoc\n *   // JSON and form serializers if none are specified. If a serializer value\n *   // is not an array, its settings will be considered omitted.\n *   serializers: [\n *     [\n *       // A function that subclasses the HTTP Serializer.\n *       HttpSerializerSubclass,\n *\n *       // Settings to pass to the constructor, optional.\n *       { ... }\n *     ]\n *   ],\n *   settings: {\n *     // By default, the listener will end the response, set this to `false`\n *     // if the response will be ended later.\n *     endResponse: true,\n *\n *     // Use compression if the request `Accept-Encoding` header allows it.\n *     // Note that Buffer-typed responses will not be compressed. This option\n *     // should be disabled in case of a reverse proxy which handles\n *     // compression.\n *     useCompression: true,\n *\n *     // Use built-in ETag implementation, which uses CRC32 for generating\n *     // weak ETags under the hood. This option should be disabled in case of\n *     // a reverse proxy which handles ETags.\n *     useETag: true,\n *\n *     // Ensure that the request is sent at an acceptable rate, to prevent\n *     // abusive slow requests. This is given in terms of kilobits per second\n *     // (kbps). Default: `28.8`, based on slow modem speed.\n *     minimumRateKBPS: 28.8,\n *\n *     // Ensure that requests can not be larger than a specific size, to\n *     // prevent abusive large requests. This is given in terms of megabytes\n *     // (MB). Default: `2`, based on unformatted 3.5\" floppy disk capacity.\n *     // Use a falsy value to turn this off (not recommended).\n *     maximumSizeMB: 2,\n *\n *     // How often to check for request rate in milliseconds (ms).\n *     // Default: 3000.\n *     rateCheckMS: 3000\n *   }\n * }\n * ```\n *\n * The main export contains the following keys:\n *\n * - `Serializer`: HTTP Serializer class.\n * - `JsonSerializer`: JSON over HTTP serializer.\n * - `HtmlSerializer`: HTML serializer.\n * - `FormDataSerializer`: Serializer for `multipart/formdata`.\n * - `FormUrlEncodedSerializer`: Serializer for\n *   `application/x-www-form-urlencoded`.\n * - `instantiateSerializer`: an internal function with the signature\n *   (`instance`, `serializer`, `options`), useful if one needs to get an\n *   instance of the serializer without the HTTP listener.\n *\n * @param {Fortune} instance\n * @param {Object} [options]\n * @return {Function}\n */\nfunction createListener (instance, options) {\n  var mediaTypes = []\n  var serializers = {}\n  var serializer, input\n  var settings, endResponse, useCompression, useETag\n  var minimumRate, maximumSize, rateCheckMS, minimumRateSize\n  var errors, nativeErrors\n  var BadRequestError, UnsupportedError, NotAcceptableError\n  var assign, message, responses, statusMap\n  var i, j\n\n  if (!instance.request || !instance.common)\n    throw new TypeError('An instance of Fortune is required.')\n\n  assign = instance.common.assign\n  message = instance.message || instance.common.message\n  responses = instance.common.responses\n  statusMap = statusMapFn(responses)\n\n  errors = instance.common.errors\n  nativeErrors = errors.nativeErrors\n  BadRequestError = errors.BadRequestError\n  UnsupportedError = errors.UnsupportedError\n  NotAcceptableError = errors.NotAcceptableError\n\n  if (options === void 0) options = {}\n  if (!('serializers' in options))\n    options.serializers = [\n      jsonSerializer(HttpSerializer),\n      htmlSerializer(HttpSerializer),\n      HttpFormSerializer.formData,\n      HttpFormSerializer.formUrlEncoded\n    ]\n  if (!('settings' in options)) options.settings = {}\n  settings = options.settings\n\n  if (!options.serializers.length)\n    throw new Error('At least one serializer must be defined.')\n\n  for (i = 0, j = options.serializers.length; i < j; i++) {\n    input = Array.isArray(options.serializers[i]) ?\n      options.serializers[i] : [ options.serializers[i] ]\n\n    serializer = instantiateSerializer(\n      instance, input[0], input[1], serializers)\n    serializers[serializer.mediaType] = serializer\n    mediaTypes.push(serializer.mediaType)\n  }\n\n  endResponse = 'endResponse' in settings ? settings.endResponse : true\n  useETag = 'useETag' in settings ? settings.useETag : true\n  useCompression = 'useCompression' in settings ?\n    settings.useCompression : true\n\n  // Values are converted from bits to bytes, since buffer lengths are\n  // measured in bytes.\n  minimumRate = 'minimumRateKBPS' in settings ?\n    settings.minimumRateKBPS * Math.pow(2, 3) : 28.8 * Math.pow(2, 3)\n\n  // Convert from MB to bytes.\n  maximumSize = 'maximumSizeMB' in settings ?\n    settings.maximumSizeMB * Math.pow(2, 20) : 2 * Math.pow(2, 20)\n\n  rateCheckMS = 'rateCheckMS' in settings ?\n    settings.rateCheckMS : 3000\n\n  minimumRateSize = Math.floor(minimumRate / (rateCheckMS / 1000))\n\n  // Expose HTTP status code map.\n  listener.statusMap = statusMap\n\n  return listener\n\n  // We can take advantage of the closure which has a reference to the\n  // Fortune instance.\n  function listener (request, response) {\n    var encoding, payload, isProcessing, contextResponse\n    var negotiator, language, serializerOutput, serializerInput, contextRequest\n\n    negotiator = new Negotiator(request)\n    language = negotiator.language()\n\n    // Using Negotiator to get the highest priority media type.\n    serializerOutput = negotiator.mediaType(mediaTypes)\n\n    // Get the media type of the request.\n    // See RFC 2045: https://www.ietf.org/rfc/rfc2045.txt\n    serializerInput = beforeSemicolon\n      .exec(request.headers['content-type'] || '')[0] || null\n\n    // Invalid media type requested. The `undefined` return value comes from\n    // the Negotiator library.\n    if (serializerOutput === void 0)\n      serializerOutput = negotiator.mediaType()\n\n    if (serializerOutput)\n      response.setHeader('Content-Type', serializerOutput)\n\n    if (useCompression) {\n      encoding = negotiator.encoding(availableEncodings)\n      if (encoding) response.setHeader('Content-Encoding', encoding)\n    }\n\n    // Set status code to obscure value meaning server not implemented,\n    // which we can check later if it should be overwritten or not.\n    response.statusCode = 501\n\n    // Initialize the request object.\n    contextRequest = {\n      meta: {\n        serializerInput: serializerInput,\n        serializerOutput: serializerOutput,\n        request: request,\n        headers: request.headers,\n        language: language\n      }\n    }\n\n    return (!serializers.hasOwnProperty(serializerOutput) ?\n      Promise.reject(new NotAcceptableError(message(\n        'SerializerNotFound', language, { id: serializerOutput }))) :\n      new Promise(function (resolve, reject) {\n        var chunks, previousLength, currentLength\n        var requestLength, rateInterval\n\n        if (!~payloadMethods.indexOf(request.method) &&\n          !('content-length' in request.headers))\n          return resolve()\n\n        // All requests with payloads expected must have a\n        // Content-Length header.\n        if (!('content-length' in request.headers)) {\n          response.statusCode = 411\n          return reject(Error())\n        }\n\n        // Read the request body before continuing.\n        requestLength = parseInt(request.headers['content-length'], 10)\n\n        if (requestLength === 0) return resolve()\n\n        if (requestLength > maximumSize) {\n          response.statusCode = 413\n          return reject(Error())\n        }\n\n        chunks = []\n        previousLength = 0\n        currentLength = 0\n        rateInterval = setInterval(function () {\n          if (currentLength - previousLength < minimumRateSize) {\n            clearInterval(rateInterval)\n            response.statusCode = 408\n            reject(Error())\n          }\n          else previousLength = currentLength\n        }, rateCheckMS)\n\n        request.on('error', function (error) {\n          response.setHeader('Content-Type', 'text/plain')\n          error.payload = message('InvalidBody', language)\n          Object.defineProperty(error, 'isInputError', { value: true })\n          reject(error)\n        })\n\n        request.on('data', function (chunk) {\n          currentLength += chunk.length\n          if (currentLength > maximumSize) {\n            response.statusCode = 413\n            reject(Error())\n          }\n          chunks.push(buffer(chunk))\n        })\n\n        request.on('end', function () {\n          clearInterval(rateInterval)\n          resolve(Buffer.concat(chunks))\n        })\n\n        return null\n      }))\n\n      .then(function (body) {\n        if (body && body.length) payload = body\n\n        return serializers[serializerOutput]\n          .processRequest(contextRequest, request, response)\n      })\n\n      .then(function (result) {\n        if (result) contextRequest = result\n        if (!serializerInput) return contextRequest\n\n        if (!serializers.hasOwnProperty(serializerInput))\n          throw new UnsupportedError(message(\n            'SerializerNotFound', language, { id: serializerInput }))\n\n        contextRequest.payload = payload\n\n        return Promise.resolve()\n          .then(function () {\n            return payload && payload.length ?\n              serializers[serializerInput]\n                .parsePayload(contextRequest, request, response) : null\n          })\n          .then(function (result) {\n            if (result) contextRequest.payload = result\n            return contextRequest\n          }, function (error) {\n            Object.defineProperty(error, 'isInputError', { value: true })\n            throw error\n          })\n      })\n\n      .then(function (contextRequest) {\n        return instance.request(contextRequest)\n      })\n\n      .then(function (result) {\n        contextResponse = result\n        isProcessing = true\n\n        return serializers[serializerOutput]\n          .processResponse(contextResponse, request, response)\n      })\n\n      .then(function (result) {\n        return end(result || contextResponse, request, response)\n      })\n\n      .catch(function (error) {\n        var exposedError = error\n\n        return Promise.resolve()\n          .then(function () {\n            if (!('payload' in error || 'meta' in error) &&\n              ~nativeErrors.indexOf(error.constructor)) {\n              if (contextResponse) delete contextResponse.payload\n              exposedError = assign(error.isInputError ?\n                new BadRequestError(message('InvalidBody', language)) :\n                new Error(message('GenericError', language)),\n              contextResponse)\n            }\n\n            return !isProcessing &&\n              serializers.hasOwnProperty(serializerOutput) ?\n              serializers[serializerOutput]\n                .processResponse(exposedError, request, response) :\n              exposedError\n          })\n          .then(function (result) {\n            return end(result || exposedError, request, response)\n          }, function () {\n            return end(new Error(message('GenericError', language)),\n              request, response)\n          })\n          .then(function () {\n            // Do not reject exceptions that result in non-error status codes.\n            if (response.statusCode < 400) return error\n\n            throw error\n          })\n      })\n  }\n\n  // Internal function to end the response.\n  function end (contextResponse, request, response) {\n    var encoding, payload, meta\n\n    if (!('meta' in contextResponse)) contextResponse.meta = {}\n    if (!('headers' in contextResponse.meta)) contextResponse.meta.headers = {}\n    meta = contextResponse.meta\n    payload = contextResponse.payload\n\n    // Expose response object downstream.\n    meta.response = response\n\n    if (response.statusCode === 501)\n      response.statusCode = statusMap.get(contextResponse.constructor) ||\n        statusMap.get(Error)\n\n    return new Promise(function (resolve, reject) {\n      if (Buffer.isBuffer(payload) || typeof payload === 'string') {\n        encoding = response.getHeader('content-encoding')\n\n        if (encoding && ~availableEncodings.indexOf(encoding))\n          return zlib[encoding](payload, function (error, result) {\n            if (error) throw error\n            payload = contextResponse.payload = result\n            response.setHeader('Content-Length', String(payload.length))\n            return resolve()\n          })\n\n        response.removeHeader('content-encoding')\n        payload = contextResponse.payload = buffer(payload)\n        response.setHeader('Content-Length', String(payload.length))\n        return resolve()\n      }\n\n      if (payload) {\n        response.statusCode = statusMap.get(Error)\n        return reject(new Error('Response payload type is invalid.'))\n      }\n\n      // Handle empty response.\n      response.removeHeader('content-encoding')\n      response.removeHeader('content-type')\n      if (response.statusCode === statusMap.get(responses.OK))\n        response.statusCode = (statusMap.get(responses.Empty))\n      payload = contextResponse.payload = ''\n      return resolve()\n    })\n      .then(function () {\n        var field, etag\n\n        for (field in meta.headers)\n          response.setHeader(field, meta.headers[field])\n\n        if (useETag && payload) {\n          etag = 'W/' + crc32(payload).toString(16)\n          response.setHeader('ETag', etag)\n\n          if (!endResponse) return contextResponse\n\n          if (request.headers['if-none-match'] === etag) {\n            response.statusCode = 304\n            response.removeHeader('content-encoding')\n            response.removeHeader('content-type')\n            response.removeHeader('content-length')\n            response.writeHead(response.statusCode, response.headers)\n\n            // Ignore error if client doesn't receive response.\n            response.end()\n\n            return contextResponse\n          }\n        }\n\n        else if (!endResponse) return contextResponse\n\n        response.writeHead(response.statusCode, response.headers)\n\n        // Ignore error if client doesn't receive response.\n        response.end(payload.length ? payload : contextResponse.toString())\n\n        return contextResponse\n      })\n      .catch(function (error) {\n        var message = error.toString()\n\n        if (response.statusCode === 501)\n          response.statusCode = statusMap.get(Error)\n\n        response.removeHeader('content-encoding')\n\n        if (message) {\n          response.setHeader('Content-Type', 'text/plain')\n          response.setHeader('Content-Length', Buffer.byteLength(message))\n        }\n\n        response.writeHead(response.statusCode, response.headers)\n\n        // Ignore error if client doesn't receive response.\n        response.end(message)\n\n        return error\n      })\n  }\n}\n\n\n// Expose instantiation method.\ncreateListener.instantiateSerializer = instantiateSerializer\n\n// Expose HTTP Serializer class, and defaults.\ncreateListener.Serializer = HttpSerializer\ncreateListener.JsonSerializer = jsonSerializer(HttpSerializer)\ncreateListener.HtmlSerializer = htmlSerializer(HttpSerializer)\ncreateListener.FormDataSerializer = HttpFormSerializer.formData\ncreateListener.FormUrlEncodedSerializer = HttpFormSerializer.formUrlEncoded\n\n\nmodule.exports = createListener\n"]}