From 617843c556d0a075dd51df19643f131d451be3a6 Mon Sep 17 00:00:00 2001 From: at15 Date: Sat, 10 Feb 2018 16:25:17 -0800 Subject: [PATCH] [noodle] Init local fs wraps http.Dir - using `os.Open` would work as well but it would have many 500 if user has url like `index.html/is-not-a-folder` - it is fixed in https://github.com/golang/go/issues/18984 there is a function called `mapDirOpenError` - [ ] TODO: serveFile would call `dirList` and it can't be disabled ... --- README.md | 4 +-- noodle/_examples/single-dir/assets/index.html | 29 ++++++++++++++++++ noodle/_examples/single-dir/assets/main.css | 4 +++ noodle/_examples/single-dir/assets/main.js | 30 +++++++++++++++++++ noodle/_examples/single-dir/main.go | 30 +++++++++++++++++++ noodle/doc/README.md | 15 ++++++++++ noodle/fs_local.go | 24 +++++++++++++++ noodle/fs_multi.go | 3 ++ noodle/fs_zip.go | 1 + noodle/generate.go | 3 ++ noodle/pkg.go | 6 ++++ noodle/zip.go | 1 + requests/auth.go | 2 ++ 13 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 noodle/_examples/single-dir/assets/index.html create mode 100644 noodle/_examples/single-dir/assets/main.css create mode 100644 noodle/_examples/single-dir/assets/main.js create mode 100644 noodle/_examples/single-dir/main.go create mode 100644 noodle/doc/README.md create mode 100644 noodle/fs_local.go create mode 100644 noodle/fs_multi.go create mode 100644 noodle/fs_zip.go create mode 100644 noodle/generate.go create mode 100644 noodle/pkg.go create mode 100644 noodle/zip.go diff --git a/README.md b/README.md index 63120b8..cee2456 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ It has the following components: - [Config](config) A YAML config reader with template support - [Log](log) A Javaish logger for Go, application can control library and set level for different pkg via config or flag - [Generator](generator) Render go template, generate methods for logger interface based on `gommon.yml` -- [Rice](rice) Embed static assets for web application with `.riceignore` support +- [Noodle](noodle) Embed static assets for web application with `.riceignore` support - [Requests](requests) A pythonic wrapper for `net/http`, HTTP for Gopher. - [Cast](cast) Convert Golang types - [Data structure](structure) Bring Set etc. to Golang. @@ -77,7 +77,7 @@ compared to packages it modeled after. - [benbjohnson/tmpl](https://github.com/benbjohnson/tmpl) for go template generator - first saw it in [influxdata/influxdb](https://github.com/influxdata/influxdb/blob/master/tsdb/engine/tsm1/encoding.gen.go.tmpl) - we put template data in `gommon.yml`, so we don't need to pass it via cli -- [GeertJohan/go.rice](https://github.com/GeertJohan/go.rice) for rice +- [GeertJohan/go.rice](https://github.com/GeertJohan/go.rice) for ~~rice~~ noodle - we implemented `.gitignore` like [feature](https://github.com/at15/go.rice/issues/1) but the upstream didn't respond for the [feature request #83](https://github.com/GeertJohan/go.rice/issues/83) ## About diff --git a/noodle/_examples/single-dir/assets/index.html b/noodle/_examples/single-dir/assets/index.html new file mode 100644 index 0000000..c9661fc --- /dev/null +++ b/noodle/_examples/single-dir/assets/index.html @@ -0,0 +1,29 @@ + + + I am title + + + +

If you being just staring at the sun light

+ + + + + + + + + +
ab
cd
+

echarts example + get + started +

+
+

image from unsplash

+unsplash random + + + + \ No newline at end of file diff --git a/noodle/_examples/single-dir/assets/main.css b/noodle/_examples/single-dir/assets/main.css new file mode 100644 index 0000000..6f19e7a --- /dev/null +++ b/noodle/_examples/single-dir/assets/main.css @@ -0,0 +1,4 @@ +body { + background-color: lightcyan; + margin: 20px; +} \ No newline at end of file diff --git a/noodle/_examples/single-dir/assets/main.js b/noodle/_examples/single-dir/assets/main.js new file mode 100644 index 0000000..a310009 --- /dev/null +++ b/noodle/_examples/single-dir/assets/main.js @@ -0,0 +1,30 @@ +'use strict'; + +// alert('this is main'); + +console.log({'o': 'bject'}); + +var myChart = echarts.init(document.getElementById('main')); + +// 指定图表的配置项和数据 +var option = { + title: { + text: 'ECharts 入门示例' + }, + tooltip: {}, + legend: { + data:['销量'] + }, + xAxis: { + data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"] + }, + yAxis: {}, + series: [{ + name: '销量', + type: 'bar', + data: [5, 20, 36, 10, 10, 20] + }] +}; + +// 使用刚指定的配置项和数据显示图表。 +myChart.setOption(option); \ No newline at end of file diff --git a/noodle/_examples/single-dir/main.go b/noodle/_examples/single-dir/main.go new file mode 100644 index 0000000..ffaab25 --- /dev/null +++ b/noodle/_examples/single-dir/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "net/http" + "fmt" + "os" + "github.com/dyweb/gommon/noodle" +) + +func main() { + fs := "default" + if len(os.Args) > 1 { + fs = os.Args[1] + } + fmt.Println(fs) + addr := ":8080" + //addr := ":6667" # https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers 6665-6669 is for IRC ... + fmt.Printf("listen on %s\n", addr) + var root http.FileSystem + switch fs { + case "default": + root = http.Dir("./assets") + case "local": + root = noodle.NewLocal("./assets") + default: + panic("unknown fs") + } + http.ListenAndServe(addr, http.FileServer(root)) + +} diff --git a/noodle/doc/README.md b/noodle/doc/README.md new file mode 100644 index 0000000..fe2af41 --- /dev/null +++ b/noodle/doc/README.md @@ -0,0 +1,15 @@ +# Noodle + +## TODO + +- generate go file based on assets (like most bind-data ish library does) +- figure out how to create and append zipfile, without relying on external zip binary + +## Ref + +- https://github.com/GeertJohan/go.rice 1.6k star, used to use it for Ayi +- https://github.com/shurcooL/vfsgen 236 star listed most packages in alternative section + - https://github.com/shurcooL/vfsgen#alternatives +- https://www.ueber.net/who/mjl/blog/p/assets-in-go-binaries/ describes how to append zip +- https://github.com/cookieo9/resources-go pretty like go.rice +- [golang-nuts/including html contents of a file at compile time](https://groups.google.com/forum/#!topic/golang-nuts/9QUjmDED96E) \ No newline at end of file diff --git a/noodle/fs_local.go b/noodle/fs_local.go new file mode 100644 index 0000000..35355d5 --- /dev/null +++ b/noodle/fs_local.go @@ -0,0 +1,24 @@ +package noodle + +import ( + "net/http" +) + +var _ http.FileSystem = (*LocalFs)(nil) + +type LocalFs struct { + root string + dir http.Dir +} + +func NewLocal(root string) *LocalFs { + return &LocalFs{root: root, dir: http.Dir(root)} +} + +func (fs *LocalFs) Open(name string) (http.File, error) { + //return os.Open(filepath.Join(fs.root, name)) + // NOTE: http.Dir has extra error handling, https://github.com/golang/go/issues/18984 + // some operation are mapped to 404 instead of 500 + // TODO: but it supports list dir and can't be disabled ... + return fs.dir.Open(name) +} diff --git a/noodle/fs_multi.go b/noodle/fs_multi.go new file mode 100644 index 0000000..a90f1fa --- /dev/null +++ b/noodle/fs_multi.go @@ -0,0 +1,3 @@ +package noodle + +// A file system that fall back to another if file not found \ No newline at end of file diff --git a/noodle/fs_zip.go b/noodle/fs_zip.go new file mode 100644 index 0000000..9cef8d3 --- /dev/null +++ b/noodle/fs_zip.go @@ -0,0 +1 @@ +package noodle diff --git a/noodle/generate.go b/noodle/generate.go new file mode 100644 index 0000000..c92226e --- /dev/null +++ b/noodle/generate.go @@ -0,0 +1,3 @@ +package noodle + +// generate assets file with flag \ No newline at end of file diff --git a/noodle/pkg.go b/noodle/pkg.go new file mode 100644 index 0000000..db1a30b --- /dev/null +++ b/noodle/pkg.go @@ -0,0 +1,6 @@ +package noodle + +import "github.com/dyweb/gommon/util/logutil" + +var log = logutil.NewPackageLogger() + diff --git a/noodle/zip.go b/noodle/zip.go new file mode 100644 index 0000000..9cef8d3 --- /dev/null +++ b/noodle/zip.go @@ -0,0 +1 @@ +package noodle diff --git a/requests/auth.go b/requests/auth.go index c42c80a..3846b6e 100644 --- a/requests/auth.go +++ b/requests/auth.go @@ -8,6 +8,8 @@ import ( "github.com/pkg/errors" ) +// TODO: it is already in net/http https://golang.org/pkg/net/http/#Request.BasicAuth + const AuthorizationHeader = "Authorization" func GenerateBasicAuth(username string, password string) string {