You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							147 lines
						
					
					
						
							3.3 KiB
						
					
					
				
			
		
		
	
	
							147 lines
						
					
					
						
							3.3 KiB
						
					
					
				'use strict'
 | 
						|
 | 
						|
const { validate: validateSchema } = require('./validation')
 | 
						|
const { hookRunner, hookIterator } = require('./hooks')
 | 
						|
const wrapThenable = require('./wrapThenable')
 | 
						|
 | 
						|
const { kReplyIsError } = require('./symbols')
 | 
						|
 | 
						|
function handleRequest (err, request, reply) {
 | 
						|
  if (reply.sent === true) return
 | 
						|
  if (err != null) {
 | 
						|
    reply.send(err)
 | 
						|
    return
 | 
						|
  }
 | 
						|
 | 
						|
  const method = request.raw.method
 | 
						|
  const headers = request.headers
 | 
						|
 | 
						|
  if (method === 'GET' || method === 'HEAD') {
 | 
						|
    handler(request, reply)
 | 
						|
    return
 | 
						|
  }
 | 
						|
 | 
						|
  const contentType = headers['content-type']
 | 
						|
 | 
						|
  if (method === 'POST' || method === 'PUT' || method === 'PATCH') {
 | 
						|
    if (contentType === undefined) {
 | 
						|
      if (
 | 
						|
        headers['transfer-encoding'] === undefined &&
 | 
						|
        (headers['content-length'] === '0' || headers['content-length'] === undefined)
 | 
						|
      ) { // Request has no body to parse
 | 
						|
        handler(request, reply)
 | 
						|
      } else {
 | 
						|
        reply.context.contentTypeParser.run('', handler, request, reply)
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      reply.context.contentTypeParser.run(contentType, handler, request, reply)
 | 
						|
    }
 | 
						|
    return
 | 
						|
  }
 | 
						|
 | 
						|
  if (method === 'OPTIONS' || method === 'DELETE') {
 | 
						|
    if (
 | 
						|
      contentType !== undefined &&
 | 
						|
      (
 | 
						|
        headers['transfer-encoding'] !== undefined ||
 | 
						|
        headers['content-length'] !== undefined
 | 
						|
      )
 | 
						|
    ) {
 | 
						|
      reply.context.contentTypeParser.run(contentType, handler, request, reply)
 | 
						|
    } else {
 | 
						|
      handler(request, reply)
 | 
						|
    }
 | 
						|
    return
 | 
						|
  }
 | 
						|
 | 
						|
  // Return 404 instead of 405 see https://github.com/fastify/fastify/pull/862 for discussion
 | 
						|
  reply.code(404).send(new Error('Not Found'))
 | 
						|
}
 | 
						|
 | 
						|
function handler (request, reply) {
 | 
						|
  try {
 | 
						|
    if (reply.context.preValidation !== null) {
 | 
						|
      hookRunner(
 | 
						|
        reply.context.preValidation,
 | 
						|
        hookIterator,
 | 
						|
        request,
 | 
						|
        reply,
 | 
						|
        preValidationCallback
 | 
						|
      )
 | 
						|
    } else {
 | 
						|
      preValidationCallback(null, request, reply)
 | 
						|
    }
 | 
						|
  } catch (err) {
 | 
						|
    preValidationCallback(err, request, reply)
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function preValidationCallback (err, request, reply) {
 | 
						|
  if (reply.sent === true ||
 | 
						|
    reply.raw.writableEnded === true ||
 | 
						|
    reply.raw.writable === false) return
 | 
						|
 | 
						|
  if (err != null) {
 | 
						|
    reply.send(err)
 | 
						|
    return
 | 
						|
  }
 | 
						|
 | 
						|
  const result = validateSchema(reply.context, request)
 | 
						|
  if (result) {
 | 
						|
    if (reply.context.attachValidation === false) {
 | 
						|
      reply.code(400).send(result)
 | 
						|
      return
 | 
						|
    }
 | 
						|
 | 
						|
    reply.request.validationError = result
 | 
						|
  }
 | 
						|
 | 
						|
  // preHandler hook
 | 
						|
  if (reply.context.preHandler !== null) {
 | 
						|
    hookRunner(
 | 
						|
      reply.context.preHandler,
 | 
						|
      hookIterator,
 | 
						|
      request,
 | 
						|
      reply,
 | 
						|
      preHandlerCallback
 | 
						|
    )
 | 
						|
  } else {
 | 
						|
    preHandlerCallback(null, request, reply)
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function preHandlerCallback (err, request, reply) {
 | 
						|
  if (reply.sent ||
 | 
						|
    reply.raw.writableEnded === true ||
 | 
						|
    reply.raw.writable === false) return
 | 
						|
 | 
						|
  if (err != null) {
 | 
						|
    reply.send(err)
 | 
						|
    return
 | 
						|
  }
 | 
						|
 | 
						|
  let result
 | 
						|
 | 
						|
  try {
 | 
						|
    result = reply.context.handler(request, reply)
 | 
						|
  } catch (err) {
 | 
						|
    if (!(err instanceof Error)) {
 | 
						|
      reply[kReplyIsError] = true
 | 
						|
    }
 | 
						|
 | 
						|
    reply.send(err)
 | 
						|
    return
 | 
						|
  }
 | 
						|
 | 
						|
  if (result !== undefined) {
 | 
						|
    if (result !== null && typeof result.then === 'function') {
 | 
						|
      wrapThenable(result, reply)
 | 
						|
    } else {
 | 
						|
      reply.send(result)
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
module.exports = handleRequest
 | 
						|
module.exports[Symbol.for('internals')] = { handler, preHandlerCallback }
 |