vendor/google.golang.org/appengine/internal/api.go
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
child 256 6d9efbef00a9
equal deleted inserted replaced
250:c040f992052f 251:1c52a0eeb952
     1 // Copyright 2011 Google Inc. All rights reserved.
     1 // Copyright 2011 Google Inc. All rights reserved.
     2 // Use of this source code is governed by the Apache 2.0
     2 // Use of this source code is governed by the Apache 2.0
     3 // license that can be found in the LICENSE file.
     3 // license that can be found in the LICENSE file.
     4 
     4 
     5 // +build !appengine
     5 // +build !appengine
     6 // +build go1.7
       
     7 
     6 
     8 package internal
     7 package internal
     9 
     8 
    10 import (
     9 import (
    11 	"bytes"
    10 	"bytes"
    43 	dapperHeader       = http.CanonicalHeaderKey("X-Google-DapperTraceInfo")
    42 	dapperHeader       = http.CanonicalHeaderKey("X-Google-DapperTraceInfo")
    44 	traceHeader        = http.CanonicalHeaderKey("X-Cloud-Trace-Context")
    43 	traceHeader        = http.CanonicalHeaderKey("X-Cloud-Trace-Context")
    45 	curNamespaceHeader = http.CanonicalHeaderKey("X-AppEngine-Current-Namespace")
    44 	curNamespaceHeader = http.CanonicalHeaderKey("X-AppEngine-Current-Namespace")
    46 	userIPHeader       = http.CanonicalHeaderKey("X-AppEngine-User-IP")
    45 	userIPHeader       = http.CanonicalHeaderKey("X-AppEngine-User-IP")
    47 	remoteAddrHeader   = http.CanonicalHeaderKey("X-AppEngine-Remote-Addr")
    46 	remoteAddrHeader   = http.CanonicalHeaderKey("X-AppEngine-Remote-Addr")
       
    47 	devRequestIdHeader = http.CanonicalHeaderKey("X-Appengine-Dev-Request-Id")
    48 
    48 
    49 	// Outgoing headers.
    49 	// Outgoing headers.
    50 	apiEndpointHeader      = http.CanonicalHeaderKey("X-Google-RPC-Service-Endpoint")
    50 	apiEndpointHeader      = http.CanonicalHeaderKey("X-Google-RPC-Service-Endpoint")
    51 	apiEndpointHeaderValue = []string{"app-engine-apis"}
    51 	apiEndpointHeaderValue = []string{"app-engine-apis"}
    52 	apiMethodHeader        = http.CanonicalHeaderKey("X-Google-RPC-Service-Method")
    52 	apiMethodHeader        = http.CanonicalHeaderKey("X-Google-RPC-Service-Method")
   128 	flushes := c.pendingLogs.flushes
   128 	flushes := c.pendingLogs.flushes
   129 	if len(c.pendingLogs.lines) > 0 {
   129 	if len(c.pendingLogs.lines) > 0 {
   130 		flushes++
   130 		flushes++
   131 	}
   131 	}
   132 	c.pendingLogs.Unlock()
   132 	c.pendingLogs.Unlock()
   133 	go c.flushLog(false)
   133 	flushed := make(chan struct{})
       
   134 	go func() {
       
   135 		defer close(flushed)
       
   136 		// Force a log flush, because with very short requests we
       
   137 		// may not ever flush logs.
       
   138 		c.flushLog(true)
       
   139 	}()
   134 	w.Header().Set(logFlushHeader, strconv.Itoa(flushes))
   140 	w.Header().Set(logFlushHeader, strconv.Itoa(flushes))
   135 
   141 
   136 	// Avoid nil Write call if c.Write is never called.
   142 	// Avoid nil Write call if c.Write is never called.
   137 	if c.outCode != 0 {
   143 	if c.outCode != 0 {
   138 		w.WriteHeader(c.outCode)
   144 		w.WriteHeader(c.outCode)
   139 	}
   145 	}
   140 	if c.outBody != nil {
   146 	if c.outBody != nil {
   141 		w.Write(c.outBody)
   147 		w.Write(c.outBody)
   142 	}
   148 	}
       
   149 	// Wait for the last flush to complete before returning,
       
   150 	// otherwise the security ticket will not be valid.
       
   151 	<-flushed
   143 }
   152 }
   144 
   153 
   145 func executeRequestSafely(c *context, r *http.Request) {
   154 func executeRequestSafely(c *context, r *http.Request) {
   146 	defer func() {
   155 	defer func() {
   147 		if x := recover(); x != nil {
   156 		if x := recover(); x != nil {
   484 	}
   493 	}
   485 	// Fall back to use background ticket when the request ticket is not available in Flex or dev_appserver.
   494 	// Fall back to use background ticket when the request ticket is not available in Flex or dev_appserver.
   486 	if ticket == "" {
   495 	if ticket == "" {
   487 		ticket = DefaultTicket()
   496 		ticket = DefaultTicket()
   488 	}
   497 	}
       
   498 	if dri := c.req.Header.Get(devRequestIdHeader); IsDevAppServer() && dri != "" {
       
   499 		ticket = dri
       
   500 	}
   489 	req := &remotepb.Request{
   501 	req := &remotepb.Request{
   490 		ServiceName: &service,
   502 		ServiceName: &service,
   491 		Method:      &method,
   503 		Method:      &method,
   492 		Request:     data,
   504 		Request:     data,
   493 		RequestId:   &ticket,
   505 		RequestId:   &ticket,
   569 	c.addLogLine(&logpb.UserAppLogLine{
   581 	c.addLogLine(&logpb.UserAppLogLine{
   570 		TimestampUsec: proto.Int64(time.Now().UnixNano() / 1e3),
   582 		TimestampUsec: proto.Int64(time.Now().UnixNano() / 1e3),
   571 		Level:         &level,
   583 		Level:         &level,
   572 		Message:       &s,
   584 		Message:       &s,
   573 	})
   585 	})
   574 	log.Print(logLevelName[level] + ": " + s)
   586 	// Only duplicate log to stderr if not running on App Engine second generation
       
   587 	if !IsSecondGen() {
       
   588 		log.Print(logLevelName[level] + ": " + s)
       
   589 	}
   575 }
   590 }
   576 
   591 
   577 // flushLog attempts to flush any pending logs to the appserver.
   592 // flushLog attempts to flush any pending logs to the appserver.
   578 // It should not be called concurrently.
   593 // It should not be called concurrently.
   579 func (c *context) flushLog(force bool) (flushed bool) {
   594 func (c *context) flushLog(force bool) (flushed bool) {