Skip to content

Commit

Permalink
Dev: Rewrite for internal URL with SPA servers (#810)
Browse files Browse the repository at this point in the history
* Dev: Rewrite for internal URL with SPA servers

* Dev: Improve tests

* Tests: Remvoe unused required

* Correct the wait time

* Add test for api rewrite rules
  • Loading branch information
RaeesBhatti authored Apr 9, 2020
1 parent 1a2cfd3 commit d501a32
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 58 deletions.
23 changes: 15 additions & 8 deletions src/commands/dev/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ const createRewriter = require('../../utils/rules-proxy')
const { onChanges } = require('../../utils/rules-proxy')
const { parseHeadersFile, objectForPath } = require('../../utils/headers')

function isFunction(functionsPort, req) {
return functionsPort && req.url.match(/^\/.netlify\/functions\/.+/)
function isInternal(url) {
return url.startsWith('/.netlify/')
}
function isFunction(functionsPort, url) {
return functionsPort && url.match(/^\/.netlify\/functions\/.+/)
}

function addonUrl(addonUrls, req) {
Expand Down Expand Up @@ -169,7 +172,7 @@ async function startProxy(settings, addonUrls, configPath, projectDir, functions
})

const server = http.createServer(function(req, res) {
if (isFunction(settings.functionsPort, req)) {
if (isFunction(settings.functionsPort, req.url)) {
return proxy.web(req, res, { target: functionsServer })
}
let urlForAddons = addonUrl(addonUrls, req)
Expand Down Expand Up @@ -213,7 +216,7 @@ function serveRedirect(req, res, proxy, match, options) {
Object.entries(match.proxyHeaders).forEach(([k, v]) => (req.headers[k] = v))
}

if (isFunction(options.functionsPort, req)) {
if (isFunction(options.functionsPort, req.url)) {
return proxy.web(req, res, { target: options.functionsServer })
}
const urlForAddons = addonUrl(options.addonUrls, req)
Expand Down Expand Up @@ -272,7 +275,7 @@ function serveRedirect(req, res, proxy, match, options) {
return render404(options.publicFolder)
}

if (match.force || (!options.serverType && notStatic(reqUrl.pathname, options.publicFolder) && match.status !== 404)) {
if (match.force || (notStatic(reqUrl.pathname, options.publicFolder) && match.status !== 404)) {
const dest = new url.URL(match.to, `${reqUrl.protocol}//${reqUrl.host}`)
if (isRedirect(match)) {
res.writeHead(match.status, {
Expand All @@ -295,10 +298,14 @@ function serveRedirect(req, res, proxy, match, options) {

const urlParams = new URLSearchParams(reqUrl.searchParams)
dest.searchParams.forEach((val, key) => urlParams.set(key, val))
req.url = dest.pathname + (urlParams.toString() && '?' + urlParams.toString())
console.log(`${NETLIFYDEVLOG} Rewrote URL to `, req.url)
const destURL = dest.pathname + (urlParams.toString() && '?' + urlParams.toString())

if (isInternal(destURL) || !options.serverType) {
req.url = destURL
console.log(`${NETLIFYDEVLOG} Rewrote URL to `, req.url)
}

if (isFunction({ functionsPort: options.functionsPort }, req)) {
if (isFunction(options.functionsPort, req.url)) {
req.headers['x-netlify-original-pathname'] = reqUrl.pathname
return proxy.web(req, res, { target: options.functionsServer })
}
Expand Down
67 changes: 17 additions & 50 deletions src/tests/dev.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const path = require('path')
const { spawn } = require('child_process')
const test = require('ava')
const http = require('http')
const fetch = require('node-fetch')
const cliPath = require('./utils/cliPath')
const sitePath = path.join(__dirname, 'dummy-site')

Expand All @@ -15,7 +15,7 @@ test.before(async t => {
['dev'],
{
cwd: sitePath,
env: Object.assign({}, process.env, { DUMMY_VAR: "true" }),
env: { ...process.env, DUMMY_VAR: 'true' },
detached: true,
shell: true,
}
Expand Down Expand Up @@ -47,66 +47,33 @@ test.before(async t => {
})

test('netlify dev functions timeout', async t => {
return new Promise((resolve, reject) => {
const req = http.request({
hostname: host,
port: port,
path: '/.netlify/functions/timeout',
method: 'GET',
}, (res) =>
{
res.on('data', () => {})
res.on('end', resolve)
})
req.on('error', reject)
const response = await fetch(`http://${host}:${port}/.netlify/functions/timeout`).then(r => r.text())

req.end()
})
t.is(response, '"ping"')
})

test('netlify dev env file', async t => {
let data = ""
await new Promise((resolve, reject) => {
const req = http.request({
hostname: host,
port: port,
path: '/.netlify/functions/env',
method: 'GET',
}, (res) =>
{
res.on('data', (d) => {data += d.toString()})
res.on('end', resolve)
})
req.on('error', reject)

req.end()
})
const response = await fetch(`http://${host}:${port}/.netlify/functions/env`).then(r => r.text())

t.is(data, "true")
t.is(response, 'true')
})


test('netlify dev env file overriding prod var', async t => {
let data = ""
await new Promise((resolve, reject) => {
const req = http.request({
hostname: host,
port: port,
path: '/.netlify/functions/override-process-env',
method: 'GET',
}, (res) =>
{
res.on('data', (d) => {data += d.toString()})
res.on('end', resolve)
})
req.on('error', reject)
const response = await fetch(`http://${host}:${port}/.netlify/functions/override-process-env`).then(r => r.text())

req.end()
})
t.is(response, 'false')
})

test('netlify dev: api rewrite', async t => {
// Wait for the redirect rules to be parsed
await new Promise((resolve, reject) => setTimeout(resolve, 1000))

const response = await fetch(`http://${host}:${port}/api/timeout`).then(r => r.text())

t.is(data, "false")
t.is(response, '"ping"')
})

test.after('cleanup', async t => {
test.after.always('cleanup', async t => {
if (ps && ps.pid) ps.kill('SIGHUP')
})
4 changes: 4 additions & 0 deletions src/tests/dummy-site/netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
command = "npm run build"
publish = "build"
functions = "functions"
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/:splat"
status = 200
[[redirects]]
from = "/something"
to = "/ping"
Expand Down

0 comments on commit d501a32

Please sign in to comment.