I made this for myself, because my blog is served as static HTML via GitHub Pages and it's hard to test locally because all of my absolute paths break (links, imgs, scripts, css, etc.). I tried using the Python module http.server, but it doesn't support dropping the file extension (e.g. /about instead of /about.html). Thought somebody else doing the same might find this useful.
Did you test it against relative path(s) ? For example, what if "../" is included in the file path ? It can be used to escape the root folder and traverse arbitrarily in the host file system.
That's a great question. Although I don't encourage anybody to expose this to any network they don't trust, it was a concern. I was previously passing the incoming path directly to ServeFile[1] which handles this, although I have since put in a filepath.Clean... I've tested this in browsers and with curl and it looks okay, I'll take a closer look at this though.
FYI GitHub Pages is merely running Jekyll (jekyllrb.com) with a couple of commonly used plugins. If you want to test you site locally you'll be better off using that.
That's a fair point. Previous iterations of my GitHub Pages used Jekyll and I used that at the time to test it, but I recently switched to plain-old-HTML and honestly it didn't occur to me that Jekyll would still work for testing it. Having said that, installing Jekyll[1] has quite a few steps and requires quite a few dependencies which I don't typically have installed, so this is a bit easier for me to distribute to my various machines.
> The source code doesn’t do anything related with GitHub pages though.
I'm not sure what your point is here exactly. Although the source code makes no mention of GitHub Pages, and you're more than welcome to use this for anything you'd like, it was specifically built to mimic the behaviour of GitHub Pages w.r.t. the custom 404 and the dropped .html extension.
> You may want to change the default port from :80 to :8080 so people don’t have to set “-port” every time.
Good point. I personally use :80 a lot but I realise :8080 is pretty standard so will use that.
> But your code says otherwise [1] since there is no 404.html file in the repository.
Edit: In case it's not clear, this is designed for testing your GitHub Page site locally, before pushing. I'll update the Readme a bit to make this clearer.
>> The source code doesn’t do anything related with GitHub pages though.
> I'm not sure what your point is here exactly.
The title, "Serve Static GitHub Pages Locally," makes it sound like you're serving github pages. Maybe "serve local static pages like github does" would make it more clear.
Have to echo the op's remark here—what's the difference between "serving static GitHub pages locally" and "serving local static pages like github"? I can't see any possible interpretation of the former that doesn't equate to the latter.
What did you assume it did when you read the title?
I will need some headers like content-type too.
https://unix4lyfe.org/darkhttpd/
darkhttpd is a simple (3k lines of C, no deps) HTTP server that handles headers and encoding. may be a good case to study.
Thanks for sharing that, I'll give it a look. I think that http.ServeFile handles content type automatically, because when I test this locally I'm seeing Content-Type in the response headers.
consider it as a feature request, but if you really plan to match github pages, I hope you will eventually include an on the fly renderer for org-mode files too, like GitHub. Markdown serving packages are dime a dozen, I am yet to see something that will serve org files without having to export first.
Sorry, to be clear the tool is designed to make it easier to locally test your static HTML GitHub Pages repos, where things like a `/about` link will not resolve in the context of your filesystem and likely also won't know to check for `about.html`. I'm not trying to make sites equivalent to GitHub Pages from other sources. Does GitHub Pages actually support org-mode? That's certainly news to me, and if so I'll take a look into how it works and whether I can add support.
My website is a static Github page that's been built without any site generator, but I've set all the paths to be relative so your main issue of "all of my absolute paths break" doesn't really apply and the website still works fine. I then don't need another program besides Brackets to do all my editing and testing in. And as far as other people's comments, it looks like Jekyll can spit out relative paths so it doesn't exactly do much.
Oh you're right, I typed that address by hand having found the page through the Google app on my phone, so didn't notice I wasn't using HTTPS. There's an issue on their GitHub that's been unanswered since November last year... https://github.com/adobe/brackets/issues/14591
Check out npm serve as a reference, it does nearly the same thing, but I assume written in javascript. It would be cool to have a faster drop-in replacement for serve (not that serve has ever been slow for me).
Good idea, thanks for the suggestion. I have thought about whipping up a version of ghp in a couple of different languages as a comparison - I originally wrote it in C#.
24 comments
[ 3.1 ms ] story [ 54.5 ms ] threadI made this for myself, because my blog is served as static HTML via GitHub Pages and it's hard to test locally because all of my absolute paths break (links, imgs, scripts, css, etc.). I tried using the Python module http.server, but it doesn't support dropping the file extension (e.g. /about instead of /about.html). Thought somebody else doing the same might find this useful.
[1]: https://golang.org/pkg/net/http/#ServeFile
[1]: https://help.github.com/articles/setting-up-your-github-page...
The source code doesn’t do anything related with GitHub pages though.
It simply starts a file server with no more features than adding “.html” at the end of the URL.
You may want to change the default port from :80 to :8080 so people don’t have to set “-port” every time.
Also, in the README, you say that one of the implemented features is:
> 4. Check whether 404.html is a file, if so serve that file as a 404
But your code says otherwise [1] since there is no 404.html file in the repository.
[1] https://github.com/CurtisLusmore/ghp/blob/6b6e2bd/ghp.go#L25...
> The source code doesn’t do anything related with GitHub pages though.
I'm not sure what your point is here exactly. Although the source code makes no mention of GitHub Pages, and you're more than welcome to use this for anything you'd like, it was specifically built to mimic the behaviour of GitHub Pages w.r.t. the custom 404 and the dropped .html extension.
> You may want to change the default port from :80 to :8080 so people don’t have to set “-port” every time.
Good point. I personally use :80 a lot but I realise :8080 is pretty standard so will use that.
> But your code says otherwise [1] since there is no 404.html file in the repository.
The 404.html file is not part of this repository, it's part of the directory you are serving. See https://help.github.com/articles/creating-a-custom-404-page-...
Edit: In case it's not clear, this is designed for testing your GitHub Page site locally, before pushing. I'll update the Readme a bit to make this clearer.
> I'm not sure what your point is here exactly.
The title, "Serve Static GitHub Pages Locally," makes it sound like you're serving github pages. Maybe "serve local static pages like github does" would make it more clear.
What did you assume it did when you read the title?
However, to be honest, I see no advantage over Jekyll. A nice side-project to learn go on one hand, on the other, does not bring much to GitHub pages.
The only relevant header that is missing is the "Access-Control-Allow-Origin: *" That comes from github but not from you server.
In 404, github sends Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; img-src data:; connect-src 'self'