[HN Gopher] static-server: an HTTP server in Go for static content
___________________________________________________________________
static-server: an HTTP server in Go for static content
Author : chmaynard
Score : 53 points
Date : 2023-09-16 13:41 UTC (9 hours ago)
(HTM) web link (eli.thegreenplace.net)
(TXT) w3m dump (eli.thegreenplace.net)
| ssddanbrown wrote:
| I wrote something like this [1] for the team at my old workplace.
| We mainly worked on static html files but some functionality
| required loading via http. Many of the devs were quite new to
| development in general, so I built a simple static server in Go,
| as an exe which they could set as the default for `.html` files,
| and therefore they could just open html files on the webserver
| via double-click as normal. The program would watch the directory
| (if not already open and watching) then open the right path in
| the default browser. I also built-in livereload, management via
| tray icon and a basic web UI.
|
| [1] https://github.com/ssddanbrown/webby
| simonw wrote:
| This is cool - I didn't know you could have Go one-liners that
| look like this: go run
| github.com/eliben/static-server@latest
|
| I had to upgrade to Go 1.21 for this to work - I was previously
| on Go 1.20. "brew upgrade go" worked for me.
|
| Looks like almost the entire implementation is here, it's mostly
| CLI option parsing logic: https://github.com/eliben/static-
| server/blob/main/internal/s...
| eliben wrote:
| Indeed, the actual heavy lifting is done by the Go standard
| library; this line (https://github.com/eliben/static-
| server/blob/main/internal/s...) is where the real magic happens
| (ignoring the logging middleware):
| fileHandler := serveLogger(serveLog,
| http.FileServer(http.Dir(rootDir)))
| flashgordon wrote:
| Awesome. There is a very surreal joy in building such standalone
| tools even just for learning. I have been working on a kitchen
| sync style "chat" app to experiment with new ideas (like
| integration with X/y/z). I just need to muster the courage to
| publish it!
| quinnftw wrote:
| Looking at the code this appears [1] to be a very thin wrapper
| around go's built in file server from the http package.
|
| [1]: https://github.com/eliben/static-
| server/blob/main/internal/s...
| mholt wrote:
| These are fun to make. I've done it several times. :) That is why
| I wrote Caddy: $ caddy file-server
|
| It does templates, TLS, and other production things really easily
| from the command line too, including automatically getting
| certificates: $ caddy file-server --domain
| example.com
|
| Done!
|
| I think projects like static-server are wonderful learning
| examples of how to get Useful Things done in Go.
| e12e wrote:
| Wait, file-server without arguments does dynamic content
| (templating)?!
|
| I assume that's just poorly phrased?
| mholt wrote:
| To clarify, you do need to use --templates to enable template
| evaluation on the static files.
|
| But for the `caddy respond` command, minimal templates are
| available by default; see the docs here:
| https://caddyserver.com/docs/command-line#examples
| skrebbel wrote:
| Only for directory listings I think. And of course you can
| turn that off as well.
| [deleted]
| eliben wrote:
| Thanks for the comment, Matt! I love Caddy. For some reason I
| thought it needs a configuration file.
|
| The simplest cmdline I found to run it as a local server on a
| non-priveledged port with listings is: $
| caddy file-server --listen localhost:8099 --browse
|
| Is there a simpler way I'm missing?
| mholt wrote:
| On Mac, the defaults aren't privileged. (Not sure why. That's
| just how it is.)
|
| The --browse flag is optional and unrelated to
| ports/privileges. Otherwise, that sounds about right. Caddy
| defaults to port 80 unless you give it a domain name, then it
| defaults to port 443 and redirects HTTP on port 80 to HTTPS.
| abhishekjha wrote:
| Is there more to the philosophy of why caddy exists? I am
| trying to jump into a few open source projects to hone my
| programming skills and I have a harder time comprehending
| things if I don't know what was the overall intention of the
| authors.
| simonw wrote:
| One of the big selling points of Caddy for me is that you can
| reconfigure it "live" without restarting the server.
|
| This is great for if you want to be able to do zero-downtime
| deploys of new applications behind a proxy server or similar.
| mholt wrote:
| Absolutely! Thanks for the feedback, Simon!
| unethical_ban wrote:
| Caddy's appeal when I last looked at it some years ago was
| that the configuration file format was very easy to read and
| use; and that configuration itself was minimal. It came/comes
| with Letsencrypt integration which was novel some years ago,
| so setting up a secure site was even easier for people who
| weren't used to it.
|
| Its syntax for being configured as a reverse proxy (secure
| front-end to less secure back-end servers) is similarly
| pretty easy.
|
| I haven't looked at it in a long time because I recall them
| screwing with their terms of service so it wasn't fully FOSS
| by the most liberal definition.
| kstrauser wrote:
| It's had an Apache-2.0 license for at least the last 4
| years:
| https://github.com/caddyserver/caddy/blob/master/LICENSE
| mholt wrote:
| Caddy has ALWAYS had the Apache 2.0 license. For a time we
| did additionally offer officially licensed binaries for
| companies, but Caddy has never deviated from Apache 2.
|
| Caddy's ease of use is one feature, but there are many more
| - like the ability to massively scale your TLS to thousands
| of sites reliably. And to use the on-line configuration API
| to make changes to your server. There's a ton to discover
| with Caddy, it's not just a tool for beginners. ;)
| mholt wrote:
| Caddy 1 was created because I needed a quick and easy web
| server for a lot of my projects.
|
| Caddy 2 was created when I got serious about it, and we had
| governments and enterprises starting to rely on the project.
|
| Now we exist because we advocate for (and deliver!) HTTPS on
| every site, memory safety, dynamic configuration,
| extensibility, and many more features valuable in a modern
| web server.
|
| Hope that helps :)
| gabereiser wrote:
| While I love Go, have we gotten this lazy that we need a package
| for this? Go does this in 3 lines minimum, like you describe in
| your blogpost. However, in your package you expose the ability to
| kill your server [0] without any security. That's a huge
| vulnerability. I know you'll say "It's just a static server,
| meant for serving static stuff" but it will be indexed by
| pkg.go.dev, people will use this outside your intent. It is the
| way. At the very least, use a secret token.
|
| [0] https://github.com/eliben/static-
| server/blob/3ce83524ed54298...
| eliben wrote:
| Thanks for your comment. I surely hope no one will even
| consider using this server for anything public-facing :) It's
| solely for testing on localhost.
|
| The shutdown endpoint is used for robust testing; I suppose I
| can hide it a bit more, like using an environment variable or
| something.
| midwit wrote:
| A simple middleware hook for http basic auth :)
| gabereiser wrote:
| Just check a header for a secret key you generate when you
| startup. Easy peasy. This keeps you able to call it for
| testing (granted you read from stdout or passed the key to
| tests as a variable). Then some scripto ransomware User from
| Omgodisztan doesn't shutdown your server from the tent he's
| camped in with Starlink.
| d-z-m wrote:
| It's fine the way it is IMO. However, it might be worth
| caveating in the README that it's for local testing only, the
| same way you do in your blog post.
|
| Mainly because of the shutdown endpoint, but also that the
| -cors flag returns "Access-Control-Allow-Origin: *" exposing
| you to arbitrary cross origin requests.
| jjice wrote:
| > I know you'll say "It's just a static server, meant for
| serving static stuff" but it will be indexed by pkg.go.dev,
| people will use this outside your intent.
|
| While true, I don't think the author should refrain from making
| code available based on the potential negatives from others
| using code they didn't even bother to read the documentation
| for.
| gabereiser wrote:
| You're right, however, due to the nature of the go ecosystem,
| someone will use it - host their react app with it - and
| expose an endpoint that could shutdown their server. I think
| that warrants being called out for.
| nicoburns wrote:
| These kind of servers are useful for quickly serving a folder
| of files locally. Security isn't a primary concern for these
| kind of use cases.
| tgv wrote:
| $ python -m http.server
| chrismarlow9 wrote:
| https://gist.github.com/willurd/5720255
| inChargeOfIT wrote:
| Assuming you have python installed on the system, yeah.
| sdf4j wrote:
| python 2 and not 3
| maleldil wrote:
| `python -m http.server` is the one for Python3. Python 2
| is `python -m SimpleHTTPServer`
| joaomacp wrote:
| or the node one:
|
| $ npm install http-server
|
| $ http-server .
| parminya wrote:
| or the go one:
|
| $ go run github.com/eliben/static-server@latest
| PinguTS wrote:
| That is the argument of the first MVP by a startup and then
| it is their onlien product.
|
| I have this seen also in automotive. "This is no problem,
| because this is not connected to the Internet." Then a few
| years later you have a DefCon presentation "GM hack, you can
| control the whole car via the Internet".
| gabereiser wrote:
| Where are you hosting your client-side code? Let me see if I
| can shut it down...
| canadaduane wrote:
| Out of curiosity, are there alternatives to this that are already
| well established or distributed? For example, something you'd get
| in debian linux?
___________________________________________________________________
(page generated 2023-09-16 23:01 UTC)