mirror of https://github.com/perkeep/perkeep.git
pkg/client: fix method to find a server in the config
http://camlistore.org/issue/325 Change-Id: I4aa6d5103848b73ed169ab7d7de3a60a33723b79
This commit is contained in:
parent
8a970d23f0
commit
3f13d1a043
|
@ -126,7 +126,7 @@ const maxParallelHTTP = 5
|
|||
// The provided server is either "host:port" (assumed http, not https) or a URL prefix, with or without a path, or a server alias from the client configuration file. A server alias should not be confused with a hostname, therefore it cannot contain any colon or period.
|
||||
// Errors are not returned until subsequent operations.
|
||||
func New(server string) *Client {
|
||||
if !isHostname(server) {
|
||||
if !isURLOrHostPort(server) {
|
||||
configOnce.Do(parseConfig)
|
||||
serverConf, ok := config.Servers[server]
|
||||
if !ok {
|
||||
|
@ -560,10 +560,11 @@ func (c *Client) blobPrefix() (string, error) {
|
|||
return pfx, nil
|
||||
}
|
||||
|
||||
// discoRoot returns the user defined server for this client. It prepends "https://" if no scheme was specified.
|
||||
func (c *Client) discoRoot() string {
|
||||
s := c.server
|
||||
if !strings.HasPrefix(s, "http") {
|
||||
s = "http://" + s
|
||||
s = "https://" + s
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ func parseConfig() {
|
|||
for alias, vei := range servers {
|
||||
// An alias should never be confused with a host name,
|
||||
// so we forbid anything looking like one.
|
||||
if isHostname(alias) {
|
||||
if isURLOrHostPort(alias) {
|
||||
log.Fatalf("Server alias %q looks like a hostname; \".\" or \";\" are not allowed.", alias)
|
||||
}
|
||||
serverMap, ok := vei.(map[string]interface{})
|
||||
|
@ -125,8 +125,8 @@ func parseConfig() {
|
|||
}
|
||||
}
|
||||
|
||||
// isHostname return true if s looks like a host name, i.e it has at least a scheme or contains a period or a colon.
|
||||
func isHostname(s string) bool {
|
||||
// isURLOrHostPort returns true if s looks like a URL, or a hostname, i.e it starts with a scheme and/or it contains a period or a colon.
|
||||
func isURLOrHostPort(s string) bool {
|
||||
return strings.HasPrefix(s, "http://") ||
|
||||
strings.HasPrefix(s, "https://") ||
|
||||
strings.Contains(s, ".") || strings.Contains(s, ":")
|
||||
|
@ -213,8 +213,10 @@ func serverKeyId() string {
|
|||
return keyId
|
||||
}
|
||||
|
||||
// cleanServer returns the canonical URL of the provided server, which must be a URL, IP, host (with dot), or host/ip:port.
|
||||
// The returned canonical URL will have trailing slashes removed and be prepended with "https://" if no scheme is provided.
|
||||
func cleanServer(server string) string {
|
||||
if !isHostname(server) {
|
||||
if !isURLOrHostPort(server) {
|
||||
log.Fatalf("server %q does not look like a server address and could be confused with a server alias. It should look like [http[s]://]foo[.com][:port] with at least one of the optional parts.", server)
|
||||
}
|
||||
// Remove trailing slash if provided.
|
||||
|
@ -235,7 +237,7 @@ func serverOrDie() string {
|
|||
return cleanServer(s)
|
||||
}
|
||||
if flagServer != "" {
|
||||
if !isHostname(flagServer) {
|
||||
if !isURLOrHostPort(flagServer) {
|
||||
configOnce.Do(parseConfig)
|
||||
serverConf, ok := config.Servers[flagServer]
|
||||
if ok {
|
||||
|
@ -276,8 +278,7 @@ func (c *Client) useTLS() bool {
|
|||
return strings.HasPrefix(c.server, "https://")
|
||||
}
|
||||
|
||||
// SetupAuth sets the client's authMode from the client
|
||||
// configuration file or from the environment.
|
||||
// SetupAuth sets the client's authMode from the client configuration file or from the environment.
|
||||
func (c *Client) SetupAuth() error {
|
||||
// env var always takes precendence
|
||||
authMode, err := auth.FromEnv()
|
||||
|
@ -299,17 +300,14 @@ func (c *Client) SetupAuth() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// serverAuth returns the auth scheme for server from the config, or the empty string if the server was not found in the config.
|
||||
func serverAuth(server string) string {
|
||||
configOnce.Do(parseConfig)
|
||||
if config == nil {
|
||||
alias := config.Alias(server)
|
||||
if alias == "" {
|
||||
return ""
|
||||
}
|
||||
for _, serverConf := range config.Servers {
|
||||
if serverConf.Server == server {
|
||||
return serverConf.Auth
|
||||
}
|
||||
}
|
||||
return ""
|
||||
return config.Servers[alias].Auth
|
||||
}
|
||||
|
||||
// SetupAuthFromString configures the clients authentication mode from
|
||||
|
@ -420,14 +418,14 @@ func (c *Client) initTrustedCerts() {
|
|||
}
|
||||
}
|
||||
|
||||
// serverTrustedCerts returns the trusted certs for server from the config.
|
||||
func serverTrustedCerts(server string) []string {
|
||||
configOnce.Do(parseConfig)
|
||||
for _, serverConf := range config.Servers {
|
||||
if serverConf.Server == server {
|
||||
return serverConf.TrustedCerts
|
||||
}
|
||||
alias := config.Alias(server)
|
||||
if alias == "" {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
return config.Servers[alias].TrustedCerts
|
||||
}
|
||||
|
||||
func (c *Client) getTrustedCerts() []string {
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
Copyright 2014 The Camlistore Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"camlistore.org/pkg/types/clientconfig"
|
||||
)
|
||||
|
||||
func TestAliasFromConfig(t *testing.T) {
|
||||
servers := map[string]*clientconfig.Server{
|
||||
"foo": {
|
||||
Server: "http://foo.com",
|
||||
},
|
||||
"foobar": {
|
||||
Server: "http://foo.com/bar",
|
||||
},
|
||||
"foobaz": {
|
||||
Server: "http://foo.com/baz",
|
||||
},
|
||||
"foobarlong": {
|
||||
Server: "http://foo.com/bar/long",
|
||||
},
|
||||
}
|
||||
config := &clientconfig.Config{
|
||||
Servers: servers,
|
||||
}
|
||||
urlWant := map[string]string{
|
||||
"http://foo.com/bs": "foo",
|
||||
"http://foo.com": "foo",
|
||||
"http://foo.com/bar/index-mysql": "foobar",
|
||||
"http://foo.com/bar": "foobar",
|
||||
"http://foo.com/baz/index-kv": "foobaz",
|
||||
"http://foo.com/baz": "foobaz",
|
||||
"http://foo.com/bar/long/disco": "foobarlong",
|
||||
"http://foo.com/bar/long": "foobarlong",
|
||||
}
|
||||
for url, want := range urlWant {
|
||||
alias := config.Alias(url)
|
||||
if alias == "" {
|
||||
t.Errorf("url %v matched nothing, wanted %v", url, want)
|
||||
continue
|
||||
}
|
||||
if alias != want {
|
||||
t.Errorf("url %v matched %v, wanted %v", url, alias, want)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,10 @@ limitations under the License.
|
|||
// Package clientconfig provides types related to the client configuration file.
|
||||
package clientconfig
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Config holds the values from the JSON client config file.
|
||||
type Config struct {
|
||||
Servers map[string]*Server `json:"servers"` // maps server alias to server config.
|
||||
|
@ -32,3 +36,18 @@ type Server struct {
|
|||
IsDefault bool `json:"default,omitempty"` // whether this server is the default one.
|
||||
TrustedCerts []string `json:"trustedCerts,omitempty"` // list of trusted certificates fingerprints.
|
||||
}
|
||||
|
||||
// Alias returns the alias of the server from conf that matches server, or the empty string if no match. A match means the server from the config is a prefix of the input server. The longest match prevails.
|
||||
func (conf *Config) Alias(server string) string {
|
||||
longestMatch := ""
|
||||
serverAlias := ""
|
||||
for alias, serverConf := range conf.Servers {
|
||||
if strings.HasPrefix(server, serverConf.Server) {
|
||||
if len(serverConf.Server) > len(longestMatch) {
|
||||
longestMatch = serverConf.Server
|
||||
serverAlias = alias
|
||||
}
|
||||
}
|
||||
}
|
||||
return serverAlias
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue