GithubHelp home page GithubHelp logo

benjie / mehserve Goto Github PK

View Code? Open in Web Editor NEW
78.0 3.0 10.0 723 KB

A simple port-sharing proxy for development on multiple local domains, supports websockets

License: MIT License

JavaScript 93.04% HTML 6.96%

mehserve's Introduction

mehserve ๐Ÿคทโ€โ™‚๏ธ

Patreon donate button Package on npm Follow MIT license

ยฏ\_(ใƒ„)_/ยฏ serve: a simple port-sharing proxy for development on multiple local domains, supports websockets (e.g. for webpack hot module replacement), SSL termination, and queuing requests whilst development server restarts so you don't get the annoying connection refused messages.

E.g. imagine you have Create React App running on port 3000, a Node.js server running on port 3030, and a Rails API running on port 3060, you can use mehserve to make these available as https://client.meh, https://server.meh and https://api.meh respectively. (Commands to enable this would be: mehserve add client 3000; mehserve add server 3030; mehserve add api 3060; followed by mehserve ssl client.meh commands for each domain to walk you through enabling SSL.)

NOTE: since Google registered the .dev TLD in 2015 and then forced certificate pinning on it in 2017 you can no longer use *.dev domains without a lot of work. Fortunately mehserve supports *.meh domains which was originally a joke... Hopefully no-one registers the .meh TLD!

Features โœจ

  • Quick (near instant) startup
  • Built in DNS server to redirect _.meh to 127.0.0.1 (requires additional configuration for your system to use this server)
  • Proxies regular HTTP requests and websocket connections based on the Host HTTP header
  • Easy to configure
  • Subdomain configuration is updated on a per-request basis - no need to restart server
  • supports xip.io and .localhost domains
  • SSL termination (using SNI to support multiple domains on one port)
  • Self-signed SSL certificate generation and help installing
  • mehserve run --exponential-backoff will automatically re-attempt requests when your development server restarts (e.g. due to file changes) saving you from receiving the error page in the intervening seconds (ALPHA)

Status โœ…

I've been using this for a few years now, it's been very smooth for me. I work on a lot of different projects in parallel. YMMV. This is NOT for production usage, it's only intended for use on your own development machine!

Getting Started ๐Ÿš€

Mehserve itself should run on Linux and OS X, but to have .meh domains resolve to localhost and to have it run on port 80 you need to do a little additional configuration.

We've currently only instructed you how to do this on OS X and Ubuntu; pull requests welcome.

Installing ๐Ÿ’พ

npm install -g mehserve
mehserve install

follow the instructions to set up port forwarding and DNS resolution.

Running ๐Ÿƒโ€โ™€๏ธ

To run the server:

mehserve run

We don't currently daemonize the server, pull requests to add this functionality would be welcome. In the mean time we recommend you set up pm2 and then tell it to run mehserve with:

pm2 start `which mehserve` -- run --exponential-backoff && pm2 dump

Configuring subdomains โš™๏ธ

Port forwarding โ†ช๏ธ

To set up a subdomain, simply run

mehserve add mysite 1337

This'll tell mehserve to proxy all HTTP requests for mysite.meh, mysite.localhost, and mysite.*.*.*.*.xip.io to localhost:1337

Static files ๐Ÿ“„

Alternatively, to serve static files:

mehserve add staticsite /path/to/public

This'll tell mehserve to serve static content from /path/to/public/ to anyone requesting http://staticsite.meh/ or http://mysite.localhost

SSL certificates ๐Ÿ”

If you want a local domain to be served with SSL you must generate a certificate for it:

mehserve ssl staticsite

Then follow the instructions.

DNS resolution fails whilst offline ๐ŸŒŽ

This is an issue with discoveryd (it also affects Pow - see basecamp/pow#471) - should be fixed by updating to OS X 10.10.4

Configuration location ๐Ÿงญ

Configuration is saved as files stored under ~/.mehserve. To remove a service registered as myapi, delete the file ~/.mehserve/myapi (and any related files such as SSL certificates/keys/etc).

Troubleshooting ๐Ÿ•ต๏ธ

  • If you get the message "Invalid Host header" in your Vue project, add disableHostCheck: true to the devServer section of your vue.config.js. More information here.

TODO ๐Ÿ˜…

Pull requests welcome!

  • Tests
  • Daemonize
  • Scripts directory organzation
    mehserve
    โ””โ”€โ”€ extras
        โ”œโ”€โ”€ macos-launchd
        โ”œโ”€โ”€ supervisord
        โ”œโ”€โ”€ systemd
        โ””โ”€โ”€ systemv
    
  • Homebrew (node formula dependency) Homebrew CONTRIBUTING

Removing old .dev TLD

As .dev is now a valid TLD we no longer use it as the domain extension. If you have installed an older version of mehserve you can remove local resolving of the .dev domain by running sudo rm /etc/resolver/dev from a terminal.

mehserve's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

mehserve's Issues

mehserve crashes when one of the dev services goes down

It seems like it should just gracefully handle this and retry the connection every few seconds.

mehserve v1.1.1 listening on port 12439
/Users/jeffrey/.nvm/versions/node/v5.5.0/lib/node_modules/mehserve/node_modules/http-proxy/lib/http-proxy/index.js:119
    throw err;
    ^

Error: connect ECONNREFUSED 127.0.0.1:9001
    at Object.exports._errnoException (util.js:856:11)
    at exports._exceptionWithHostPort (util.js:879:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1062:14)

`ECONNRESET` not being handled

~ ๐Ÿ’ƒ  ๐Ÿ‘‰  mehserve run --exponential-backoff
Exponential backoff enabled, with 25 attempts
mehserve v2.0.0-2 listening on port 12439
mehserve v2.0.0-2 (SSL) listening on port 12443
_http_server.js:188
    throw new RangeError(`Invalid status code: ${originalStatusCode}`);
    ^

RangeError: Invalid status code: ECONNRESET
    at ServerResponse.writeHead (_http_server.js:188:11)
    at ServerResponse._implicitHeader (_http_server.js:179:8)
    at write_ (_http_outgoing.js:630:9)
    at ServerResponse.end (_http_outgoing.js:749:5)
    at /usr/local/lib/node_modules/mehserve/index.js:71:7
    at cb (/usr/local/lib/node_modules/mehserve/index.js:205:34)
    at ClientRequest.proxyError (/usr/local/lib/node_modules/mehserve/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js:154:11)
    at emitOne (events.js:115:13)
    at ClientRequest.emit (events.js:210:7)
    at Socket.socketOnEnd (_http_client.js:421:9)

This was caused by a server that accepted the connection then closed the socket without sending any data.

SSL instructions for Ubuntu

sudo mkdir -p /usr/local/share/ca-certificates/mehserve
sudo cp ~/.mehserve/blah.ssl.crt /usr/local/share/ca-certificates/mehserve/blah.ssl.crt
sudo update-ca-certificates
# For chrome/etc
certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n blah -i ~/.mehserve/blah.ssl.crt

Request: more transparent configuration

From what I can see in the readme:

  • there is no listed location for the configuration file that mehserve is presumably writing to
  • there is no command that lists registered ports
  • there is no command to remove or modify registered ports, only add new ones

So, there's no way, short of digging through the code, to say, change the port of a registered service.

Now, by digging through the code, I can now see that service "foo" is registered as port 8081 simply by creating a file ~/.mehserve/foo with contents 8081.

I'd suggest:

  • documenting this directory structure in the README
  • a mehserve ls command that lists the registered services (by scanning that directory) with their ports

Firewall issue in Node v17+

In Node 17+, making requests to *.meh domains from within Node (e.g. via built-in fetch) is failing with Error: connect ECONNREFUSED ::1:443.

Turns out that Node 17 changes the default sorting order for DNS records so that IPv4 records are no longer sorted ahead of IPv6 by default: nodejs/node#39987

So instead of using 127.0.0.1, requests now resolve to ::1 as the default behaviour.

The cause of the failed requests (at least on MacOS) seems to be this line in meh.firewall.plist: if I change 127.0.0.1 to ::1 it appears to all go back to a working state, however, I'm not smart enough to understand why, so I'm hesitant to make a PR suggesting a change! But it looks to be something with the firewall rule not forwarding traffic in an IPv6 friendly way.

Hope that's useful! ๐Ÿ™‚

Add Ubuntu instructions to `mehserve install`

sudo apt-get install dnsmasq
echo -e "local=/dev/\naddress=/dev/127.0.0.1" | sudo tee /etc/dnsmasq.d/dev-tld
echo -e "local=/meh/\naddress=/meh/127.0.0.1" | sudo tee /etc/dnsmasq.d/meh-tld
sudo service dnsmasq restart
sudo iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 12439
sudo iptables-save

This would also mean that we can disable the DNS server on linux since dnsmasq serves this purpose for us. Shame we can't do platform-specific dependencies in npm!

SSL Cert generation not working on OS X Catalina

Hey, @benjie! I just installed mehserve and I'm really impressed with what you've done!

I tried to add a self-signed cert using mehserve ssl <sitename> and I got the following message:

SSL certificate successfully generated

================================================================================

We'll open Keychain Access in a moment. Here are the instructions what to do:

1. Click "Add"
2. Find the certificate (e.g. "chocolate") in the "Certificates" category,
   select it, and click the [๏ฝ‰] button at the bottom
3. In the popup window, click the โ–ถ button to the left of 'Trust', and select
   'Always Trust' for 'When using this certificate:'.
4. Close the popup window.
5. When prompted, enter your password again and click Update Settings.
6. Quit Keychain Access.

Press enter to continue

Error: open exited with status '1'
    at ChildProcess.<anonymous> (/usr/local/lib/node_modules/mehserve/ssl.js:15:16)
    at ChildProcess.emit (events.js:210:5)
    at maybeClose (internal/child_process.js:1021:16)
    at Socket.<anonymous> (internal/child_process.js:430:11)
    at Socket.emit (events.js:210:5)
    at Pipe.<anonymous> (net.js:659:12)

I popped open keychain myself to see if the certificate had been added, but I don't see it in there at all. Any advice?

Invalid Host header

Cool repo! It's working nicely.

However when I try to connect to my Vue app running at localhost:8080, through your proxy, I get a document containing "Invalid Host header". And that's all I get! (Directly at localhost:8080 it works fine). Do you know if this error is something that comes from mehserve?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.