1// Copyright 2011 Google Inc. All rights reserved. 2// Use of this source code is governed by the Apache 2.0 3// license that can be found in the LICENSE file. 4 5// +build !appengine 6 7package internal 8 9import ( 10 "log" 11 "net/http" 12 "os" 13 "strings" 14 15 netcontext "golang.org/x/net/context" 16) 17 18// These functions are implementations of the wrapper functions 19// in ../appengine/identity.go. See that file for commentary. 20 21const ( 22 hDefaultVersionHostname = "X-AppEngine-Default-Version-Hostname" 23 hRequestLogId = "X-AppEngine-Request-Log-Id" 24 hDatacenter = "X-AppEngine-Datacenter" 25) 26 27func ctxHeaders(ctx netcontext.Context) http.Header { 28 c := fromContext(ctx) 29 if c == nil { 30 return nil 31 } 32 return c.Request().Header 33} 34 35func DefaultVersionHostname(ctx netcontext.Context) string { 36 return ctxHeaders(ctx).Get(hDefaultVersionHostname) 37} 38 39func RequestID(ctx netcontext.Context) string { 40 return ctxHeaders(ctx).Get(hRequestLogId) 41} 42 43func Datacenter(ctx netcontext.Context) string { 44 if dc := ctxHeaders(ctx).Get(hDatacenter); dc != "" { 45 return dc 46 } 47 // If the header isn't set, read zone from the metadata service. 48 // It has the format projects/[NUMERIC_PROJECT_ID]/zones/[ZONE] 49 zone, err := getMetadata("instance/zone") 50 if err != nil { 51 log.Printf("Datacenter: %v", err) 52 return "" 53 } 54 parts := strings.Split(string(zone), "/") 55 if len(parts) == 0 { 56 return "" 57 } 58 return parts[len(parts)-1] 59} 60 61func ServerSoftware() string { 62 // TODO(dsymonds): Remove fallback when we've verified this. 63 if s := os.Getenv("SERVER_SOFTWARE"); s != "" { 64 return s 65 } 66 if s := os.Getenv("GAE_ENV"); s != "" { 67 return s 68 } 69 return "Google App Engine/1.x.x" 70} 71 72// TODO(dsymonds): Remove the metadata fetches. 73 74func ModuleName(_ netcontext.Context) string { 75 if s := os.Getenv("GAE_MODULE_NAME"); s != "" { 76 return s 77 } 78 if s := os.Getenv("GAE_SERVICE"); s != "" { 79 return s 80 } 81 return string(mustGetMetadata("instance/attributes/gae_backend_name")) 82} 83 84func VersionID(_ netcontext.Context) string { 85 if s1, s2 := os.Getenv("GAE_MODULE_VERSION"), os.Getenv("GAE_MINOR_VERSION"); s1 != "" && s2 != "" { 86 return s1 + "." + s2 87 } 88 if s1, s2 := os.Getenv("GAE_VERSION"), os.Getenv("GAE_DEPLOYMENT_ID"); s1 != "" && s2 != "" { 89 return s1 + "." + s2 90 } 91 return string(mustGetMetadata("instance/attributes/gae_backend_version")) + "." + string(mustGetMetadata("instance/attributes/gae_backend_minor_version")) 92} 93 94func InstanceID() string { 95 if s := os.Getenv("GAE_MODULE_INSTANCE"); s != "" { 96 return s 97 } 98 if s := os.Getenv("GAE_INSTANCE"); s != "" { 99 return s 100 } 101 return string(mustGetMetadata("instance/attributes/gae_backend_instance")) 102} 103 104func partitionlessAppID() string { 105 // gae_project has everything except the partition prefix. 106 if appID := os.Getenv("GAE_LONG_APP_ID"); appID != "" { 107 return appID 108 } 109 if project := os.Getenv("GOOGLE_CLOUD_PROJECT"); project != "" { 110 return project 111 } 112 return string(mustGetMetadata("instance/attributes/gae_project")) 113} 114 115func fullyQualifiedAppID(_ netcontext.Context) string { 116 if s := os.Getenv("GAE_APPLICATION"); s != "" { 117 return s 118 } 119 appID := partitionlessAppID() 120 121 part := os.Getenv("GAE_PARTITION") 122 if part == "" { 123 part = string(mustGetMetadata("instance/attributes/gae_partition")) 124 } 125 126 if part != "" { 127 appID = part + "~" + appID 128 } 129 return appID 130} 131 132func IsDevAppServer() bool { 133 return os.Getenv("RUN_WITH_DEVAPPSERVER") != "" 134} 135