Skip to content
This repository has been archived by the owner on Aug 14, 2020. It is now read-only.

Commit

Permalink
discovery: add http and https port parameters
Browse files Browse the repository at this point in the history
Currently the ACI spec only supports discovery on ports 443 and 80, this
does not allow using a discovery server in any other ports.

Fix the problem by adding support for arbitrary HTTP and HTTPS ports
when querying a discovery server.
  • Loading branch information
iaguis committed Feb 11, 2015
1 parent ab28d47 commit 5be30f2
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 22 deletions.
13 changes: 11 additions & 2 deletions actool/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@ var (
Name: "discover",
Description: "Discover the download URLs for an app",
Summary: "Discover the download URLs for one or more app container images",
Usage: "APP...",
Usage: "[--http-port PORT] [--https-port PORT] [--insecure] APP...",
Run: runDiscover,
}
flagHttpPort uint
flagHttpsPort uint
)

func init() {
cmdDiscover.Flags.BoolVar(&transportFlags.Insecure, "insecure", false,
"Allow insecure non-TLS downloads over http")
cmdDiscover.Flags.UintVar(&flagHttpPort, "http-port", 0,
"Port to connect when performing discovery using HTTP. If unset or set to 0, defaults to 80. Sets insecure.")
cmdDiscover.Flags.UintVar(&flagHttpsPort, "https-port", 0,
"Port to connect when performing discovery HTTPS. If unset or set to 0, defaults to 443.")
}

func runDiscover(args []string) (exit int) {
Expand All @@ -40,7 +46,10 @@ func runDiscover(args []string) (exit int) {
stderr("%s: %s", name, err)
return 1
}
eps, attempts, err := discovery.DiscoverEndpoints(*app, transportFlags.Insecure)
if flagHttpPort != 0 {
transportFlags.Insecure = true
}
eps, attempts, err := discovery.DiscoverEndpoints(*app, flagHttpPort, flagHttpsPort, transportFlags.Insecure)
if err != nil {
stderr("error fetching %s: %s", name, err)
return 1
Expand Down
34 changes: 20 additions & 14 deletions discovery/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@ func createTemplateVars(app App) []string {
return tplVars
}

func doDiscover(pre string, app App, insecure bool) (*Endpoints, error) {
func doDiscover(pre string, httpPort uint, httpsPort uint, app App, insecure bool) (*Endpoints, error) {
if app.Labels["version"] == "" {
app.Labels["version"] = defaultVersion
}

_, body, err := httpsOrHTTP(pre, insecure)
_, body, err := httpsOrHTTP(pre, httpPort, httpsPort, insecure)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -154,9 +154,11 @@ func doDiscover(pre string, app App, insecure bool) (*Endpoints, error) {
}

// DiscoverWalk will make HTTPS requests to find discovery meta tags and
// optionally will use HTTP if insecure is set. Based on the response of the
// discoverFn it will continue to recurse up the tree.
func DiscoverWalk(app App, insecure bool, discoverFn DiscoverWalkFunc) (err error) {
// optionally will use HTTP if insecure is set. httpPort and httpsPort are the
// ports to be used for the corresponding requests, if set to 0, the default
// ports will be tried. Based on the response of the discoverFn it will continue
// to recurse up the tree.
func DiscoverWalk(app App, httpPort uint, httpsPort uint, insecure bool, discoverFn DiscoverWalkFunc) (err error) {
var (
eps *Endpoints
)
Expand All @@ -166,7 +168,7 @@ func DiscoverWalk(app App, insecure bool, discoverFn DiscoverWalkFunc) (err erro
end := len(parts) - i
pre := strings.Join(parts[:end], "/")

eps, err = doDiscover(pre, app, insecure)
eps, err = doDiscover(pre, httpPort, httpsPort, app, insecure)
derr := discoverFn(pre, eps, err)
if derr != nil {
return err
Expand Down Expand Up @@ -201,9 +203,11 @@ func walker(out *Endpoints, attempts *[]FailedAttempt, testFn DiscoverWalkFunc)
}

// DiscoverEndpoints will make HTTPS requests to find the ac-discovery meta
// tags and optionally will use HTTP if insecure is set. It will not give up
// until it has exhausted the path or found an image discovery.
func DiscoverEndpoints(app App, insecure bool) (out *Endpoints, attempts []FailedAttempt, err error) {
// tags and optionally will use HTTP if insecure is set. httpPort and httpsPort
// are the ports to be used for the corresponding requests, if set to 0, the
// default ports will be tried. It will not give up until it has exhausted the
// path or found an image discovery.
func DiscoverEndpoints(app App, httpPort uint, httpsPort uint, insecure bool) (out *Endpoints, attempts []FailedAttempt, err error) {
out = &Endpoints{}
testFn := func(pre string, eps *Endpoints, err error) error {
if len(out.ACIEndpoints) != 0 {
Expand All @@ -212,7 +216,7 @@ func DiscoverEndpoints(app App, insecure bool) (out *Endpoints, attempts []Faile
return nil
}

err = DiscoverWalk(app, insecure, walker(out, &attempts, testFn))
err = DiscoverWalk(app, httpPort, httpsPort, insecure, walker(out, &attempts, testFn))
if err != nil && err != errEnough {
return nil, attempts, err
}
Expand All @@ -221,9 +225,11 @@ func DiscoverEndpoints(app App, insecure bool) (out *Endpoints, attempts []Faile
}

// DiscoverPublicKey will make HTTPS requests to find the ac-public-keys meta
// tags and optionally will use HTTP if insecure is set. It will not give up
// until it has exhausted the path or found an public key.
func DiscoverPublicKeys(app App, insecure bool) (out *Endpoints, attempts []FailedAttempt, err error) {
// tags and optionally will use HTTP if insecure is set. httpPort and httpsPort
// are the ports to be used for the corresponding requests, if set to 0, the
// default ports will be tried. It will not give up until it has exhausted the
// path or found an public key.
func DiscoverPublicKeys(app App, httpPort uint, httpsPort uint, insecure bool) (out *Endpoints, attempts []FailedAttempt, err error) {
out = &Endpoints{}
testFn := func(pre string, eps *Endpoints, err error) error {
if len(out.Keys) != 0 {
Expand All @@ -232,7 +238,7 @@ func DiscoverPublicKeys(app App, insecure bool) (out *Endpoints, attempts []Fail
return nil
}

err = DiscoverWalk(app, insecure, walker(out, &attempts, testFn))
err = DiscoverWalk(app, httpPort, httpsPort, insecure, walker(out, &attempts, testFn))
if err != nil && err != errEnough {
return nil, attempts, err
}
Expand Down
2 changes: 1 addition & 1 deletion discovery/discovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func TestDiscoverEndpoints(t *testing.T) {

for i, tt := range tests {
httpGet = tt.get
de, _, err := DiscoverEndpoints(tt.app, true)
de, _, err := DiscoverEndpoints(tt.app, 0, 0, true)
if err != nil && !tt.expectDiscoverySuccess {
continue
}
Expand Down
12 changes: 8 additions & 4 deletions discovery/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net"
"net/http"
"net/url"
"strconv"
"time"
)

Expand All @@ -31,13 +32,16 @@ func init() {
httpGet = c.Get
}

func httpsOrHTTP(name string, insecure bool) (urlStr string, body io.ReadCloser, err error) {
fetch := func(scheme string) (urlStr string, res *http.Response, err error) {
func httpsOrHTTP(name string, httpPort uint, httpsPort uint, insecure bool) (urlStr string, body io.ReadCloser, err error) {
fetch := func(scheme string, port uint) (urlStr string, res *http.Response, err error) {
u, err := url.Parse(scheme + "://" + name)
if err != nil {
return "", nil, err
}
u.RawQuery = "ac-discovery=1"
if port != 0 {
u.Host += ":" + strconv.FormatUint(uint64(port), 10)
}
urlStr = u.String()
res, err = httpGet(urlStr)
return
Expand All @@ -47,11 +51,11 @@ func httpsOrHTTP(name string, insecure bool) (urlStr string, body io.ReadCloser,
res.Body.Close()
}
}
urlStr, res, err := fetch("https")
urlStr, res, err := fetch("https", httpsPort)
if err != nil || res.StatusCode != http.StatusOK {
if insecure {
closeBody(res)
urlStr, res, err = fetch("http")
urlStr, res, err = fetch("http", httpPort)
}
}

Expand Down
34 changes: 33 additions & 1 deletion discovery/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,57 +59,89 @@ func TestHttpsOrHTTP(t *testing.T) {
tests := []struct {
name string
insecure bool
httpPort uint
httpsPort uint
get httpgetter
expectUrlStr string
expectSuccess bool
}{
{
"good-server",
false,
0,
0,
fakeHttpOrHttpsGet("myapp.html", true, true, 0),
"https://good-server?ac-discovery=1",
true,
},
{
"file-not-found",
false,
0,
0,
fakeHttpOrHttpsGet("myapp.html", false, false, 404),
"",
false,
},
{
"completely-broken-server",
false,
0,
0,
fakeHttpOrHttpsGet("myapp.html", false, false, 0),
"",
false,
},
{
"file-only-on-http",
false, // do not accept fallback on http
0,
0,
fakeHttpOrHttpsGet("myapp.html", true, false, 404),
"",
false,
},
{
"file-only-on-http",
true, // accept fallback on http
0,
0,
fakeHttpOrHttpsGet("myapp.html", true, false, 404),
"http://file-only-on-http?ac-discovery=1",
true,
},
{
"https-server-is-down",
true, // accept fallback on http
0,
0,
fakeHttpOrHttpsGet("myapp.html", true, false, 0),
"http://https-server-is-down?ac-discovery=1",
true,
},
{
"custom-http-port-file-on-http",
true, // accept fallback on http
8080,
0,
fakeHttpOrHttpsGet("myapp.html", true, false, 404),
"http://custom-http-port-file-on-http:8080?ac-discovery=1",
true,
},
{
"custom-https-port-file-on-https",
true, // accept fallback on http
8080,
8090,
fakeHttpOrHttpsGet("myapp.html", true, true, 0),
"https://custom-https-port-file-on-https:8090?ac-discovery=1",
true,
},
}

for i, tt := range tests {
httpGet = tt.get
urlStr, body, err := httpsOrHTTP(tt.name, tt.insecure)
urlStr, body, err := httpsOrHTTP(tt.name, tt.httpPort, tt.httpsPort, tt.insecure)
if tt.expectSuccess {
if err != nil {
t.Fatalf("#%d httpsOrHTTP failed: %v", i, err)
Expand Down

0 comments on commit 5be30f2

Please sign in to comment.