Git Product home page Git Product logo

serve's Introduction

serve

Windows macOS Linux
Build status Build Status CircleCI

GitHub Releases

serve starts a simple temporary static file server in your current directory and prints your IP address to share with colleagues.

It was based on a Gist by Paul Mach, but has evolved a lot.

Contents

Features

  • Serves static files in any given accessible directory until you hit Ctrl-C
  • Prints a table of your network interfaces and their IP addresses and guesses which one you most likely want to share
  • Follows softlinks transparently
  • Optional basic authentication
  • Optionally serve files via HTTPS instead of HTTP, using a temporary self signed certificate that's automatically generated for you on the fly
  • Optionally bind to a specific network interface, for example localhost to disable access from other devices
  • Only uses the Go standard library and no external dependencies
  • Single file executable, usable without any installation, or easy automatic updates when using a package manager

Roadmap

  • Find out and print external IP address that's reachable from the Internet
  • Optionally compress files when requested
  • Optionally make your server reachable from the Internet even if it's behind a router with NAT
  • Optionally run a Tor hidden service (v3) for:
    • Automatic accessibility from the Internet (via Tor Browser or proxy) even when behind a router with NAT
    • Encrypted traffic
    • No exposure of your IP address

Install

We recommend installing serve with one of the following package managers, because they provide you with functionality such as automatic updates, instant availability as command in the PATH, easy removal, sandboxing (depending on the package manager) etc.
But alternatively you can always install serve manually as well, see Manually.

Windows

The easiest way is to use the package manager Scoop:
scoop install serve

Another option is Chocolatey:
choco install serve

You can also have a look at the description in the Chocolatey Gallery on https://chocolatey.org/packages/serve/.

macOS

The easiest way is to use the package manager Homebrew:
brew tap philippgille/tap
brew install serve

Or in a single command:
brew install philippgille/tap/serve

Linux

The easiest way is to use the package manager Snap, which is installed by default on Ubuntu 16.04 and later:
snap install serve

You can also have a look at the description in the Snap Store on https://snapcraft.io/serve.

Note: Due to sandboxing by Snap, serve can only serve files in the user's $HOME directory.

Manually

With Go installed

go get -u github.com/philippgille/serve

Note: Requires your $GOPATH/bin directory to be in your PATH, which is usually the case.

Without Go installed

You can download the binary for your OS from the releases simply make it available as command in your PATH. See Manual Installation for details.

Docker

serve is also available as Docker image in the Docker Hub: https://hub.docker.com/r/philippgille/serve/

Please read docker/README.md for information on how to use it.

Use

$ serve -h
Usage of serve:
  -a string
        Require basic authentication with the given credentials (e.g. -a "alice:secret")
  -b string
        Bind to (listen on) a specific interface. "0.0.0.0" is for ALL interfaces. "localhost" disables access from other devices. (default "0.0.0.0")
  -d string
        The directory of static files to host (default ".")
  -h    Print the usage
  -p string
        Port to serve on. 8080 by default for HTTP, 8443 for HTTPS (when using the -s flag) (default "8080")
  -s    Serve via HTTPS instead of HTTP. Creates a temporary self-signed certificate for localhost, 127.0.0.1, <hostname>.local, <hostname>.lan, <hostname>.home and the determined LAN IP address
  -t    Test / dry run (just prints the interface table)
  -v    Print the version

Press Ctrl+C in the terminal to stop the server.

Example

~/path/to/servable/files$ serve

Serving "." on all network interfaces (0.0.0.0) on HTTP port: 8080

Local network interfaces and their IP address so you can pass one to your colleagues:

      Interface      |  IPv4 Address   |              IPv6 Address
---------------------|-----------------|----------------------------------------
lo                   | 127.0.0.1       | ::1
eth0                 |                 | 
wlan0                | 192.168.178.123 | fe80::e7b:fdaf:ae5d:3cfa
virbr0               | 192.168.122.1   | 
br-8ef347e8a4e9      | 172.22.0.1      | fe80::42:c9ff:fed3:35a
docker_gwbridge      | 172.21.0.1      | 
docker0              | 172.17.0.1      | fe80::42:c6cf:fe3d:a554
veth0d522f4          |                 | fe80::307a:7fcf:fe3d:cba4

You probably want to share:
http://192.168.178.123:8080

When opening the URL http://192.168.178.123:8080 in a browser you see the directory you're serving. For example:

screenshot

Build

To build serve by yourself:

  1. Install Go
  2. cd into the root directory of this repository
  3. Execute: go build

Note: The binaries in GitHub Releases are shrinked with additional Go linker flags and UPX

To also make serve available as command in other directories:

  1. Add $GOPATH/bin to your PATH if you haven't done that already when installing Go
  2. Execute: go install

There are also build scripts for Windows and Linux for creating release artifacts (shrinked binaries for Windows, macOS and Linux):

  • Windows: build/build.ps1
  • Linux: build/build.sh

Note: They require Go and UPX to be installed

To build with a Docker container:

docker run --rm -v $(pwd):/go/src/github.com/philippgille/serve -w /go/src/github.com/philippgille/serve golang build/build.sh noupx
Or with UPX:
docker run --rm -v $(pwd):/go/src/github.com/philippgille/serve -w /go/src/github.com/philippgille/serve golang bash -c "apt update && apt install -y upx-ucl && build/build.sh"

Note: You have to use ${pwd} instead of $(pwd) on Windows.

Packages

For Scoop and Homebrew no packages need to be built. They use "manifests"/"formulae" and the binaries from GitHub Releases.

For releasing a new version, they need to be updated here:

For Snap a Git hook is set up in the Snapcraft dashboard to automatically build a new Snap on every commit, so for releasing a new version the file in this repository needs to be updated:

The Snap package can also be built manually. In the past this could even be done within a Docker container, but the official Snapcraft Docker image (according to the docs) is outdated (as of 2019-05-01) and doesn't contain the latest version of snapcraft (and installing the latest version via snap itself, as you'd do nowadays according to the official docs, doesn't work).
So now you can only build the Snap package on Linux, using the following steps:

  1. snap install snapcraft --classic
  2. snapcraft

Depending on the current serve version and your CPU's architecture it will create a file like serve_0.3.2_amd64.snap, which can manually be installed with snap install --dangerous serve_0.3.2_amd64.snap.

The Chocolatey packages need to be uploaded manually to Chocolatey here. The package can be built with this script:

  • Windows: build\build-chocolatey.ps1

The Docker image can be built like this:

docker build -f docker/Dockerfile -t philippgille/serve .

Related projects

  • python -m SimpleHTTPServer 8080
    • Con: Requires Python, no option to require authentication, no HTTPS
  • https://github.com/indexzero/http-server
    • Pro: Popular (8200 GitHub stars as of 2019-05-02), mature, feature-rich
    • Con: Requires Node.js
  • https://github.com/zeit/serve
    • Pro: Popular (4200 GitHub stars as of 2019-05-02), mature
    • Con: Requires Node.js, no option to require authentication, no HTTPS, can't serve directories other than the current working directory
  • https://github.com/codeskyblue/gohttpserver
    • Pro: Nice web UI, shows QR codes for downloading files from a smartphone, OpenID and OAuth2 authentication, optional upload of files from a client, README.md preview, directory zip download any many more features
    • Con: Too many features ("feature creep")? Many dependencies.
  • https://github.com/syntaqx/serve
    • Con: No option to require authentication, no installation packages for Windows or Linux
  • https://github.com/rhardih/serve
    • Con: No option to require authentication, no installation packages, no HTTPS when not using HTTP/2, when using HTTP/2 the certificate and private key are written to disk in the current working directory, which is served by default, so an attacker can easily download and use them in a Man-in-the-Middle attack without the client noticing (because it's the correct certificate) (as of 2019-05-05 - I created an issue for that and hope it gets fixed soon)
  • Many others!

serve's People

Contributors

philippgille avatar

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

serve's Issues

Create binary checksums during build

The Scoop and Homebrew manifests have an optional SHA256 field. Instead of re-creating it manually on each build, include creating them in the build scripts.

For example:

  • serve_v0.2.0_Windows_x64.sha256

serve 0.3.0 fails to run on mac os x

Bug description

serve 0.3.0 fails to start on Mac OS X:

$ serve0.3.0
Killed: 9

Reproduction

curl -ssL https://github.com/philippgille/serve/releases/download/v0.3.0/serve_v0.3.0_macOS_x64 > ~/bin/serve && chmod a+x ~/bin/serve

Info

Example:

  • Version: 0.3.0
  • Operating system: Mac OS X 10.13.6

Add option to open an SSH reverse tunnel to a remote server

In addition to serving a directory on your host computer to colleagues on your local network, it would be awesome if you could also share the directory to people outside of that network, even if you're behind a NAT/firefall.

SSH reverse tunnels make this possible.

Go has an SSH package and it should be possible to open a reverse tunnel within the application itself.

Add Bash script for building Chocolatey package

For executing in Linux or a Docker container with Mono installed.

Like this:

#!/bin/bash

# Builds the Chocolatey package if the Windows x64 binary exists.
# Uses Chocolatey via Mono
# Is intended to be used inside a linuturk/mono-choco Docker container

# No "-o pipefail" option for the bash script,
# because when used in the .NET Core SDK Docker container this leads to "invalid option name: pipefail".
set -eux

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
APPNAME=$(<$SCRIPTDIR/APP_NAME)
VERSION=$(<$SCRIPTDIR/../VERSION)
ARTIFACTSDIR="$SCRIPTDIR/../artifacts"

$SCRIPTDIR/bumpVersion.sh

# Build chocolatey package if a win-x64 SCD was built

if [[ -f $ARTIFACTSDIR/${APPNAME}_v${VERSION}_win-x64/$APPNAME.exe ]]; then
    # Clean and create directories
    rm -f $ARTIFACTSDIR/$APPNAME.*.nupkg
    rm -f $SCRIPTDIR/../chocolatey/tools/serve.exe
    mkdir -p $SCRIPTDIR/../chocolatey/tools
    # Copy SCD files
    cp -r $ARTIFACTSDIR/${APPNAME}_v${VERSION}_win-x64 $SCRIPTDIR/../chocolatey/tools
    # Workaround for a bug where choco uses the wrong working directory when using choco via Mono
    REGEX="<file src=\\\"tools\\\\\**\\\" target=\"tools\" />"
    REPLACEMENT="<file src=\"${SCRIPTDIR}/../chocolatey/tools\\**\" target=\"tools\" />"
    sed -r "s@${REGEX}@${REPLACEMENT}@g" $SCRIPTDIR/../chocolatey/$APPNAME.portable.nuspec > $SCRIPTDIR/../chocolatey/$APPNAME.temp-linux.nuspec
    # Build Chocolatey package
    choco pack "$SCRIPTDIR/../chocolatey/$APPNAME.temp-linux.nuspec" --out $ARTIFACTSDIR
    choco pack "$SCRIPTDIR/../chocolatey/$APPNAME.nuspec" --out $ARTIFACTSDIR
    # Clean up workaround
    rm -f $SCRIPTDIR/../chocolatey/$APPNAME.temp-linux.nuspec
fi

First check if the workaround is still required with the current Chocolatey version.

Snap package doesn't work

When executing the Snap, the following error occurs:

$ serve

Serving "." on all network interfaces (0.0.0.0) on HTTP port: 8100

Local network interfaces and their IP addresses so you can pass one to your colleagues:

2018/05/12 12:39:23 route ip+net: netlinkrib: operation not permitted

The same when using -t for testing.

Solution

We probably need to declare some capabilities in the snapcraft.yaml, see:

network-bind is probably necessary for acting as server.

Another interface might be necessary for accessing files in the directory the user requests.

Add printing external (internet) IP address

Currently (v.0.2.1) only LAN IP addresses are printed, but in case the user set up port forwarding in his home network or uses serve on a VPS, the external IP address that's reachable from the internet would be useful as well.

Use 3rd party web services to get the external IP address:

Make requests to multiple services in case 1) one goes offline in the future and 2) the responses differ (then use the address which most services responded with).

Two things need to be kept in mind:

  • Make this optional (maybe true as default, but the user should be able to disable it), because some user's might not want any 3rd party programs to make requests to other services
  • When using with -s, the external IP address should be included in the SAN entries

Add Docker image

There should be a Docker image for serve.

  • This is the easiest way to launch the server, no installation or binary download needed!
  • People feel more safe to mount a single directory to a container and know the application in the container can't access anything else in the filesystem.

Add script for bumping version number

The version number is currently hard coded in several places:

  • serve.go - the actual code
  • README
  • docs/README
  • Scoop manifest
  • Hombebrew formula
  • Snapcraft configuration file
  • VERSION file

Add tests

Go main packages can be tested as well, so add a serve_test.go and write some tests.

Consider moving the helper functions into their own package, where it makes sense to export them, which in turn makes it more idiomatic to test them (instead of using the main package in serve_test.go).

Create a Homebrew package

Improve URL suggestion by checking against default gateway

Instead of relying on network interface names we could check the IPv4 addresses against the default gateway's address.

For example:

  • The gateway's address is 123.123.123.0
  • Our system, in this example Windows, has (interface name + address):
    • "Ethernet 2": 234.234.234.234
    • "Ethernet 3": 123.123.123.123

If we would choose by name, "Ethernet 2" would match first and we would use that IP address in the URL suggestion, which is the wrong one.

If instead we would match the first three parts of the IP address against the first three parts of the gateway address, we would choose "Ethernet 3", which is the correct one.

This requires determining the gateway's IP address, which is not possible with Go's stdlib. But this package seems to be perfect: https://github.com/jackpal/gateway

Use UPX to shrink the binaries even more

Instead of building release artifacts locally, add the following to the .travis.yml: apt-get install -y upx-ucl.

Then either use those artifacts from Travis CI to upload them to GitHub Releases, or use Travis CI to automate the release as well (see hello-netcoreap/.travis.yml for example).

Add possibility to bind to specific interface

Currently serve always binds on 0.0.0.0, but maybe you only want the server to be reachable on a specific address, like localhost for temporary testing without exposing a directory to other network members.

A flag b would make sense for this.

Printint the network interface table probably doesn't make sense in this case, and the URL suggestion could simply be the chosen bind address + port.

A format check and proper message in case of a bad format should be added.

The network interface and address table looks bad on Windows

On Linux it looks nice, but also just by accident. On Windows the interface names are longer and the code only fills up to 15 characters, it doesn't cut them off if a string is longer.

Also, the default network interfaces on Windows aren't called eth0 and wlan0, so use the proper Windows interface names for a good suggestion of an IP address that can be shared with colleagues.

Also, in the below example, no IPv4 address is shown for Ethernet 3, although it has one.

   Interface    |  IPv4 Address   | IPv6 Address
----------------|-----------------|----------------
vEthernet (nat) | 172.29.123.123     | foo:bar::::123
vEthernet (Standardswitch) | 172.21.123.123   | foo:bar::::124
vEthernet (DockerNAT) | 10.0.75.1       |
Ethernet 3      |                 | foo:bar::::125
Loopback Pseudo-Interface 1 | 127.0.0.1       | ::1

Add file size information

Hi, thanks for this awesome tool you've built.

have you considered to add a file size information to the served index page? It would help for an end-user to verify that the they download the right file, comparing the file size to the expected value.

Add option to serve files via Tor hidden service

Tor hidden services (v3) have the advantage of being accessible from the internet without having to set up any port forwarding from the router (that's using NAT). Additionally the traffic is encrypted by default.

It should be possible to launch a temporary hidden service with a single simple serve command.

Libraries:

With those libraries it should be possible to include Tor in the single serve binary, without requiring the user to install anything.

Other info:

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.