Skip to content

Commit

Permalink
Added support for http and https links as paths to config files
Browse files Browse the repository at this point in the history
  • Loading branch information
valyala committed Aug 22, 2014
1 parent faa4132 commit fd894b1
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 9 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ flag2 = foobar
# Now flag1="value1", while flag2="foobar"
```

Both -config path and imported ini files can be addressed via http
or https links:

```bash
/path/to/app -config=https://google.com/path/to/config.ini
```

config.ini
```ini
# The following line will import configs from the given http link.
#import "http://google.com/path/to/config.ini"
```

All flags defined in the app can be dumped into stdout with ini-compatible sytax
by passing -dumpflags flag to the app. The following command creates ini-file
Expand Down
64 changes: 55 additions & 9 deletions iniflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"fmt"
"io"
"log"
"net/http"
"net/url"
"os"
"os/signal"
"path"
Expand Down Expand Up @@ -69,9 +71,12 @@ func sighupHandler(ch <-chan os.Signal) {
}

func parseConfigFlags() bool {
var ok bool
configPath := *config
if !strings.HasPrefix(configPath, "./") {
configPath = combinePath(os.Args[0], *config)
if configPath, ok = combinePath(os.Args[0], *config); !ok {
return false
}
}
if configPath == "" {
return true
Expand Down Expand Up @@ -130,9 +135,8 @@ func getArgsFromConfig(configPath string) (args []Arg, ok bool) {
importStack = importStack[:len(importStack)-1]
}()

file, err := os.Open(configPath)
if err != nil {
log.Printf("Cannot open config file at [%s]: [%s]\n", configPath, err)
file := openConfigFile(configPath)
if file == nil {
return nil, false
}
defer file.Close()
Expand All @@ -155,7 +159,9 @@ func getArgsFromConfig(configPath string) (args []Arg, ok bool) {
if !ok {
return nil, false
}
importPath = combinePath(configPath, importPath)
if importPath, ok = combinePath(configPath, importPath); !ok {
return nil, false
}
importArgs, ok := getArgsFromConfig(importPath)
if !ok {
return nil, false
Expand All @@ -182,11 +188,51 @@ func getArgsFromConfig(configPath string) (args []Arg, ok bool) {
return args, true
}

func combinePath(basePath, relPath string) string {
if relPath == "" || relPath[0] == '/' {
return relPath
func openConfigFile(path string) io.ReadCloser {
if isHttp(path) {
resp, err := http.Get(path)
if err != nil {
log.Printf("Cannot load config file at [%s]: [%s]\n", path, err)
return nil
}
if resp.StatusCode != http.StatusOK {
log.Printf("Unexpected http status code when obtaining config file [%s]: %d. Expected %d\n", path, resp.StatusCode, http.StatusOK)
return nil
}
return resp.Body
}

file, err := os.Open(path)
if err != nil {
log.Printf("Cannot open config file at [%s]: [%s]\n", path, err)
return nil
}
return path.Join(path.Dir(basePath), relPath)
return file
}

func combinePath(basePath, relPath string) (string, bool) {
if isHttp(basePath) {
base, err := url.Parse(basePath)
if err != nil {
log.Printf("Error when parsing http base path [%s]: %s\n", basePath, err)
return "", false
}
rel, err := url.Parse(relPath)
if err != nil {
log.Printf("Error when parsing http rel path [%s] for base [%s]: %s\n", relPath, basePath, err)
return "", false
}
return base.ResolveReference(rel).String(), true
}

if relPath == "" || relPath[0] == '/' || isHttp(relPath) {
return relPath, true
}
return path.Join(path.Dir(basePath), relPath), true
}

func isHttp(path string) bool {
return strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://")
}

func getMissingFlags() map[string]bool {
Expand Down

0 comments on commit fd894b1

Please sign in to comment.