61a49bb6 |
package dockerversion
import ( |
d1502afb |
"fmt" |
61a49bb6 |
"runtime"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/pkg/useragent" |
d1502afb |
"golang.org/x/net/context" |
61a49bb6 |
)
|
64981b9f |
// UAStringKey is used as key type for user-agent string in net/context struct
const UAStringKey = "upstream-user-agent"
|
61a49bb6 |
// DockerUserAgent is the User-Agent the Docker client uses to identify itself. |
d1502afb |
// In accordance with RFC 7231 (5.5.3) is of the form:
// [docker client's UA] UpstreamClient([upstream client's UA]) |
c44e7a3e |
func DockerUserAgent(ctx context.Context) string { |
61a49bb6 |
httpVersion := make([]useragent.VersionInfo, 0, 6)
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "docker", Version: Version})
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "go", Version: runtime.Version()})
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "git-commit", Version: GitCommit})
if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "kernel", Version: kernelVersion.String()})
}
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "os", Version: runtime.GOOS})
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "arch", Version: runtime.GOARCH})
|
d1502afb |
dockerUA := useragent.AppendVersions("", httpVersion...) |
c44e7a3e |
upstreamUA := getUserAgentFromContext(ctx) |
d1502afb |
if len(upstreamUA) > 0 {
ret := insertUpstreamUserAgent(upstreamUA, dockerUA)
return ret
}
return dockerUA
}
|
c44e7a3e |
// getUserAgentFromContext returns the previously saved user-agent context stored in ctx, if one exists
func getUserAgentFromContext(ctx context.Context) string { |
d1502afb |
var upstreamUA string
if ctx != nil { |
64981b9f |
var ki interface{} = ctx.Value(UAStringKey) |
d1502afb |
if ki != nil { |
64981b9f |
upstreamUA = ctx.Value(UAStringKey).(string) |
d1502afb |
}
}
return upstreamUA
}
// escapeStr returns s with every rune in charsToEscape escaped by a backslash
func escapeStr(s string, charsToEscape string) string {
var ret string
for _, currRune := range s {
appended := false |
39bcaee4 |
for _, escapableRune := range charsToEscape {
if currRune == escapableRune { |
c44e7a3e |
ret += `\` + string(currRune) |
d1502afb |
appended = true
break
}
}
if !appended {
ret += string(currRune)
}
}
return ret
}
// insertUpstreamUserAgent adds the upstream client useragent to create a user-agent
// string of the form:
// $dockerUA UpstreamClient($upstreamUA)
func insertUpstreamUserAgent(upstreamUA string, dockerUA string) string { |
c44e7a3e |
charsToEscape := `();\` |
d1502afb |
upstreamUAEscaped := escapeStr(upstreamUA, charsToEscape)
return fmt.Sprintf("%s UpstreamClient(%s)", dockerUA, upstreamUAEscaped) |
61a49bb6 |
} |