Show HN: Easy-to-configure Web Server in Go
github.com
github.com
In the case of the former, that's a huge step backwards in terms of security.
In the case of the latter, that would mean you'd need another reverse proxy hooked up - which would negate the need for this web server to begin with.
This can easily be fixed within Go though:
import (
"log"
"syscall"
)
const (
user_id int = 1000
group_id int = 1000
)
func secureDaemon() {
// set group id first as you need to be root to change group
err := syscall.Setgid(group_id)
if err != nil {
log.Fatalln(err)
}
err = syscall.Setuid(user_id)
if err != nil {
log.Fatalln(err)
}
}
You can also add chroot to your code if you want to be ultra paranoid: import (
"os"
)
const (
chroot_dir string = "/opt/go-webserver"
)
func chrootDaemon() {
err := os.Chdir(chroot_dir)
if err != nil {
log.Fatalln(err)
}
err = syscall.Chroot(chroot_dir)
if err != nil {
log.Fatalln(err)
}
}
This will need to be done before you change your user ID (as you need root permissions to chroot) and you may need to compile the Go without CGO because some of the standard Go libraries will have SO dependencies (I found this to be the case with domain name lookups).(the above code is adapted from my own Go web framework that I'm in the processes of building)
With github, it's very rare when I have anything worth contributing to other peoples gits so I've never really missed it. But I'm sure I'll end up on there at some point in the future.
usage example; http://github.com/azer/boxcars#security
thanks for the helpful comment!
https://github.com/sarnowski/mitigation/blob/master/mitigati...
Comments mentions safe OS and golang bugticket.
However you have given me reason to test my own code again and more thoroughly :-)
(1) I find error handling just too tedious to get right (Edit: "I find error handling _in Go_ just too tedious...")
A recent issue where one of our developers ate an exception cost us 12 days of developer time. Another historical issue where the error handling and return codes weren't understood and handled correctly threw 500mb of stack dumps a minute and took our logging system out.
Spent the time to get it right :)
I added an edit to my comment to avoid the implication you picked up on!
Go even has exceptions, it just doesn't usually use them.
Can you explain what you think the problem is with supporting exceptions?
You raise a good point though, in that there is a valid question of "how would you introduce exceptions into the language / runtime". I think the answer is that the err return value can become implicit. Throwing an exception is the equivalent of "return _, err". Invoking a function that can throw an exception is done by not checking the err return; if an exception is thrown/returned and not checked then it is immediately rethrown (return _,err) in an implicit method. try/catch should be easy to introduce, although the semantics of e.g. "defer" could be tricky.
Exceptions propagate up the call stack within a goroutine, and then, if not recovered within the goroutine that raised them, crash the whole program.
(I cheated a bit -- that's how go already handles exceptions, which it calls "panics". The difference between go and, say, Java is that the core and standard library don't panic as much as Java's throws exceptions, leaving the decision to panic to user code more often.)
The Go version may in fact be faster, but I don't think that's necessarily fair either: if the Go version adds features to be more comparable to nginx it would definitely slow down.
Good point. That is often how alternative parallel implementations are started. A small example is written. Benchmarks are published. The new project is hailed as better than predecessor. Many jump ship. Request for features comes in. New features starts to slow down the product. Someone new comes, writes a simple benchmark and so on.
* Are they relevant. Does this represent the expected production workload. You could find this is 10x better than nginx at some feature but that feature is just not interesting to you then benchmarks are not that interesting
* Does the speed difference matter? Does it matter if the page loads 1ms faster when it was only 20ms before.
* Does it scale. This kind of relates to first question but it looks at abnormal amounts of traffic (Slashdot effects). Either from an attack or just becoming popular too quickly. If simply adds a server with more CPUs would that let Go server scale better than nginx? It might even though nginx could probably process sequential requests faster.
I wrote a flexible reverse proxy[0] using node.js, a year or so ago, and haven't missed the ability to serve static files directly - so I'm wondering what the use-case for that is? I guess proxying to rails, or similar?
I agree that static serving is not as interesting, but it is useful to be able to serve up a fail-whale page!
I'm sure that if I were to pimp the project properly then that would be a good thing to do, but half the fun of my proxy is to allow "interesting" rewrites, dynamically.
To benchmark I'd be too tempted try to game the results by doing a straight pass-through comparison to mod_proxy, nginx, etc. That would lose half of the appeal of the project in the first place.
and here is the benchmarks of it; https://gist.github.com/azer/5946227
It should probably be described as 'an easily embeddable and extendable(?) option for hosting your golang web app'.
In fairness though, json will probably wind up being a common configuration format anyhow. And the idea of programmatically configurable system software is nice. I liked the Mongrel2 approach of having it in SQLite.
That said, I can't think of any reason a web server needs super accurate numbers. All the config options I can think of require nice round ints. Maybe specifying weights to individual backends to proxy to (so all the weights sum up to 1.0)?
JSON is a subset of the ECMA JavaScript standard which declares only floating point.
Do "100!" on wolfram alpha and find me a parser that will load that as an example.
I think I would prefer toml take off as a config language.
We use XML (still after 10 years). For all its warts, at least parsers and deserializers work properly.
Is HTTPS supported or planned?
(I'm more used to the Clojure namespace/filesystem symmetry, so this is somewhat new to me. I like the more shallow project tree but it's not immediately apparent where things are defined.)