Skip to content

Commit

Permalink
Add CORS support
Browse files Browse the repository at this point in the history
  • Loading branch information
mat committed Jul 25, 2020
1 parent 62226c1 commit da6f747
Show file tree
Hide file tree
Showing 13 changed files with 732 additions and 3 deletions.
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ COPY --from=builder /go/src/github.com/mat/besticon/bin/linux_amd64/iconserver /

ENV ADDRESS=''
ENV CACHE_SIZE_MB=32
ENV CORS_ENABLED=false
ENV CORS_ALLOWED_HEADERS=''
ENV CORS_ALLOWED_METHODS=''
ENV CORS_ALLOWED_ORIGINS=''
ENV CORS_ALLOW_CREDENTIALS=''
ENV CORS_DEBUG=''
ENV HOST_ONLY_DOMAINS=*
ENV HTTP_CLIENT_TIMEOUT=5s
ENV HTTP_MAX_AGE_DURATION=720h
Expand Down
8 changes: 8 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions Readme.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -114,19 +114,29 @@ To use a different port use
To listen on a different address (say localhost) use

$ ADDRESS=127.0.0.1 iconserver

To enable CORS headers you need to set `CORS_ENABLED=true`. Optionally, you can set [additional environment variables](https://github.com/mat/besticon#configuration) which will be passed as options to the [rs/cors middleware](https://github.com/rs/cors#parameters).

$ CORS_ENABLED=true iconserver

Now when you open <http://localhost:8080/icons?url=instagram.com> you should see something like
![Screenshot of The Favicon Finder](https://github.com/mat/besticon/raw/master/the-icon-finder.png)


## Configuration

There is not a lot to configure but these environment variables exist
There is not a lot to configure, but these environment variables exist

| Variable | Description | Default Value |
|-------------------------|--------------------------------------------------------------------------------------------|----------------------------|
| `ADDRESS` | HTTP server listen address | 0.0.0.0 |
| `CACHE_SIZE_MB` | Size for the [groupcache](http://github.com/golang/groupcache), set to 0 to disable | 32 |
| `CORS_ENABLED` | Enables the [rs/cors](https://github.com/rs/cors) middleware | false |
| `CORS_ALLOWED_HEADERS` | Comma-separated, passed to middleware | |
| `CORS_ALLOWED_METHODS` | Comma-separated, passed to middleware | |
| `CORS_ALLOWED_ORIGINS` | Comma-separated, passed to middleware | |
| `CORS_ALLOW_CREDENTIALS` | Boolean, passed to middleware | |
| `CORS_DEBUG` | Boolean, passed to middleware | |
| `HOST_ONLY_DOMAINS` | | * |
| `HTTP_CLIENT_TIMEOUT` | Timeout used for HTTP requests. Supports units like ms, s, m. | 5s |
| `HTTP_MAX_AGE_DURATION` | Cache duration for all dynamically generated HTTP responses. Supports units like ms, s, m. | 720h *(30 days)* |
Expand All @@ -145,7 +155,8 @@ Package | Description | License
<http://github.com/golang/freetype> | | [FreeType License](https://github.com/golang/freetype/blob/master/LICENSE)
<http://golang.org/x/image> | supplementary image libraries | [BSD style](https://github.com/golang/image/blob/master/LICENSE) |
<http://golang.org/x/net> | | [BSD style](https://github.com/golang/net/blob/master/LICENSE)|
<http://golang.org/x/text> | | [BSD style](https://github.com/golang/text/blob/master/LICENSE)|
<http://golang.org/x/text> | | [BSD style](https://github.com/golang/text/blob/master/LICENSE)|
<https://github.com/rs/cors> | CORS Support | [MIT License](https://github.com/rs/cors/blob/master/LICENSE)
| [Noto Sans font](https://www.google.com/get/noto/) used for the generated icons | | [SIL Open Font License 1.1](http://scripts.sil.org/OFL) |
| [The icon](http://sixrevisions.com/freebies/icons/free-icons-1000/) | | [License](http://sixrevisions.com/freebies/icons/free-icons-1000/) |

Expand Down
24 changes: 24 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,30 @@
"HOST_ONLY_DOMAINS": {
"value": "*"
},
"CORS_ENABLED": {
"value": "false",
"description": "Enables the cors middleware, defaults to false"
},
"CORS_ALLOWED_HEADERS": {
"value": " ",
"description": "Comma-separated, passed to middleware"
},
"CORS_ALLOWED_METHODS": {
"value": " ",
"description": "Comma-separated, passed to middleware"
},
"CORS_ALLOWED_ORIGINS": {
"value": " ",
"description": "Comma-separated, passed to middleware"
},
"CORS_ALLOW_CREDENTIALS": {
"value": " ",
"description": "Boolean, passed to middleware"
},
"CORS_DEBUG": {
"value": " ",
"description": "Boolean, passed to middleware"
},
"HTTP_CLIENT_TIMEOUT": {
"value": "5s",
"description": "Timeout used for HTTP requests. Supports units like ms, s, m, defaults to 5s"
Expand Down
Binary file modified besticon.paw
Binary file not shown.
36 changes: 35 additions & 1 deletion besticon/iconserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/mat/besticon/lettericon"

"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/rs/cors"

// Enable runtime profiling at /debug/pprof
_ "net/http/pprof"
Expand Down Expand Up @@ -261,12 +262,33 @@ func startServer(port string, address string) {

addr := address + ":" + port
logger.Print("Starting server on ", addr, "...")
e := http.ListenAndServe(addr, newLoggingMux())
e := http.ListenAndServe(addr, httpHandler())
if e != nil {
logger.Fatalf("cannot start server: %s\n", e)
}
}

func httpHandler() http.Handler {
corsEnabled := getTrueFromEnv("CORS_ENABLED")
if corsEnabled {
logger.Print("Enabling CORS middleware")
return corsHandler(newLoggingMux())
} else {
return newLoggingMux()
}
}

func corsHandler(mux http.HandlerFunc) http.Handler {
corsOpts := cors.Options{
AllowedOrigins: stringSliceFromEnv("CORS_ALLOWED_ORIGINS"),
AllowedMethods: stringSliceFromEnv("CORS_ALLOWED_METHODS"),
AllowedHeaders: stringSliceFromEnv("CORS_ALLOWED_HEADERS"),
AllowCredentials: getTrueFromEnv("CORS_ALLOW_CREDENTIALS"),
Debug: getTrueFromEnv("CORS_DEBUG"),
}
return cors.New(corsOpts).Handler(mux)
}

const (
cacheControl = "Cache-Control"
oneYear = 365 * 24 * 3600
Expand Down Expand Up @@ -390,6 +412,18 @@ func init() {
hostOnlyDomains = strings.Split(os.Getenv("HOST_ONLY_DOMAINS"), ",")
}

func getTrueFromEnv(s string) bool {
return getenvOrFallback(s, "") == "true"
}

func stringSliceFromEnv(key string) []string {
value := os.Getenv(key)
if value == "" {
return nil
}
return strings.Split(value, ",")
}

func getenvOrFallback(key string, fallbackValue string) string {
value := os.Getenv(key)
if len(strings.TrimSpace(value)) != 0 {
Expand Down
6 changes: 6 additions & 0 deletions docker_run.env
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@

ADDRESS=0.0.0.0
CACHE_SIZE_MB=32
CORS_ENABLED=false
CORS_ALLOWED_HEADERS=
CORS_ALLOWED_METHODS=
CORS_ALLOWED_ORIGINS=
CORS_ALLOW_CREDENTIALS=
CORS_DEBUG=true
HOST_ONLY_DOMAINS=*
HTTP_CLIENT_TIMEOUT=5s
HTTP_MAX_AGE_DURATION=720h
Expand Down
9 changes: 9 additions & 0 deletions vendor/github.com/rs/cors/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions vendor/github.com/rs/cors/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

115 changes: 115 additions & 0 deletions vendor/github.com/rs/cors/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit da6f747

Please sign in to comment.