github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/google.golang.org/appengine/internal/api_classic.go (about)

     1  // Copyright 2015 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  
     7  package internal
     8  
     9  import (
    10  	"errors"
    11  	"net/http"
    12  	"time"
    13  
    14  	"appengine"
    15  	"appengine_internal"
    16  	basepb "appengine_internal/base"
    17  
    18  	"github.com/golang/protobuf/proto"
    19  	netcontext "golang.org/x/net/context"
    20  )
    21  
    22  var contextKey = "holds an appengine.Context"
    23  
    24  func fromContext(ctx netcontext.Context) appengine.Context {
    25  	c, _ := ctx.Value(&contextKey).(appengine.Context)
    26  	return c
    27  }
    28  
    29  // This is only for classic App Engine adapters.
    30  func ClassicContextFromContext(ctx netcontext.Context) appengine.Context {
    31  	return fromContext(ctx)
    32  }
    33  
    34  func withContext(parent netcontext.Context, c appengine.Context) netcontext.Context {
    35  	ctx := netcontext.WithValue(parent, &contextKey, c)
    36  
    37  	s := &basepb.StringProto{}
    38  	c.Call("__go__", "GetNamespace", &basepb.VoidProto{}, s, nil)
    39  	if ns := s.GetValue(); ns != "" {
    40  		ctx = NamespacedContext(ctx, ns)
    41  	}
    42  
    43  	return ctx
    44  }
    45  
    46  func IncomingHeaders(ctx netcontext.Context) http.Header {
    47  	if c := fromContext(ctx); c != nil {
    48  		if req, ok := c.Request().(*http.Request); ok {
    49  			return req.Header
    50  		}
    51  	}
    52  	return nil
    53  }
    54  
    55  func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context {
    56  	c := appengine.NewContext(req)
    57  	return withContext(parent, c)
    58  }
    59  
    60  func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error {
    61  	if f, ctx, ok := callOverrideFromContext(ctx); ok {
    62  		return f(ctx, service, method, in, out)
    63  	}
    64  
    65  	// Handle already-done contexts quickly.
    66  	select {
    67  	case <-ctx.Done():
    68  		return ctx.Err()
    69  	default:
    70  	}
    71  
    72  	c := fromContext(ctx)
    73  	if c == nil {
    74  		// Give a good error message rather than a panic lower down.
    75  		return errors.New("not an App Engine context")
    76  	}
    77  
    78  	// Apply transaction modifications if we're in a transaction.
    79  	if t := transactionFromContext(ctx); t != nil {
    80  		if t.finished {
    81  			return errors.New("transaction context has expired")
    82  		}
    83  		applyTransaction(in, &t.transaction)
    84  	}
    85  
    86  	var opts *appengine_internal.CallOptions
    87  	if d, ok := ctx.Deadline(); ok {
    88  		opts = &appengine_internal.CallOptions{
    89  			Timeout: d.Sub(time.Now()),
    90  		}
    91  	}
    92  
    93  	err := c.Call(service, method, in, out, opts)
    94  	switch v := err.(type) {
    95  	case *appengine_internal.APIError:
    96  		return &APIError{
    97  			Service: v.Service,
    98  			Detail:  v.Detail,
    99  			Code:    v.Code,
   100  		}
   101  	case *appengine_internal.CallError:
   102  		return &CallError{
   103  			Detail:  v.Detail,
   104  			Code:    v.Code,
   105  			Timeout: v.Timeout,
   106  		}
   107  	}
   108  	return err
   109  }
   110  
   111  func handleHTTP(w http.ResponseWriter, r *http.Request) {
   112  	panic("handleHTTP called; this should be impossible")
   113  }
   114  
   115  func logf(c appengine.Context, level int64, format string, args ...interface{}) {
   116  	var fn func(format string, args ...interface{})
   117  	switch level {
   118  	case 0:
   119  		fn = c.Debugf
   120  	case 1:
   121  		fn = c.Infof
   122  	case 2:
   123  		fn = c.Warningf
   124  	case 3:
   125  		fn = c.Errorf
   126  	case 4:
   127  		fn = c.Criticalf
   128  	default:
   129  		// This shouldn't happen.
   130  		fn = c.Criticalf
   131  	}
   132  	fn(format, args...)
   133  }