CoolFace
Apppublic

strong-tie/inbound-calls

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
handleRequest.js187 linesDownload Raw Back to lib
1'use strict'2 3const diagnostics = require('node:diagnostics_channel')4const { validate: validateSchema } = require('./validation')5const { preValidationHookRunner, preHandlerHookRunner } = require('./hooks')6const wrapThenable = require('./wrapThenable')7const {8  kReplyIsError,9  kRouteContext,10  kFourOhFourContext,11  kSupportedHTTPMethods12} = require('./symbols')13 14const channels = diagnostics.tracingChannel('fastify.request.handler')15 16function handleRequest (err, request, reply) {17  if (reply.sent === true) return18  if (err != null) {19    reply[kReplyIsError] = true20    reply.send(err)21    return22  }23 24  const method = request.raw.method25  const headers = request.headers26  const context = request[kRouteContext]27 28  if (this[kSupportedHTTPMethods].bodyless.has(method)) {29    handler(request, reply)30    return31  }32 33  if (this[kSupportedHTTPMethods].bodywith.has(method)) {34    const contentType = headers['content-type']35    const contentLength = headers['content-length']36    const transferEncoding = headers['transfer-encoding']37 38    if (contentType === undefined) {39      if (40        (contentLength === undefined || contentLength === '0') &&41        transferEncoding === undefined42      ) {43        // Request has no body to parse44        handler(request, reply)45      } else {46        context.contentTypeParser.run('', handler, request, reply)47      }48    } else {49      if (contentLength === undefined && transferEncoding === undefined && method === 'OPTIONS') {50        // OPTIONS can have a Content-Type header without a body51        handler(request, reply)52        return53      }54      context.contentTypeParser.run(contentType, handler, request, reply)55    }56    return57  }58 59  // Return 404 instead of 405 see https://github.com/fastify/fastify/pull/862 for discussion60  handler(request, reply)61}62 63function handler (request, reply) {64  try {65    if (request[kRouteContext].preValidation !== null) {66      preValidationHookRunner(67        request[kRouteContext].preValidation,68        request,69        reply,70        preValidationCallback71      )72    } else {73      preValidationCallback(null, request, reply)74    }75  } catch (err) {76    preValidationCallback(err, request, reply)77  }78}79 80function preValidationCallback (err, request, reply) {81  if (reply.sent === true) return82 83  if (err != null) {84    reply[kReplyIsError] = true85    reply.send(err)86    return87  }88 89  const validationErr = validateSchema(reply[kRouteContext], request)90  const isAsync = (validationErr && typeof validationErr.then === 'function') || false91 92  if (isAsync) {93    const cb = validationCompleted.bind(null, request, reply)94    validationErr.then(cb, cb)95  } else {96    validationCompleted(request, reply, validationErr)97  }98}99 100function validationCompleted (request, reply, validationErr) {101  if (validationErr) {102    if (reply[kRouteContext].attachValidation === false) {103      reply.send(validationErr)104      return105    }106 107    reply.request.validationError = validationErr108  }109 110  // preHandler hook111  if (request[kRouteContext].preHandler !== null) {112    preHandlerHookRunner(113      request[kRouteContext].preHandler,114      request,115      reply,116      preHandlerCallback117    )118  } else {119    preHandlerCallback(null, request, reply)120  }121}122 123function preHandlerCallback (err, request, reply) {124  if (reply.sent) return125 126  const context = request[kRouteContext]127 128  if (!channels.hasSubscribers || context[kFourOhFourContext] === null) {129    preHandlerCallbackInner(err, request, reply)130  } else {131    const store = {132      request,133      reply,134      async: false,135      route: {136        url: context.config.url,137        method: context.config.method138      }139    }140    channels.start.runStores(store, preHandlerCallbackInner, undefined, err, request, reply, store)141  }142}143 144function preHandlerCallbackInner (err, request, reply, store) {145  const context = request[kRouteContext]146 147  try {148    if (err != null) {149      reply[kReplyIsError] = true150      reply.send(err)151      if (store) {152        store.error = err153        channels.error.publish(store)154      }155      return156    }157 158    let result159 160    try {161      result = context.handler(request, reply)162    } catch (err) {163      if (store) {164        store.error = err165        channels.error.publish(store)166      }167 168      reply[kReplyIsError] = true169      reply.send(err)170      return171    }172 173    if (result !== undefined) {174      if (result !== null && typeof result.then === 'function') {175        wrapThenable(result, reply, store)176      } else {177        reply.send(result)178      }179    }180  } finally {181    if (store) channels.end.publish(store)182  }183}184 185module.exports = handleRequest186module.exports[Symbol.for('internals')] = { handler, preHandlerCallback }187