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 }
 |