123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- /*
- *
- * Copyright 2021 Google LLC
- *
- * 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
- *
- * https://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 service is a utility for calling the S2A handshaker service.
- package service
- import (
- "context"
- "net"
- "os"
- "strings"
- "sync"
- "time"
- "google.golang.org/appengine"
- "google.golang.org/appengine/socket"
- grpc "google.golang.org/grpc"
- "google.golang.org/grpc/grpclog"
- )
- // An environment variable, if true, opportunistically use AppEngine-specific dialer to call S2A.
- const enableAppEngineDialerEnv = "S2A_ENABLE_APP_ENGINE_DIALER"
- var (
- // appEngineDialerHook is an AppEngine-specific dial option that is set
- // during init time. If nil, then the application is not running on Google
- // AppEngine.
- appEngineDialerHook func(context.Context) grpc.DialOption
- // mu guards hsConnMap and hsDialer.
- mu sync.Mutex
- // hsConnMap represents a mapping from an S2A handshaker service address
- // to a corresponding connection to an S2A handshaker service instance.
- hsConnMap = make(map[string]*grpc.ClientConn)
- // hsDialer will be reassigned in tests.
- hsDialer = grpc.Dial
- )
- func init() {
- if !appengine.IsAppEngine() && !appengine.IsDevAppServer() {
- return
- }
- appEngineDialerHook = func(ctx context.Context) grpc.DialOption {
- return grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
- return socket.DialTimeout(ctx, "tcp", addr, timeout)
- })
- }
- }
- // Dial dials the S2A handshaker service. If a connection has already been
- // established, this function returns it. Otherwise, a new connection is
- // created.
- func Dial(handshakerServiceAddress string) (*grpc.ClientConn, error) {
- mu.Lock()
- defer mu.Unlock()
- hsConn, ok := hsConnMap[handshakerServiceAddress]
- if !ok {
- // Create a new connection to the S2A handshaker service. Note that
- // this connection stays open until the application is closed.
- grpcOpts := []grpc.DialOption{
- grpc.WithInsecure(),
- }
- if enableAppEngineDialer() && appEngineDialerHook != nil {
- if grpclog.V(1) {
- grpclog.Info("Using AppEngine-specific dialer to talk to S2A.")
- }
- grpcOpts = append(grpcOpts, appEngineDialerHook(context.Background()))
- }
- var err error
- hsConn, err = hsDialer(handshakerServiceAddress, grpcOpts...)
- if err != nil {
- return nil, err
- }
- hsConnMap[handshakerServiceAddress] = hsConn
- }
- return hsConn, nil
- }
- func enableAppEngineDialer() bool {
- if strings.ToLower(os.Getenv(enableAppEngineDialerEnv)) == "true" {
- return true
- }
- return false
- }
|