Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: impl/prod/context.go

Issue 1557223002: Make UseRemote work for dev_appserver too. (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: Add support for creating remote_api connections FROM appengine Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package prod 5 package prod
6 6
7 import ( 7 import (
8 "fmt"
8 "net/http" 9 "net/http"
10 "net/http/cookiejar"
11 "net/url"
12 "strings"
9 13
10 "github.com/luci/gae/service/info" 14 "github.com/luci/gae/service/info"
15 "github.com/luci/gae/service/urlfetch"
11 "golang.org/x/net/context" 16 "golang.org/x/net/context"
12 gOAuth "golang.org/x/oauth2/google" 17 gOAuth "golang.org/x/oauth2/google"
13 "google.golang.org/appengine" 18 "google.golang.org/appengine"
14 "google.golang.org/appengine/remote_api" 19 "google.golang.org/appengine/remote_api"
15 ) 20 )
16 21
17 type key int 22 type key int
18 23
19 var ( 24 var (
20 prodContextKey key 25 prodContextKey key
21 prodContextNoTxnKey key = 1 26 prodContextNoTxnKey key = 1
22 probeCacheKey key = 2 27 probeCacheKey key = 2
23 ) 28 )
24 29
25 // AEContext retrieves the raw "google.golang.org/appengine" compatible Context. 30 // AEContext retrieves the raw "google.golang.org/appengine" compatible Context.
26 // 31 //
27 // It also transfers deadline of `c` to AE context, since deadline is used for 32 // It also transfers deadline of `c` to AE context, since deadline is used for
28 // RPCs. Doesn't transfer cancelation ability though (since it's ignored by GAE 33 // RPCs. Doesn't transfer cancelation ability though (since it's ignored by GAE
29 // anyway). 34 // anyway).
30 func AEContext(c context.Context) context.Context { 35 func AEContext(c context.Context) context.Context {
31 aeCtx, _ := c.Value(prodContextKey).(context.Context) 36 aeCtx, _ := c.Value(prodContextKey).(context.Context)
37 if aeCtx == nil {
38 return nil
39 }
32 if deadline, ok := c.Deadline(); ok { 40 if deadline, ok := c.Deadline(); ok {
33 aeCtx, _ = context.WithDeadline(aeCtx, deadline) 41 aeCtx, _ = context.WithDeadline(aeCtx, deadline)
34 } 42 }
35 return aeCtx 43 return aeCtx
36 } 44 }
37 45
38 // AEContextNoTxn retrieves the raw "google.golang.org/appengine" compatible 46 // AEContextNoTxn retrieves the raw "google.golang.org/appengine" compatible
39 // Context that's not part of a transaction. 47 // Context that's not part of a transaction.
40 func AEContextNoTxn(c context.Context) context.Context { 48 func AEContextNoTxn(c context.Context) context.Context {
41 aeCtx, _ := c.Value(prodContextNoTxnKey).(context.Context) 49 aeCtx, _ := c.Value(prodContextNoTxnKey).(context.Context)
50 if aeCtx == nil {
51 return nil
52 }
42 aeCtx, err := appengine.Namespace(aeCtx, info.Get(c).GetNamespace()) 53 aeCtx, err := appengine.Namespace(aeCtx, info.Get(c).GetNamespace())
43 if err != nil { 54 if err != nil {
44 panic(err) 55 panic(err)
45 } 56 }
46 if deadline, ok := c.Deadline(); ok { 57 if deadline, ok := c.Deadline(); ok {
47 aeCtx, _ = context.WithDeadline(aeCtx, deadline) 58 aeCtx, _ = context.WithDeadline(aeCtx, deadline)
48 } 59 }
49 return aeCtx 60 return aeCtx
50 } 61 }
51 62
(...skipping 22 matching lines...) Expand all
74 func Use(c context.Context, r *http.Request) context.Context { 85 func Use(c context.Context, r *http.Request) context.Context {
75 return setupAECtx(c, appengine.NewContext(r)) 86 return setupAECtx(c, appengine.NewContext(r))
76 } 87 }
77 88
78 // UseRemote is the same as Use, except that it lets you attach a context to 89 // UseRemote is the same as Use, except that it lets you attach a context to
79 // a remote host using the Remote API feature. See the docs for the 90 // a remote host using the Remote API feature. See the docs for the
80 // prerequisites. 91 // prerequisites.
81 // 92 //
82 // docs: https://cloud.google.com/appengine/docs/go/tools/remoteapi 93 // docs: https://cloud.google.com/appengine/docs/go/tools/remoteapi
83 // 94 //
84 // If client is nil, this will use a default Google OAuth2 client. Otherwise the 95 // inOutCtx will be replaced with the new, derived context, if err is nil,
85 // client must be configured to have the following OAuth2 scopes: 96 // otherwise it's unchanged and continues to be safe-to-use.
86 //» » "https://www.googleapis.com/auth/appengine.apis" 97 //
87 //» » "https://www.googleapis.com/auth/userinfo.email" 98 // If client is nil, this will use create a new client, and will try to be
88 //» » "https://www.googleapis.com/auth/cloud.platform" 99 // clever about it:
89 func UseRemote(c context.Context, host string, client *http.Client) (context.Con text, error) { 100 // * If you're creating a remote context FROM AppEngine, this will use
90 » err := error(nil) 101 // urlfetch.Transport. This can be used to allow app-to-app remote_api
102 // control.
103 //
104 // * If host starts with "localhost", this will create a regular http.Client
105 // with a cookiejar, and call the _ah/login API to log in as an admin with
106 // the user "admin@example.com".
107 //
108 // * Otherwise, it will create a Google OAuth2 client with the following scope s:
109 // - "https://www.googleapis.com/auth/appengine.apis"
110 // - "https://www.googleapis.com/auth/userinfo.email"
111 // - "https://www.googleapis.com/auth/cloud.platform"
112 func UseRemote(inOutCtx *context.Context, host string, client *http.Client) (err error) {
91 if client == nil { 113 if client == nil {
92 » » client, err = gOAuth.DefaultClient(context.Background(), 114 » » if strings.HasPrefix(host, "localhost") {
93 » » » "https://www.googleapis.com/auth/appengine.apis", 115 » » » transp := http.DefaultTransport
94 » » » "https://www.googleapis.com/auth/userinfo.email", 116 » » » if aeCtx := AEContextNoTxn(*inOutCtx); aeCtx != nil {
95 » » » "https://www.googleapis.com/auth/cloud.platform", 117 » » » » transp = urlfetch.Get(aeCtx)
96 » » ) 118 » » » }
97 » » if err != nil { 119
98 » » » return nil, err 120 » » » client = &http.Client{Transport: transp}
121 » » » client.Jar, err = cookiejar.New(nil)
122 » » » if err != nil {
123 » » » » return
124 » » » }
125 » » » u := fmt.Sprintf("http://%s/_ah/login?%s", host, url.Val ues{
126 » » » » "email": {"admin@example.com"},
127 » » » » "admin": {"True"},
128 » » » » "action": {"Login"},
129 » » » }.Encode())
130
131 » » » var rsp *http.Response
132 » » » rsp, err = client.Get(u)
133 » » » if err != nil {
134 » » » » return
135 » » » }
136 » » » defer rsp.Body.Close()
137 » » } else {
138 » » » aeCtx := AEContextNoTxn(*inOutCtx)
139 » » » if aeCtx == nil {
140 » » » » aeCtx = context.Background()
141 » » » }
142 » » » client, err = gOAuth.DefaultClient(aeCtx,
143 » » » » "https://www.googleapis.com/auth/appengine.apis" ,
144 » » » » "https://www.googleapis.com/auth/userinfo.email" ,
145 » » » » "https://www.googleapis.com/auth/cloud.platform" ,
146 » » » )
147 » » » if err != nil {
148 » » » » return
149 » » » }
99 } 150 }
100 } 151 }
101 152
102 aeCtx, err := remote_api.NewRemoteContext(host, client) 153 aeCtx, err := remote_api.NewRemoteContext(host, client)
103 if err != nil { 154 if err != nil {
104 » » return nil, err 155 » » return
105 } 156 }
106 » return setupAECtx(c, aeCtx), nil 157 » *inOutCtx = setupAECtx(*inOutCtx, aeCtx)
158 » return nil
107 } 159 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698