├── .gitignore ├── LICENSE ├── README.md ├── go.mod ├── go.sum └── markdir.go /.gitignore: -------------------------------------------------------------------------------- 1 | /markdir 2 | /markdir.exe 3 | 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Barracuda Networks, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | markdir 2 | ======= 3 | 4 | Markdir serves up a directory of files in HTML, rendering Markdown files 5 | into HTML when they are encountered as `.md` files. It's sort of the most 6 | degenerate Wiki you could imagine writing short of simply having static 7 | HTML files. 8 | 9 | Markdir started out as a simple web application that did something useful 10 | for me. However, I also noticed when I was done that this was a 11 | reasonable answer to a question I've seen on /r/golang a few times: "Does 12 | anyone have a Go web app that does something non-trivial that I can look at 13 | to see how it all works?" 14 | 15 | Yes. This actually works out pretty well. This uses enough features that 16 | it's not a "hello world" app: 17 | 18 | * Loads an external library from github.com. 19 | * Uses the flag library to determine where to bind. 20 | * Uses the built-in HTTP server. 21 | * Uses the built-in html/template code. 22 | * Including a use of template.HTML to indicate already-HTML-encoded text. 23 | * Implements a struct-based HTTP handler. 24 | * Demonstrates both declared and anonymous struct usage. 25 | * Demonstrates wrapping an existing HTTP handler, that is to say, the 26 | Markdown server is the very simplest sort of "middleware" you can have, 27 | manually spelled out without a "framework". 28 | 29 | This is not written to be a "tour de force" of Go, nor to show off my own 30 | skills, nor to be the fanciest thing ever... it's written to be a readable, 31 | useful example. It's fewer bytes than this README.md is. 32 | 33 | Installation 34 | ============ 35 | 36 | go get -v -u github.com/thejerf/markdir 37 | ./markdir -h # see the default flag help file 38 | ./markdir # serves the directory 39 | 40 | The `-v` is just to show you what is being installed, since this is a 41 | learning exercise. `-u` says to update if necessary. 42 | 43 | Navigate to [http://localhost:19000](http://localhost:19000) by default to 44 | see the server. You may need to find some markdown files to see the program 45 | doing anything useful, though. If you start it up in the directory this 46 | repo clones into, you can go 47 | to [http://localhost:19000/README.md](http://localhost:19000/README.md) to 48 | read this very file through the server. 49 | 50 | Security 51 | ======== 52 | 53 | This HTTP server accepts no commands beyond GET commands to read the files 54 | in your directory. In theory, because this only reads files off of the 55 | disk, even if the blackfriday library is vulnerable to something you'd 56 | still have to have disk access to exploit it. 57 | 58 | That said, I have this bind to localhost by default on purpose. I'd think 59 | twice about opening this up to the internet, because you should always 60 | think twice about that. If I were going to do that, I'd probably still take 61 | the step of running the output of blackfriday 62 | through [bluemonday](https://github.com/microcosm-cc/bluemonday). Call it a 63 | good exercise. 64 | 65 | [titpetric on /r/golang also mentions](https://www.reddit.com/r/golang/comments/626m0s/markdir_a_simple_but_nontrivial_nethttp_example/dflhjqr/) that 66 | if you were going to put something like this up on the Internet, you ought 67 | to use read, write, and idle timeouts. As those appeared in net/http in Go 68 | 1.8, I've not put them in here. 69 | 70 | Release History 71 | =============== 72 | 73 | * v1.0.2: Internal changes as suggested by Reddit. 74 | * v1.0.1: Internal rename to make this lint-clean by my gometalinter standards. 75 | * v1.0: Initial release. 76 | 77 | Other Simple Projects 78 | ===================== 79 | 80 | * [sonyflake](https://github.com/titpetric/sonyflake): A service for 81 | generating sortable IDs. Note that repo has a lot more files because 82 | it's all set up to be run in Docker, but the [actual Go code that 83 | implements the service](https://github.com/titpetric/sonyflake/blob/master/main.go) is 84 | comparable in size. sonyflake also has an example of dumping out 85 | JSON. 86 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module markdir 2 | 3 | go 1.15 4 | 5 | require github.com/russross/blackfriday v1.6.0 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= 2 | github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= 3 | -------------------------------------------------------------------------------- /markdir.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "flag" 6 | "html/template" 7 | "io/ioutil" 8 | "log" 9 | "net/http" 10 | "os" 11 | "strings" 12 | 13 | "github.com/russross/blackfriday" 14 | ) 15 | 16 | var bind = flag.String("bind", "127.0.0.1:19000", "port to run the server on") 17 | 18 | func main() { 19 | flag.Parse() 20 | 21 | httpdir := http.Dir(".") 22 | handler := renderer{httpdir, http.FileServer(httpdir)} 23 | 24 | log.Println("Serving on http://" + *bind) 25 | log.Fatal(http.ListenAndServe(*bind, handler)) 26 | } 27 | 28 | var outputTemplate = template.Must(template.New("base").Parse(` 29 | 30 |
31 |