From 23d290aa67a5eb64ed5909dfa3f222a08dd51e45 Mon Sep 17 00:00:00 2001 From: Yuvi Panda Date: Wed, 12 Aug 2020 15:37:11 +0000 Subject: [PATCH] fix(command-dev): handle missing content-type header (#1083) --- src/commands/dev/index.js | 8 ++++---- tests/command.dev.test.js | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/commands/dev/index.js b/src/commands/dev/index.js index 71bfe6b9e0f..ed1eb9b0bbc 100644 --- a/src/commands/dev/index.js +++ b/src/commands/dev/index.js @@ -214,11 +214,11 @@ async function startProxy(settings = {}, addonUrls, configPath, projectDir, func if (match) return serveRedirect(req, res, proxy, match, options) - const ct = req.headers['content-type'] ? contentType.parse(req) : {} + const ct = req.headers['content-type'] ? contentType.parse(req).type : '' if ( req.method === 'POST' && !isInternal(req.url) && - (ct.type.endsWith('/x-www-form-urlencoded') || ct.type === 'multipart/form-data') + (ct.endsWith('/x-www-form-urlencoded') || ct === 'multipart/form-data') ) { return proxy.web(req, res, { target: functionsServer }) } @@ -338,12 +338,12 @@ async function serveRedirect(req, res, proxy, match, options) { return handler(req, res, {}) } - const ct = req.headers['content-type'] ? contentType.parse(req) : {} + const ct = req.headers['content-type'] ? contentType.parse(req).type : '' if ( req.method === 'POST' && !isInternal(req.url) && !isInternal(destURL) && - (ct.type.endsWith('/x-www-form-urlencoded') || ct.type === 'multipart/form-data') + (ct.endsWith('/x-www-form-urlencoded') || ct === 'multipart/form-data') ) { return proxy.web(req, res, { target: options.functionsServer }) } diff --git a/tests/command.dev.test.js b/tests/command.dev.test.js index 3b3f31f53bb..17273d78e69 100644 --- a/tests/command.dev.test.js +++ b/tests/command.dev.test.js @@ -764,3 +764,42 @@ test('should redirect requests to an external server', async t => { server.close() }) }) + +test('should redirect POST request if content-type is missing', async t => { + await withSiteBuilder('site-with-post-no-content-type', async builder => { + builder.withNetlifyToml({ + config: { + build: { functions: 'functions' }, + redirects: [{ from: '/api/*', to: '/other/:splat', status: 200 }], + }, + }) + + await builder.buildAsync() + + await withDevServer({ cwd: builder.directory }, async server => { + // we use http.request since fetch automatically sends a content-type header + const http = require('http') + const options = { + host: server.host, + port: server.port, + path: '/api/echo', + method: 'POST', + } + let data = '' + await new Promise(resolve => { + const callback = response => { + response.on('data', chunk => { + data += chunk + }) + response.on('end', resolve) + } + const req = http.request(options, callback) + req.write('param=value') + req.end() + }) + + // we're testing Netlify Dev didn't crash + t.is(data, 'Method Not Allowed') + }) + }) +})