Self-hosted service
projectdiscovery/simplehttpserver avatar
projectdiscovery/simplehttpserver

simplehttpserver adds TLS, uploads and a fake TCP server to the file server

Go alternative of python SimpleHTTPServer

544 stars57 forksGoMIT

At a glance

What is it?
This is a Go take on Python's SimpleHTTPServer that also exposes a customizable TCP server with TLS, serves files from any directory, dumps requests and responses, and can be driven by YAML rules for canned responses. It is MIT licensed, installs with a single go install command, and the last tagged release is from 2023.
Who is it for?
Adopt simplehttpserver if you need to serve a directory over HTTP with TLS, uploads or basic auth and would rather not pull in a full web server, or if you need a scriptable TCP listener that answers with canned responses for testing. Do not adopt it as a production web server, because the readme shows it listening on all interfaces by default and the documentation gives no hardening guidance.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A file server that also pretends to be a TCP server

SimpleHTTPserver is a Go enhanced version of the well known Python simplehttpserver, with in addition a fully customizable TCP server, both supporting TLS.

That second half is the unusual part. The HTTP side does what you would expect from a static file server. The TCP side is a listener that answers with responses you define, which makes it useful as a stand-in for a service your code has to talk to but that you do not have running.

The feature list is short and specific. There is an HTTP or HTTPS web server, a file server with arbitrary directory support, HTTP request and response dump, a configurable IP address and listening port, and a configurable HTTP or TCP server with a customizable response via a YAML template.

So there are three modes worth distinguishing. A plain file server, an HTTP server with the extra behaviour switched on, and a TCP server that is not a file server at all but speaks whatever you tell it to speak. The TLS support covers both the HTTP and the TCP side, which is what makes the TCP mode usable against a client that refuses plaintext.

The project is by ProjectDiscovery, the homepage is projectdiscovery.io, and the licence is MIT. It is a small tool with a small footprint: the repository holds a cmd directory, an internal directory, a pkg directory, a test directory, a go.mod, a Dockerfile and a goreleaser configuration.

Installation, and the flags that matter

SimpleHTTPserver requires go1.17 or newer to install, and the install is a single command:

sh
go install -v github.com/projectdiscovery/simplehttpserver/cmd/simplehttpserver@latest

The help output lists the switches, and the table is the real reference for the tool.

The basics are -listen for the listening address, defaulting to 127.0.0.1:8000, and -path for the fileserver folder, defaulting to the current directory. The tool also has a -tcp flag for the TCP server, and the tool supports -tls to enable TLS for the TCP server, -https to enable HTTPS on the HTTP side, and -cert and -key for the certificate and its private key.

The certificate handling has a neat convenience. If you do not specify a certificate, one is self generated, and -domain sets the domain name used for that self-generated certificate, with the example being projectdiscovery.io.

The HTTP-only extras are -upload to enable file upload, -max-file-size with a default of 50 MB, -basic-auth with a username:password pair, and -realm for the message the browser shows in its credential prompt. There is -cors to enable cross-origin resource sharing, and -header for an HTTP response header, which can be given multiple times.

Two flags are for testing rather than serving. -verbose dumps the request and response, and -py emulates Python style, which is a nod to the tool this one is modelled on. -silent shows only results, and -version prints the version.

The YAML rules that drive the TCP mode

The TCP server is driven by a rules file, and the format is short:

yaml
rules:
  - match: regex-match
    match-contains: literal-match
    name: rule-name
    response: response data

So a rule has a regular expression match, a literal substring match, a name, and the response data to return. That is enough to write a small fake protocol: match on a command the client sends, and answer with whatever bytes the client expects to see.

The invocation that turns it on combines the flags:

sh
simplehttpserver -rules rules.yaml -tcp -tls -domain localhost

So the rules file, the TCP mode, TLS and the self-signed domain are all needed together, and the domain matters because the TLS handshake happens before any of your rules get a chance to run.

This is the mode that makes the tool more than a file server. A test suite that expects to talk to a device, a licensing server or a hardware dongle can be pointed at a local listener that answers correctly, without the real thing present and without a mock library for a protocol that does not have one.

File upload with basic auth, and how it is called

The upload mode and the basic auth mode are designed to work together, and the readme shows the combination.

sh
simplehttpserver -basic-auth root:root -upload

The description is that this will run the tool and will request the user to enter username and password before authorizing file uploads. The upload is then done with a normal HTTP PUT carrying the basic auth header:

sh
curl -v --user 'root:root' --upload-file file.txt http://localhost:8000/file.txt

So the upload path is a plain HTTP PUT to the file path, and the credential goes in the standard Authorization header. There is no separate upload API, which means a client that does not speak the put-with-basic-auth pattern cannot use it.

The -max-file-size flag caps the upload at 50 MB by default, and the example shows how to raise it to 100. That matters for the use case the mode is presumably for, which is getting a file off a device or a machine that has nothing but a browser and a terminal.

The -realm option sets the basic auth message, and the readme example puts a prompt in it, which is the text a browser shows in its credential dialog.

Docker, and a dependency list that shows the architecture

The Dockerfile is a two-stage build that keeps the final image small.

dockerfile
FROM golang:1.20.2-alpine as build-env
RUN go install -v github.com/projectdiscovery/simplehttpserver/cmd/simplehttpserver@latest

FROM alpine:latest
RUN apk add --no-cache bind-tools ca-certificates
COPY --from=build-env /go/bin/simplehttpserver /usr/local/bin/simplehttpserver
ENTRYPOINT ["simplehttpserver"]

The builder installs the binary from source, and the runtime stage copies it into a plain Alpine image with bind-tools and ca-certificates added. The ca-certificates are there for TLS, and bind-tools for the host lookup the HTTP server needs.

The go.mod tells you how the tool is put together, and the dependency list is short. The direct requirements are fsnotify for filesystem watching, phayes/freeport for finding a free port, projectdiscovery/gologger for the logging with the coloured output you see in the sample logs, projectdiscovery/sslcert for the self-signed certificate generation, and gopkg.in/yaml.v2 for the rules file.

The two internal dependencies are telling. fsnotify means the file server can notice changes on disk, and freeport means it can pick a free port when you ask for port zero or when the configured port is taken. The indirect list is mostly archive libraries, which come in through gologger.

The module requires go 1.19, and the Docker build uses golang 1.20.2-alpine, so the two are slightly out of step with each other, which is harmless but tells you the Dockerfile was not updated when the go directive moved.

Maintenance, and what the sample output tells you

The release history is sparse. The tags are v0.0.6 from 2023-03-20, v0.0.5 from 2022-04-18 and v0.0.4 from 2021-07-28. The last push was on 2026-10-13, and the project is not archived.

So the branch is active and the published versions are old. For a tool whose job is a static file server, that gap matters less than it would for a library, since there is little to break, but it does mean the go install command, which pulls @latest, is what you get rather than a pinned release.

The sample output in the readme is worth reading carefully, because it shows two things. First, the log format:

sh
simplehttpserver

2021/01/11 21:40:48 Serving . on http://0.0.0.0:8000/...
2021/01/11 21:41:15 [::1]:50181 "GET / HTTP/1.1" 200 383
2021/01/11 21:41:15 [::1]:50181 "GET /favicon.ico HTTP/1.1" 404 19

The address line says Serving . on http://0.0.0.0:8000, meaning the current directory and all interfaces, even though the -listen default is 127.0.0.1:8000. That mismatch between the documented default and the observed behaviour is the single most important thing to check before you run this on a machine you care about.

The request lines are the standard combined log format with the status code and the response size, and they show the favicon request that every browser makes, which is a good reminder that a file server serving a browser-facing directory will get a request for a file that does not exist.

The -sandbox flag is listed in the flags table as enabling sandbox mode, and the documentation does not describe its behaviour in detail, so it is worth reading the source before relying on it.

Editorial conclusion

Adopt simplehttpserver if you need to serve a directory over HTTP with TLS, uploads or basic auth and would rather not pull in a full web server, or if you need a scriptable TCP listener that answers with canned responses for testing. Do not adopt it as a production web server, because the readme shows it listening on all interfaces by default and the documentation gives no hardening guidance. Before you expose it, check three things: which address you bind to, since the default is 127.0.0.1:8000 but the sample output shows 0.0.0.0, whether the sandbox mode and basic auth are enough for your use, and which certificate you pass, because the tool will generate a self-signed one with the domain you name if you do not supply your own.

Frequently asked questions

What does simplehttpserver do that Python's SimpleHTTPServer does not?

It adds a fully customizable TCP server alongside the file server, with both supporting TLS, plus HTTP request and response dumping, configurable listening address, file upload with basic auth, and a YAML-driven customizable response. It is a Go alternative to the well known Python simplehttpserver.

How do I install simplehttpserver?

You need go 1.17 or newer, then run go install -v github.com/projectdiscovery/simplehttpserver/cmd/simplehttpserver@latest. There is also a Docker image, and the repository ships a goreleaser configuration for building releases.

How do I make simplehttpserver serve a directory over HTTPS?

Use the -https flag with -cert and -key for your own certificate, or let it self-generate one and set the name with -domain. The -path flag chooses the directory to serve and -listen sets the address, which defaults to 127.0.0.1:8000.

What is the YAML rules file used for?

It drives the TCP mode. Each rule has a regex match, a match-contains literal match, a name and a response, and the tool answers matching requests with that response. You run it with -rules rules.yaml -tcp -tls -domain localhost.

How do I upload a file to simplehttpserver?

Enable the -upload flag and protect it with -basic-auth, then send a PUT with the basic auth header, for example curl -v --user 'root:root' --upload-file file.txt http://localhost:8000/file.txt. The -max-file-size flag caps the upload size and defaults to 50 MB.

Official sources

  1. License: MIT
  2. projectdiscovery/simplehttpserver on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/projectdiscovery-simplehttpserver.svg)](https://hysenlabs.com/projects/projectdiscovery-simplehttpserver)

Was this useful?