vercel / serve-handler Goto Github PK
View Code? Open in Web Editor NEWThe foundation of `serve`
Home Page: https://npmjs.com/serve-handler
License: MIT License
The foundation of `serve`
Home Page: https://npmjs.com/serve-handler
License: MIT License
/app
prefix e.g. example.com/app/products
serve
and customized with serve.json
"homepage":"/app"
in package.json
according to CRA docsserve
is not serving asset files correctly under build/static/...
serve.json
used for above:
{
"public": "build",
"rewrites": [
{ "source": "/app/static/:segment*", "destination": "/static/:segment*" },
{ "source": "/app", "destination": "/index.html"}.
{ "source": "/app/**", "destination": "/index.html"}
]
}
After some debugging, I identified the issue to be in toTarget
. We are not passing in array of parameters when we are compiling the valid path https://github.com/zeit/serve-handler/blob/e7c4e42a63e9cd59b43256bb4ca04a22a5f77994/src/index.js#L79-L86
We should be passing array according to the docs(v2.2.1 that we are using). If not it treats the whole string as a single segment value and encodes /
.
Debug logs:
// applyRewrites
relativePath: "/app/static/css/2.c7bb94bc.chunk.css" //argument
rewrittenPath: "/app/%2Fcss%2F2.c7bb94bc.chunk.css" // return value
// toTarget
props: {
"segment": "/css/2.c7bb94bc.chunk.css"
}
normalizedDest: "/static/:segment*"
toPath(props): "/static/%2Fcss%2F2.c7bb94bc.chunk.css"
This should be easily fixed by doing a split by /
when we are setting the props i.e. props[name] = results[index + 1].split("/");
This will fix repeated segment for redirects as well.
Documents should also be updated with instructions on how to use repeated segment. (I figured out during debugging that destination needs *
as well else the compile function will complain that the url built does not match the destination pattern ๐
)
Not sure if my proposed solution is correct but it works locally for me so far. I am happy to work on this with tests and docs for repeated segment
Since I am trying to create 500+ redirect rules I was thinking that there must be an easier way than doing this
redirects: [
{ source: '/partners*', destination: '/company#partners', type: 301 },
...
]
500+ times. The SEO expert I am working with on this project created a Google Spreadsheet which holds all the old domains and where they should redirect to. I thought of just looping over that file by creating an API from the Google spreadsheet, call it in my index.js
and generate those 500+ redirects automatically.
Unfortunately it seems that I can't really import or fetch anything in the index.js
which should be designed as describes here: https://github.com/zeit/serve-handler#usage.
Does anybody know why this is different from all the other .js
files in my React project and how I can solve this? Thanks!
Here's the closest example to what I want to do for rewrites that I found:
{
"rewrites": [
{ "source": "/projects/:id/edit", "destination": "/edit-project-:id.html" },
]
}
What I really want to do is have
But I don't want to rewrite the url. I just want to have all requests be handled by my react app, the entry point for which is index.html.
What I find now is that if I go directly to a page (let's say /pages/foo
), or do a forced refresh of that page, react doesn't load/route properly and returns a 404.
So what rules do I need to have all requests under the specific paths /pages/**
and /tags/**
all handled by /index.html
but without changing the URL?
After updating serve-handler from 5.0.7 to 5.0.8 my rewrites don't seem to work. My client side routes just show 404. This also happens in https://github.com/zeit/serve with the --single option.
Minimal code:
const http = require("http");
const handler = require("serve-handler");
const handlerOptions = {
public: "./dist",
rewrites: [{ source: "**", destination: "/index.html" }],
};
const requestListener = async (request, response) => {
await handler(request, response, handlerOptions);
};
http.createServer(requestListener).listen(8080);
console.log(`Started webserver http://localhost:8080/`);
Using Windows 10, NodeJS 11.9.0
Hi there,
I couldn't find any TypeScript typings and wrote these:
declare module 'serve-handler' {
import { IncomingMessage, ServerResponse } from 'http'
export interface IHeader {
key: string
value: string
}
export interface IRedirect {
source: string
destination: string
}
export interface IServeHandlerOptions {
public?: string
cleanUrls?: boolean | string[],
rewrites?: IRedirect[],
redirects?: IRedirect[],
headers?: IHeader[],
directoryListing?: boolean | string[],
unlisted?: string[],
trailingSlash?: boolean,
renderSingle?: boolean,
symlinks?: boolean
}
export default function (request: IncomingMessage, response: ServerResponse, options?: IServeHandlerOptions): void
}
Hope these will help others using this library with TypeScript!
I want to use home.html as default root file instead of index.html.
any way to do it?
Hi, we used the serve since 6.5.3 version with -c option which automatically generated ETag in the response. However in recent versions I see that this option is no longer supported.
Also I see that now it is possible to define ETag header in serve.json.
Is there any way to generate it automatically for each server run?
I'm trying to rewrite everything under /admin
, e.g.
...and so on.
Can this be accomplished using rewrites
in serve.json
without specificying every possible path?
I tried the following but no luck:
{
"rewrites": [{
"source": "/admin/(.*)",
"destination": "/$1"
}]
}
I'd love to be able to customize the port the data is served on via the serve.json file. I'll submit a PR if need be.
With serve-static it'd looks like:
const serveStatic = require('serve-static')
const serve = serveStatic('build');
serve(req, res, () => {
// if we're there, the file was not found
res.end('...')
});
not sure this lib can do this?
I want to serve a Create-React-App production build at different stages.
So I want to set all REACT_APP_
environment variables during runtime, not at build time.
In order to make this work I would like to utilize a tool similar to react-env
, which creates a env.js
file, which will hold all environment variables like:
window._env = { REACT_ENV_FOO: 'BAR' };
This can be archived by using a middleware
It could just be that I am misunderstanding how this works. But I've tried every combination I can think of. My goal is to direct all routes without /dp
to index, and everything with /dp
to it's html file. Is this possible?
rewrites: [
{ source: '!/dp', destination: '/index.html' },
{ source: '/dp/:id', destination: '/dp/:id.html' }
],
Edit: This is NOT related to #77 ... I've rolled back to 5.0.7 and tested on that version as well.
It would be nice if we could have and HTTP auth flag which we can define in the now.json
. There are a few static pages that I have that I would like to hide behind a basic auth.
I believe the feature existed in previous versions of server
but it is gone now.
cc @leo
Is it possible to do redirect from http to https using redirects? If so, how?
Something like this
redirects: [{
source: "http://**",
destination: 'https://**',
type: 301
}]
but source is phrased incorrectly or the protocol part cannot be used.
I need serve-handler for the lower-level interface, but i need to run a react app that i built.
Any ideas on how to do this?
when the config cleanUrls is set to true (by default)
and the requested URL is a file name with an extension
and has some parameter in it ex:
/index_2.html?foo&bar=1
the server rewrite the url to
/index_2
and remove the extension AND the url parameters
those URL on the other hand works as intended :
/index_2?foo&bar=1
/?foo&bar=1
/folderName?foo&bar=1
/folderName/?foo&bar=1
question :
is it as intended ?
If the response is "yes, you should set cleanUrls to false" then the README should be mentioning those cases
but I think the cleanUrls setting should set urls like :
/index.html?foo&bar=1
to
/?foo&bar=1
it would be more useful
It's not supporting Full Refresh like serve npm package.
I'm trying to load index.html from build folder with the help of NGINX.
Would be great to have proxy support for external APIs in this microservice world. This would also alleviate the pain of using CORs. Also in relation to issue #28
{
"proxy": [
{ "path": "api/**", "destination": "https://xxx.api/" }
]
}
I am launching serve
with a serve.json
file. I have a rewrite like this:
{
"source": "/foo/api/:rest",
"destination": "http:/xxx.xx.x.xx:8080/foo/api/:rest"
}
But this causes an error when I launch serve
:
(node:14574) UnhandledPromiseRejectionWarning: TypeError: Expected "8080" to be a string
at /Users/sdavico/Development/installer/webapp/node_modules/serve-handler/node_modules/path-to-regexp/index.js:194:13
at toTarget (/Users/sdavico/Development/installer/webapp/node_modules/serve-handler/src/index.js:68:9)
at applyRewrites (/Users/sdavico/Development/installer/webapp/node_modules/serve-handler/src/index.js:85:18)
at module.exports (/Users/sdavico/Development/installer/webapp/node_modules/serve-handler/src/index.js:547:24)
at Server.http.createServer (/Users/sdavico/Development/installer/webapp/node_modules/serve/bin/serve.js:147:58)
at Server.emit (events.js:160:13)
at parserOnIncoming (_http_server.js:618:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:115:23)
This is due to using path-to-regexp
to process the destination. Could we add support for full URLs?
The most recent version breaks when provided with header names longer than 32 characters. For example, we are using Content-Security-Policy-Report-Only
and serve will not start:
INFO: Discovered configuration in `serve.json`
ERROR: The configuration you provided is wrong:
should NOT be longer than 32 characters
{"limit":32}
Is there any way to enable hot reload on this ?
I do have a question, I don't know if this is a bug or an expected behavior.
When trying to run a http server that uses serve-handler
works as expected as long as the process.cwd()
returns the same path of the script, instead of /
.
await handler(request, response, {
public: "www"
});
The example below works as expected and the public path is set correctly.
https://github.com/zeit/serve-handler/blob/master/src/index.js#L508
# process.cwd() === /path/to
# public path === /path/to/www
$ node /path/to/index.js
I am using forever
and it seems forever current working directory is set to /
.
# process.cwd() === /
# public path === /www
$ forever start /path/to/index.js
The serve-handler
module tries to find files in the /www
directory instead of the correct directory /path/to/www
.
Using absolute path doesn't fix it, as it will create an incorrect path for Example 1.
Hi folks,
I would like to test my local build. I have already a local test CA and private key and certificate.
I use mkcert for that.
Are there any options for this?
Kind regards,
Remzi
In a SPA settings, I'm prerendering the some landing pages for SEO and perf. But I can't figure out the corresponding rewrites rules.
So far, I've tried:
{
"rewrites": [
{ "source": "", "destination": "prerender/landing.html" },
{
"source": "/landing-2",
"destination": "prerender/landing-2.html"
},
{ "source": "**", "destination": "index.html" }
],
...
}
This doesn't work because apparently, all the rewrites rules are applied to the path (instead of stopping after the first match).
The problem is that I can't seem to find a way to negate the two prerendered path in the last rule, using minimatch.
What would be the proper way to handle this use case ? Is it even possible ?
Thanks!
I've tried to use the production use case for a site I was testing using Now 2.0 with GitHub integration.
But the Now bot commented that the static
property cannot be used in the config and the build failed. The option cannot be seen in https://zeit.co/docs/configuration too, so is it invalid?
Following vercel/serve#536
As I explain in this comment, IMO it's not a legit way of using serve, as it's a workflow that even will cause an error in bash
.
But still, I think we can handle the error, show a message to the user, and exit gracefully, because right now an exception is thrown and the browser just hangs.
Is there any way I can set multiple Set-Cookie
headers? Currently if I do the following, only the last item in the array, b=b
, is set:
handler(request, response, {
public: "public",
headers: [
{
source: "**",
headers: [
{
key: "Set-Cookie",
value: `a=a`
},
{
key: "Set-Cookie",
value: `b=b`
}
]
}
]
});
Due to the direct use of fs.lstat
, in acquiring similar D: \ when the file, Windows system folder "System Volume Information" method would result in an exception.
Perhaps you can first use fs.readdir
list all the files, then use fs.lstat
to get detailed information and filter list.
So even if some files wrong, it will not affect the normal display other files.
If you have an index.html in a subdirectory default behavior strips out the index.html
part of the url which breaks relative paths. public/foo/index.html
becomes public/foo
.
This causes an issue when you have a relative script in public/foo/index.html
referencing <script src="main.js"></script>
. Instead of looking for public/foo/main.js
default browser behavior is now to look for public/main.js
.
Setting cleanUrls
to true would fix this issue, except it causes the public/foo/index.html
link to redirect to the directory listing for public/foo
causing public/foo/index.html
to be inaccessible.
If this is intended default behavior it should probably be documented, if not it would be great to have an option to serve index.html
files.
Hi,
Is [email protected] this still your security email address? Have reported a potential security flaw few weeks ago and it would be nice to hear back on it from you.
Thanks
Hi,
I'm using the trailingSlash: true
option to redirect all my pages from /page
to /page/
. However this has the unintended consequence of also redirecting /image.jpeg
to /image.jpeg/
.
After having a look through the ZEIT now spectrum community, someone suggested:
routes [{
"src": "/(((?!\\?|#|\\.|_next).)*((?!\\?|/|#|\\.).))",
"status": 301,
"headers": { "Location": "/$1/" }
}]
Eg. redirect all paths to trailing slash, unless it's a file (or the _next) folder.
Am I missing something here or isn't this the intended behaviour of trailingSlash?
Thanks in advance
Having trouble using serve-handler in my Express app. Developing on Mac. Have tried deleting node_modules and installing again.
Running npm i glob-slash
doesn't seem to fix the issue either.
My use-case: I want to deploy a folder of photos, and have the directory page use a lightbox to view the photos. Would be really awesome to be able to use serve-handler directly and just supply a custom template or perhaps a way to just append some html to the output.
I tried to look for a similar issue but didn't see anything. If that's something that other people are interested in, i'd be happy to PR it.
it redirects urls like:
http://localhost:8000/abc/def/index.html
to http://localhost:8000/abc/def
if index.html
contains links like <a href="file.html">File</a>
browser resolves that links like:
http://localhost:8000/abc/file.html
instead of http://localhost:8000/abc/def/file.html
actual behaviour:
redirects http://localhost:8000/abc/def/index.html
to http://localhost:8000/abc/def
expected behaviour:
redirects http://localhost:8000/abc/def/index.html
to http://localhost:8000/abc/def/
I compared it to for example SimpleHTTPServer from python, and it works correctly.
With the following directory structure:
images
|- image1.png
|- image2.png
|- image3.png
images.html
images.html
is preferred over images
when going to /images
.
I'm not sure if this is the standard behavior of other web servers.
Example of how it should probably be handled:
/images
=> images.html
and /images/
=> images
directory index
Accessing a path like static/a/abc
will throw an error and respond with status code 500 if a
is a file. This is because this generates an ENOTDIR
error, instead of ENOENT
.
We discovered this since we serve images at static/*.jpg
and paths like static/*.jpg/abc
returned 500 instead of 404.
Should respond with status code 404 and show the 404 page.
In the code you check forif (err.code !== 'ENOENT')
. Adding && err.code !== 'ENOTDIR'
for example here makes it correctly respond with 404 instead of 500:
Hi,
I would like the server listen to a virtual path / base-path like this - localhost:/.
I used the rewrite property but I didnt found a way that serve the index.html file when accesing without postfix while serving the other files.
My configuration:
{ "rewrites": [ { "source": "/virtual-path", "destination": "/index.html" }, { "source": "/virtual-path/:rest", "destination": "/:rest" } ] }
Please help,
Thanks
Is this the desired behaviour? Or should attempting to traverse unlisted files/directory return 404 status.
Hi,
I've discovered a potential security flaw. Would it be okay if I open a PR for the fix or would you like it to be disclosed privately first?
Running npm audit found a vulnerability as a deep dependency on my project:
=== npm audit security report ===
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Manual Review โ
โ Some vulnerabilities require your attention to resolve โ
โ โ
โ Visit https://go.npm.me/audit-guide for additional guidance โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Low โ Prototype Pollution โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Package โ lodash โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Patched in โ >=4.17.5 โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Dependency of โ serve [dev] โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Path โ serve > serve-handler > glob-slasher > toxic > lodash โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ More info โ https://nodesecurity.io/advisories/577 โ
โโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
You should update glob-slasher version.
It has already been fixed here and here
const handler = require('serve-handler');
const http = require('http');
const path = require('path');
const server = http.createServer(async(req, res) => {
// res.setHeader('Content-Encoding', 'gzip')
await handler(req, res, {
public: path.resolve(__dirname, './dist'),
headers: [
{
"source" : path.resolve('./dist/js/chunk-elementUI.1d709726.js.gz'),
"headers" : [{
"key" : "Content-Encoding",
"value" : "gzip"
}]
}
]
});
});
console.log(server)
server.listen(3000, () => {
console.log('Listening on http://localhost:3000');
});
serve@^11
currently errors out when setting symlinks: true
:
root@c3ee02fdad56:/app# serve --version
11.0.0
root@c3ee02fdad56:/app# serve -p 8000 -c ./serve.json
INFO: Discovered configuration in `./serve.json`
ERROR: The configuration you provided is wrong:
should NOT have additional properties
{"additionalProperty":"symlinks"}
Here i'm using serve like a static file server, I store files in it and visit from my program. But here comes a problem that if someone see my link such as http://example.com/1.jpeg
, they can cut off the filename and visit http://example.com
, then they will get a whole list of my files. Sometimes this will bring me some trouble.
Can I have an option to hide files from listing by visiting the root domain? I mean, when people open my domain, they will get nothing, but still they can get my files by direct link.
We should add a test for the behavior outlined here: vercel/serve#378
So that we won't regress on it in the future.
Hello
Example: Say I have this redirect
{
"redirects": [
{ "source": "/some/old-path.html", "destination": "/new-path", "type": 301 }
]
}
The result is
HTTP/1.1 301 Moved Permanently
Location: /some/old-path
Date: Fri, 31 Jan 2020 03:39:03 GMT
Connection: keep-alive
instead expected result
HTTP/1.1 301 Moved Permanently
Location: /new-path
Date: Fri, 31 Jan 2020 03:39:03 GMT
Connection: keep-alive
serve
version 11.3.0
I get my requests to the following URL /some/frontend/static/js/main.js
.
My build folder to be served has the following structure
build
|_ static
|_ js
|_ main.js
Therefore serve should translate the url /some/frontend/static/js/main.js
into the path static/js/main.js
.
As far as I know a rewrite would be the way to go. However it doesnt work out for me, instead I found out serve creates a wrong path for me.
serve.json
{
"rewrites": [{ "source": "/some/frontend/:path*", "destination": "/:path" }]
}
The serve handler translates the path into /static%2Fjs%2Fmain.5a829761.js
. So he is escaping it.
This comes from line 70 in the index.js file, where the translation takes place.
Is there a way to define my rewrite route correctly?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.