Hacker News
3 years ago by satyanash

The ruby one with the -run option is a bit nonintuitive in how it works.

  $ ruby -run -ehttpd . -p8000
The -r option requires un.rb[1] which is a file full of convenience functions, such as httpd in this example. Classic Ruby.

Given that go has popularized long args with a single hyphen (-name etc), it is easy to mistake -run as an option by itself.

[1] https://github.com/ruby/ruby/blob/master/lib/un.rb#L323

3 years ago by BiteCode_dev

> go has popularized long args, with a single hyphen (-name etc)

Why did they do that?

It took us 20 years to standardize on - for short and -- for long, with occasional finger rage on tar or find, and now this?

What were they thinking?

3 years ago by unscaled

My hunch is that Rob Pike, Ken Thompson, Russ Cox and the other Bell Labs alumni behind Go disliked GNU getopt-style flags, like they dislike a lot of other GNU and BSD decisions that "contaminate" the original philosophy behind Unix.

This overall attitude has led to many design decisions in Go, which define the language for better or worse. Statically-linked executables, for instance, contributed more than anything else to Go's popularity as a CLI tool language. Of course, the Bell Labs crowd was already highly skeptical of dynamic linking. See Rob Pike's opinion here: http://harmful.cat-v.org/software/dynamic-linking/

I say it's a hunch, but I think Russ Cox's following comments pretty much demonstrate this attitude against GNUisms and BSDisms: https://github.com/golang/go/issues/2096#issuecomment-660578... https://news.ycombinator.com/item?id=9207316

On the other hand, Russ clearly goes on to say they designed the flags not based on Plan 9 (which only had short single-letter flags), but on Google's gflags library: https://github.com/golang/go/issues/2096#issuecomment-660578...

In short, it's probably both:

- Innate distrust of all things BSD/GNU meant that the original Go team didn't feel they have to honor the established tradition. Just like dynamic linking, they believed that if there is something that GNU does wrong, they don't need to follow it just for the sake of keeping compatibility.

- Positive experience using gflags convinced the team that the gflags approach (single-dash long flags) is the best one.

I personally think they were wrong here. As Russ Cox himself clearly stated in response to all requests for fixing go flags: there are many libraries out there who implement GNU-style flags. What happened in practice is that most Go developers voted with their feet and chose a third-party flag module (even Google's own Kubernetes is using spf13/cobra). In the end, the Go flags package just ended up causing more confusion and didn't solve any of the problems (perceived or real) with GNU flags.

3 years ago by BiteCode_dev

Damn, a constructive and sourced answer. I wish I could upvote that twice.

3 years ago by xaduha

You can use -- or - as far as Go proper goes, doesn't matter in most cases. I think popular args libraries do that too, but there's a million of them, so some probably don't.

3 years ago by masklinn

> What were they thinking?

They were starting back from the 70s.

Also one more check for go being alt.history.java, this style is also the standard for Java tooling.

And Apple, I think.

3 years ago by nonameiguess

Also the standard for PowerShell.

3 years ago by kazinator

The XWindow system used -long -opts long before that.

3 years ago by BiteCode_dev

The XWindow system is a collection of the worse api in the world so it's no surprise.

But the vast majority of modern command line tools agree on --long.

3 years ago by gimboland

...aaaand it's more than 20 years old, so yeah, that kinda agrees with the point that it took us a long time to stop doing that because it's confusing.

3 years ago by Sohcahtoa82

I've always disliked not having a space between a -parameter and it's option. "-r un" is so much more readable and explicit than "-run".

Why do people not include that space? Certainly it's not to save the time of not hitting the spacebar, right?

3 years ago by amarshall

Permalink: https://github.com/ruby/ruby/blob/v3_0_1/lib/un.rb#L323

(Tip: can hit ā€œyā€ on GitHub to change the URL to a revision-based permalink)

3 years ago by lipanski

My favourite is thttpd [1] which is super tiny, battle-tested and actually meant for the job (and only this job). It's available as a package on most Linux distros.

Serving a static folder `/static` on port `3000` as user `static-user` and with cache headers set to 60 seconds would go like this:

  thttpd -D -h 0.0.0.0 -p 3000 -d /static -u static-user -l - -M 60
Even if you've got Python lying around on every Ubuntu server, I still don't get why you wouldn't use something leaner to serve your static files, as long as it's easy to install/configure. Same goes for most of the runtimes in that list.

[1] https://www.acme.com/software/thttpd/

3 years ago by Evidlo

Because the point is that I want a webserver up now. If I was running something long-term I would just use Caddy anyway.

3 years ago by Macha

Yeah, I want a HTTP server up because I need an actual server to test my web app or because I want to send a large file to someone on my local network and don't want to guide them through setting up smb/rsync/whatever and just want to give them a URL.

I don't particularly care about what's least likely to fall over under sustained load or is suitable security wise to expose to the internet, because it's not going to have to deal with either of these things. Being "already installed" on the other hand is a big selling point.

3 years ago by makeworld
3 years ago by throw0101a

> My favourite is thttpd [1] which is super tiny, battle-tested and actually meant for the job (and only this job). It's available as a package on most Linux distros.

Surprising not on Debian or Ubuntu AFAICT:

* https://packages.debian.org/search?keywords=thttpd

Though it does seem to have this from the same author:

* https://packages.debian.org/search?keywords=mini-httpd

* http://www.acme.com/software/mini_httpd/

There are times that I want to run Let's Encrypt that's not a full-time web server (SMTP, IMAP, etc), and it would be handy to spin up something ad hoc on tcp/80 to do the verification step and then stop it right after.

3 years ago by jart

thttpd has one cool cat badge icon but have you seen its critical path http parsing code?

        /* Read the MIME headers. */
        while ( ( buf = bufgets( hc ) ) != (char*) 0 )
            {
            if ( buf[0] == '\0' )
                break;
            if ( strncasecmp( buf, "Referer:", 8 ) == 0 )
                {
                cp = &buf[8];
                cp += strspn( cp, " \t" );
                hc->referrer = cp;
                }
            else if ( strncasecmp( buf, "Referrer:", 9 ) == 0 )
                {
                cp = &buf[9];
                cp += strspn( cp, " \t" );
                hc->referrer = cp;
                }
            else if ( strncasecmp( buf, "User-Agent:", 11 ) == 0 )
                {
                cp = &buf[11];
                cp += strspn( cp, " \t" );
                hc->useragent = cp;
                }
            else if ( strncasecmp( buf, "Host:", 5 ) == 0 )
                {
                cp = &buf[5];
                cp += strspn( cp, " \t" );
                hc->hdrhost = cp;
Use perfect hash tables for known http headers, because they're perfect.
3 years ago by FriedrichN

I often use netcat to test stuff locally.

  while true; do cat index.html | nc -l 9999 -q 1; echo -e "\n---"; done
3 years ago by rijoja

nice one

3 years ago by mousepilot

netcat is just handy in general!

3 years ago by kevincox

Note that a lot of these bind to 0.0.0.0 by default. This has caused me surprises in the past as I was failing to connect to a host that is available over IPv6. Sometimes it was even intermittent as I would sometime resolve to the IPv4 and sometimes get the IPv6 and fail.

For python3 this is easily remedied.

    python -m http.server -b ::
On most OS configurations this will listen on both IPv4 and IPv6.

Or for when you only need local access:

    python -m http.server -b localhost
3 years ago by darkwater

For the use cases of most of that software list, they should actually listen to localhost (127.0.0.1 and ::1) only, because security. Listening on every IPv6 interface, which might be exposed directly on the IPv6 internet, is even a worse idea.

3 years ago by kevincox

In general I agree. Localhost is a safer default, it doesn't cost much to type a bind address when you need jt. However 0.0.0.0 is a worse default than ::

3 years ago by chrismorgan

(2013). There are many comments since then providing more alternatives, many of which didnā€™t exist back in 2013, but the article itself hasnā€™t been touched since 2013-07-07.

3 years ago by aoleinik

While the author hasnā€™t updated the main link, itā€™s clear he checked up on the article until atleast 2017: one of the comments originally was a base64 encoded string, and the author edited and deleted it so that no one would run random base64 strings off the internet.

3 years ago by mradmin

Some of these are multi-liners that can be converted to one-liners. For example I believe "npx" can be used for all the node examples for example "npx http-server -p 6007 ./root"

[edit] ahh i see this is called out in the gist comments

3 years ago by jfjfhvhfhfhfhfh

$ emrun --port 8000 . # Handles WASM; most others don't.[1]

[1] Emscripten's emsdk includes emrun, which actually serves WASM files with the correct MIME type out-of-the-box, unlike the python2 and python3 servers and most others.

3 years ago by henearkr

Does emrun allow CORS, required for SharedArrayBuffers?

3 years ago by capableweb

CORS is up to the server you're calling, not up to the server hosting the JS code. Any server that supports custom HTTP headers, support CORS. No, SharedArrayBuffers don't require "CORS" (which you probably mean if they work in CORS context rather than "require"). What they do require is a Secure Context (https, localhost or similar) https://developer.mozilla.org/en-US/docs/Web/Security/Secure...

I wonder how come CORS is such a misunderstood concept globally. It's a really simple concept in general, and understanding it will make a lot of your work as a frontend/full stack developer easier. Take a day and fully understand it, it'll pay off.

3 years ago by abhishekjha

Isn't python's server blocking? If you make two requests simultaneously, one of them will have to wait.

3 years ago by masklinn

Thatā€™s correct. Well blocking is not much of an issue in and of itself but itā€™s blocking and single process and single threaded, so it can only serve one request at a time.

Itā€™s not usually an issue for small stuff, but it does mean you canā€™t really use this snippet to serve big files for a lan, which is a bit of a surprise the first time you hit that limitation.

3 years ago by oss2020

Python 2 was blocking. Python 3 is non-blocking.

Daily Digest

Get a daily email with the the top stories from Hacker News. No spam, unsubscribe at any time.