text:
// Copyright 2012 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build appengine

package socket

import (
	"fmt"
	"io"
	"net"
	"strconv"
	"time"

	"github.com/golang/protobuf/proto"
	"golang.org/x/net/context"
	"google.golang.org/appengine/internal"

	pb "google.golang.org/appengine/internal/socket"
)

// Dial connects to the address addr on the network protocol.
// The address format is host:port, where host may be a hostname or an IP address.
// Known protocols are "tcp" and "udp".
// The returned connection satisfies net.Conn, and is valid while ctx is valid;
// if the connection is to be used after ctx becomes invalid, invoke SetContext
// with the new context.
func Dial(ctx context.Context, protocol, addr string) (*Conn, error) {
	return DialTimeout(ctx, protocol, addr, 0)
}

var ipFamilies = []pb.CreateSocketRequest_SocketFamily{
	pb.CreateSocketRequest_IPv4,
	pb.CreateSocketRequest_IPv6,
}

// DialTimeout is like Dial but takes a timeout.
// The timeout includes name resolution, if required.
func DialTimeout(ctx context.Context, protocol, addr string, timeout time.Duration) (*Conn, error) {
	dialCtx := ctx // Used for dialing and name resolution, but not stored in the *Conn.
	if timeout > 0 {
		var cancel context.CancelFunc
		dialCtx, cancel = context.WithTimeout(ctx, timeout)
		defer cancel()
	}

	host, portStr, err := net.SplitHostPort(addr)
	if err != nil {
		return nil, err
	}
	port, err := strconv.Atoi(portStr)
	if err != nil {
		return nil, fmt.Errorf("socket: bad port %q: %v", portStr, err)
	}

	var prot pb.CreateSocketRequest_SocketProtocol
	switch protocol {
	case "tcp":
		prot = pb.CreateSocketRequest_TCP
	case "udp":
		prot = pb.CreateSocketRequest_UDP
	default:
		return nil, fmt.Errorf("socket: unknown protocol %q", protocol)
	}

	packedAddrs, resolved, err := resolve(dialCtx, ipFamilies, host)
	if err != nil {
		return nil, fmt.Errorf("socket: failed resolving %q: %v", host, err)
	}
	if len(packedAddrs) == 0 {
		return nil, fmt.Errorf("no addresses for %q", host)
	}

	packedAddr := packedAddrs[0] // use first address
	fam := pb.CreateSocketRequest_IPv4
	if len(packedAddr) == net.IPv6len {
		fam = pb.CreateSocketRequest_IPv6
	}

	req := &pb.CreateSocketRequest{
		Family:   fam.Enum(),
		Protocol: prot.Enum(),
		RemoteIp: &pb.AddressPort{
			Port:          proto.Int32(int32(port)),
			PackedAddress: packedAddr,
		},
	}
	if resolved {
		req.RemoteIp.HostnameHint = &host
	}
	res := &pb.CreateSocketReply{}
	if err := internal.Call(dialCtx, "remote_socket", "CreateSocket", req, res); err != nil {
		return nil, err
	}

	return &Conn{
		ctx:    ctx,
		desc:   res.GetSocketDescriptor(),
		prot:   prot,
		local:  res.ProxyExternalIp,
		remote: req.RemoteIp,
	}, nil
}

// LookupIP returns the given host's IP addresses.
func LookupIP(ctx context.Context, host string) (addrs []net.IP, err error) {
	packedAddrs, _, err := resolve(ctx, ipFamilies, host)
	if err != nil {
		return nil, fmt.Errorf("socket: failed resolving %q: %v", host, err)
	}
	addrs = make([]net.IP, len(packedAddrs))
	for i, pa := range packedAddrs {
		addrs[i] = net.IP(pa)
	}
	return addrs, nil
}

func resolve(ctx context.Context, fams []pb.CreateSocketRequest_SocketFamily, host string) ([][]byte, bool, error) {
	// Check if it's an IP address.
	if ip := net.ParseIP(host); ip != nil {
		if ip := ip.To4(); ip != nil {
			return [][]byte{ip}, false, nil
		}
		return [][]byte{ip}, false, nil
	}

	req := &pb.ResolveRequest{
		Name:            &host,
		AddressFamilies: fams,
	}
	res := &pb.ResolveReply{}
	if err := internal.Call(ctx, "remote_socket", "Resolve", req, res); err != nil {
		// XXX: need to map to pb.ResolveReply_ErrorCode?
		return nil, false, err
	}
	return res.PackedAddress, true, nil
}

// withDeadline is like context.WithDeadline, except it ignores the zero deadline.
func withDeadline(parent context.Context, deadline time.Time) (context.Context, context.CancelFunc) {
	if deadline.IsZero() {
		return parent, func() {}
	}
	return context.WithDeadline(parent, deadline)
}

// Conn represents a socket connection.
// It implements net.Conn.
type Conn struct {
	ctx    context.Context
	desc   string
	offset int64

	prot          pb.CreateSocketRequest_SocketProtocol
	local, remote *pb.AddressPort

	readDeadline, writeDeadline time.Time // optional
}

// SetContext sets the context that is used by this Conn.
// It is usually used only when using a Conn that was created in a different context,
// such as when a connection is created during a warmup request but used while
// servicing a user request.
func (cn *Conn) SetContext(ctx context.Context) {
	cn.ctx = ctx
}

func (cn *Conn) Read(b []byte) (n int, err error) {
	const maxRead = 1 << 20
	if len(b) > maxRead {
		b = b[:maxRead]
	}

	req := &pb.ReceiveRequest{
		SocketDescriptor: &cn.desc,
		DataSize:         proto.Int32(int32(len(b))),
	}
	res := &pb.ReceiveReply{}
	if !cn.readDeadline.IsZero() {
		req.TimeoutSeconds = proto.Float64(cn.readDeadline.Sub(time.Now()).Seconds())
	}
	ctx, cancel := withDeadline(cn.ctx, cn.readDeadline)
	defer cancel()
	if err := internal.Call(ctx, "remote_socket", "Receive", req, res); err != nil {
		return 0, err
	}
	if len(res.Data) == 0 {
		return 0, io.EOF
	}
	if len(res.Data) > len(b) {
		return 0, fmt.Errorf("socket: internal error: read too much data: %d > %d", len(res.Data), len(b))
	}
	return copy(b, res.Data), nil
}

func (cn *Conn) Write(b []byte) (n int, err error) {
	const lim = 1 << 20 // max per chunk

	for n < len(b) {
		chunk := b[n:]
		if len(chunk) > lim {
			chunk = chunk[:lim]
		}

		req := &pb.SendRequest{
			SocketDescriptor: &cn.desc,
			Data:             chunk,
			StreamOffset:     &cn.offset,
		}
		res := &pb.SendReply{}
		if !cn.writeDeadline.IsZero() {
			req.TimeoutSeconds = proto.Float64(cn.writeDeadline.Sub(time.Now()).Seconds())
		}
		ctx, cancel := withDeadline(cn.ctx, cn.writeDeadline)
		defer cancel()
		if err = internal.Call(ctx, "remote_socket", "Send", req, res); err != nil {
			// assume zero bytes were sent in this RPC
			break
		}
		n += int(res.GetDataSent())
		cn.offset += int64(res.GetDataSent())
	}

	return
}

func (cn *Conn) Close() error {
	req := &pb.CloseRequest{
		SocketDescriptor: &cn.desc,
	}
	res := &pb.CloseReply{}
	if err := internal.Call(cn.ctx, "remote_socket", "Close", req, res); err != nil {
		return err
	}
	cn.desc = "CLOSED"
	return nil
}

func addr(prot pb.CreateSocketRequest_SocketProtocol, ap *pb.AddressPort) net.Addr {
	if ap == nil {
		return nil
	}
	switch prot {
	case pb.CreateSocketRequest_TCP:
		return &net.TCPAddr{
			IP:   net.IP(ap.PackedAddress),
			Port: int(*ap.Port),
		}
	case pb.CreateSocketRequest_UDP:
		return &net.UDPAddr{
			IP:   net.IP(ap.PackedAddress),
			Port: int(*ap.Port),
		}
	}
	panic("unknown protocol " + prot.String())
}

func (cn *Conn) LocalAddr() net.Addr  { return addr(cn.prot, cn.local) }
func (cn *Conn) RemoteAddr() net.Addr { return addr(cn.prot, cn.remote) }

func (cn *Conn) SetDeadline(t time.Time) error {
	cn.readDeadline = t
	cn.writeDeadline = t
	return nil
}

func (cn *Conn) SetReadDeadline(t time.Time) error {
	cn.readDeadline = t
	return nil
}

func (cn *Conn) SetWriteDeadline(t time.Time) error {
	cn.writeDeadline = t
	return nil
}

// KeepAlive signals that the connection is still in use.
// It may be called to prevent the socket being closed due to inactivity.
func (cn *Conn) KeepAlive() error {
	req := &pb.GetSocketNameRequest{
		SocketDescriptor: &cn.desc,
	}
	res := &pb.GetSocketNameReply{}
	return internal.Call(cn.ctx, "remote_socket", "GetSocketName", req, res)
}

func init() {
	internal.RegisterErrorCodeMap("remote_socket", pb.RemoteSocketServiceError_ErrorCode_name)
}


text:
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build !appengine

package socket

import (
	"net"
	"time"

	"golang.org/x/net/context"
)

// Dial connects to the address addr on the network protocol.
// The address format is host:port, where host may be a hostname or an IP address.
// Known protocols are "tcp" and "udp".
// The returned connection satisfies net.Conn, and is valid while ctx is valid;
// if the connection is to be used after ctx becomes invalid, invoke SetContext
// with the new context.
func Dial(ctx context.Context, protocol, addr string) (*Conn, error) {
	conn, err := net.Dial(protocol, addr)
	if err != nil {
		return nil, err
	}
	return &Conn{conn}, nil
}

// DialTimeout is like Dial but takes a timeout.
// The timeout includes name resolution, if required.
func DialTimeout(ctx context.Context, protocol, addr string, timeout time.Duration) (*Conn, error) {
	conn, err := net.DialTimeout(protocol, addr, timeout)
	if err != nil {
		return nil, err
	}
	return &Conn{conn}, nil
}

// LookupIP returns the given host's IP addresses.
func LookupIP(ctx context.Context, host string) (addrs []net.IP, err error) {
	return net.LookupIP(host)
}

// Conn represents a socket connection.
// It implements net.Conn.
type Conn struct {
	net.Conn
}

// SetContext sets the context that is used by this Conn.
// It is usually used only when using a Conn that was created in a different context,
// such as when a connection is created during a warmup request but used while
// servicing a user request.
func (cn *Conn) SetContext(ctx context.Context) {
	// This function is not required in App Engine "flexible environment".
}

// KeepAlive signals that the connection is still in use.
// It may be called to prevent the socket being closed due to inactivity.
func (cn *Conn) KeepAlive() error {
	// This function is not required in App Engine "flexible environment".
	return nil
}

repo_name: dan-v/dosxvpn

repo_language: Go

mime_type: text/x-shellscript


text:
// Copyright 2012 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// Package socket provides outbound network sockets.
//
// This package is only required in the classic App Engine environment.
// Applications running only in App Engine "flexible environment" should
// use the standard library's net package.
package socket


text:
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package log

// This file implements the logging API.

import (
	"golang.org/x/net/context"

	"google.golang.org/appengine/internal"
)

// Debugf formats its arguments according to the format, analogous to fmt.Printf,
// and records the text as a log message at Debug level. The message will be associated
// with the request linked with the provided context.
func Debugf(ctx context.Context, format string, args ...interface{}) {
	internal.Logf(ctx, 0, format, args...)
}

// Infof is like Debugf, but at Info level.
func Infof(ctx context.Context, format string, args ...interface{}) {
	internal.Logf(ctx, 1, format, args...)
}

// Warningf is like Debugf, but at Warning level.
func Warningf(ctx context.Context, format string, args ...interface{}) {
	internal.Logf(ctx, 2, format, args...)
}

// Errorf is like Debugf, but at Error level.
func Errorf(ctx context.Context, format string, args ...interface{}) {
	internal.Logf(ctx, 3, format, args...)
}

// Criticalf is like Debugf, but at Critical level.
func Criticalf(ctx context.Context, format string, args ...interface{}) {
	internal.Logf(ctx, 4, format, args...)
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

/*
Package log provides the means of querying an application's logs from
within an App Engine application.

Example:
	c := appengine.NewContext(r)
	query := &log.Query{
		AppLogs:  true,
		Versions: []string{"1"},
	}

	for results := query.Run(c); ; {
		record, err := results.Next()
		if err == log.Done {
			log.Infof(c, "Done processing results")
			break
		}
		if err != nil {
			log.Errorf(c, "Failed to retrieve next log: %v", err)
			break
		}
		log.Infof(c, "Saw record %v", record)
	}
*/
package log // import "google.golang.org/appengine/log"

import (
	"errors"
	"fmt"
	"strings"
	"time"

	"github.com/golang/protobuf/proto"
	"golang.org/x/net/context"

	"google.golang.org/appengine"
	"google.golang.org/appengine/internal"
	pb "google.golang.org/appengine/internal/log"
)

// Query defines a logs query.
type Query struct {
	// Start time specifies the earliest log to return (inclusive).
	StartTime time.Time

	// End time specifies the latest log to return (exclusive).
	EndTime time.Time

	// Offset specifies a position within the log stream to resume reading from,
	// and should come from a previously returned Record's field of the same name.
	Offset []byte

	// Incomplete controls whether active (incomplete) requests should be included.
	Incomplete bool

	// AppLogs indicates if application-level logs should be included.
	AppLogs bool

	// ApplyMinLevel indicates if MinLevel should be used to filter results.
	ApplyMinLevel bool

	// If ApplyMinLevel is true, only logs for requests with at least one
	// application log of MinLevel or higher will be returned.
	MinLevel int

	// Versions is the major version IDs whose logs should be retrieved.
	// Logs for specific modules can be retrieved by the specifying versions
	// in the form "module:version"; the default module is used if no module
	// is specified.
	Versions []string

	// A list of requests to search for instead of a time-based scan. Cannot be
	// combined with filtering options such as StartTime, EndTime, Offset,
	// Incomplete, ApplyMinLevel, or Versions.
	RequestIDs []string
}

// AppLog represents a single application-level log.
type AppLog struct {
	Time    time.Time
	Level   int
	Message string
}

// Record contains all the information for a single web request.
type Record struct {
	AppID            string
	ModuleID         string
	VersionID        string
	RequestID        []byte
	IP               string
	Nickname         string
	AppEngineRelease string

	// The time when this request started.
	StartTime time.Time

	// The time when this request finished.
	EndTime time.Time

	// Opaque cursor into the result stream.
	Offset []byte

	// The time required to process the request.
	Latency     time.Duration
	MCycles     int64
	Method      string
	Resource    string
	HTTPVersion string
	Status      int32

	// The size of the request sent back to the client, in bytes.
	ResponseSize int64
	Referrer     string
	UserAgent    string
	URLMapEntry  string
	Combined     string
	Host         string

	// The estimated cost of this request, in dollars.
	Cost              float64
	TaskQueueName     string
	TaskName          string
	WasLoadingRequest bool
	PendingTime       time.Duration
	Finished          bool
	AppLogs           []AppLog

	// Mostly-unique identifier for the instance that handled the request if available.
	InstanceID string
}

// Result represents the result of a query.
type Result struct {
	logs        []*Record
	context     context.Context
	request     *pb.LogReadRequest
	resultsSeen bool
	err         error
}

// Next returns the next log record,
func (qr *Result) Next() (*Record, error) {
	if qr.err != nil {
		return nil, qr.err
	}
	if len(qr.logs) > 0 {
		lr := qr.logs[0]
		qr.logs = qr.logs[1:]
		return lr, nil
	}

	if qr.request.Offset == nil && qr.resultsSeen {
		return nil, Done
	}

	if err := qr.run(); err != nil {
		// Errors here may be retried, so don't store the error.
		return nil, err
	}

	return qr.Next()
}

// Done is returned when a query iteration has completed.
var Done = errors.New("log: query has no more results")

// protoToAppLogs takes as input an array of pointers to LogLines, the internal
// Protocol Buffer representation of a single application-level log,
// and converts it to an array of AppLogs, the external representation
// of an application-level log.
func protoToAppLogs(logLines []*pb.LogLine) []AppLog {
	appLogs := make([]AppLog, len(logLines))

	for i, line := range logLines {
		appLogs[i] = AppLog{
			Time:    time.Unix(0, *line.Time*1e3),
			Level:   int(*line.Level),
			Message: *line.LogMessage,
		}
	}

	return appLogs
}

// protoToRecord converts a RequestLog, the internal Protocol Buffer
// representation of a single request-level log, to a Record, its
// corresponding external representation.
func protoToRecord(rl *pb.RequestLog) *Record {
	offset, err := proto.Marshal(rl.Offset)
	if err != nil {
		offset = nil
	}
	return &Record{
		AppID:             *rl.AppId,
		ModuleID:          rl.GetModuleId(),
		VersionID:         *rl.VersionId,
		RequestID:         rl.RequestId,
		Offset:            offset,
		IP:                *rl.Ip,
		Nickname:          rl.GetNickname(),
		AppEngineRelease:  string(rl.GetAppEngineRelease()),
		StartTime:         time.Unix(0, *rl.StartTime*1e3),
		EndTime:           time.Unix(0, *rl.EndTime*1e3),
		Latency:           time.Duration(*rl.Latency) * time.Microsecond,
		MCycles:           *rl.Mcycles,
		Method:            *rl.Method,
		Resource:          *rl.Resource,
		HTTPVersion:       *rl.HttpVersion,
		Status:            *rl.Status,
		ResponseSize:      *rl.ResponseSize,
		Referrer:          rl.GetReferrer(),
		UserAgent:         rl.GetUserAgent(),
		URLMapEntry:       *rl.UrlMapEntry,
		Combined:          *rl.Combined,
		Host:              rl.GetHost(),
		Cost:              rl.GetCost(),
		TaskQueueName:     rl.GetTaskQueueName(),
		TaskName:          rl.GetTaskName(),
		WasLoadingRequest: rl.GetWasLoadingRequest(),
		PendingTime:       time.Duration(rl.GetPendingTime()) * time.Microsecond,
		Finished:          rl.GetFinished(),
		AppLogs:           protoToAppLogs(rl.Line),
		InstanceID:        string(rl.GetCloneKey()),
	}
}

// Run starts a query for log records, which contain request and application
// level log information.
func (params *Query) Run(c context.Context) *Result {
	req, err := makeRequest(params, internal.FullyQualifiedAppID(c), appengine.VersionID(c))
	return &Result{
		context: c,
		request: req,
		err:     err,
	}
}

func makeRequest(params *Query, appID, versionID string) (*pb.LogReadRequest, error) {
	req := &pb.LogReadRequest{}
	req.AppId = &appID
	if !params.StartTime.IsZero() {
		req.StartTime = proto.Int64(params.StartTime.UnixNano() / 1e3)
	}
	if !params.EndTime.IsZero() {
		req.EndTime = proto.Int64(params.EndTime.UnixNano() / 1e3)
	}
	if len(params.Offset) > 0 {
		var offset pb.LogOffset
		if err := proto.Unmarshal(params.Offset, &offset); err != nil {
			return nil, fmt.Errorf("bad Offset: %v", err)
		}
		req.Offset = &offset
	}
	if params.Incomplete {
		req.IncludeIncomplete = &params.Incomplete
	}
	if params.AppLogs {
		req.IncludeAppLogs = &params.AppLogs
	}
	if params.ApplyMinLevel {
		req.MinimumLogLevel = proto.Int32(int32(params.MinLevel))
	}
	if params.Versions == nil {
		// If no versions were specified, default to the default module at
		// the major version being used by this module.
		if i := strings.Index(versionID, "."); i >= 0 {
			versionID = versionID[:i]
		}
		req.VersionId = []string{versionID}
	} else {
		req.ModuleVersion = make([]*pb.LogModuleVersion, 0, len(params.Versions))
		for _, v := range params.Versions {
			var m *string
			if i := strings.Index(v, ":"); i >= 0 {
				m, v = proto.String(v[:i]), v[i+1:]
			}
			req.ModuleVersion = append(req.ModuleVersion, &pb.LogModuleVersion{
				ModuleId:  m,
				VersionId: proto.String(v),
			})
		}
	}
	if params.RequestIDs != nil {
		ids := make([][]byte, len(params.RequestIDs))
		for i, v := range params.RequestIDs {
			ids[i] = []byte(v)
		}
		req.RequestId = ids
	}

	return req, nil
}

// run takes the query Result produced by a call to Run and updates it with
// more Records. The updated Result contains a new set of logs as well as an
// offset to where more logs can be found. We also convert the items in the
// response from their internal representations to external versions of the
// same structs.
func (r *Result) run() error {
	res := &pb.LogReadResponse{}
	if err := internal.Call(r.context, "logservice", "Read", r.request, res); err != nil {
		return err
	}

	r.logs = make([]*Record, len(res.Log))
	r.request.Offset = res.Offset
	r.resultsSeen = true

	for i, log := range res.Log {
		r.logs[i] = protoToRecord(log)
	}

	return nil
}

func init() {
	internal.RegisterErrorCodeMap("logservice", pb.LogServiceError_ErrorCode_name)
}


text:
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package log

import (
	"reflect"
	"testing"
	"time"

	"github.com/golang/protobuf/proto"

	pb "google.golang.org/appengine/internal/log"
)

func TestQueryToRequest(t *testing.T) {
	testCases := []struct {
		desc  string
		query *Query
		want  *pb.LogReadRequest
	}{
		{
			desc:  "Empty",
			query: &Query{},
			want: &pb.LogReadRequest{
				AppId:     proto.String("s~fake"),
				VersionId: []string{"v12"},
			},
		},
		{
			desc: "Versions",
			query: &Query{
				Versions: []string{"alpha", "backend:beta"},
			},
			want: &pb.LogReadRequest{
				AppId: proto.String("s~fake"),
				ModuleVersion: []*pb.LogModuleVersion{
					{
						VersionId: proto.String("alpha"),
					}, {
						ModuleId:  proto.String("backend"),
						VersionId: proto.String("beta"),
					},
				},
			},
		},
	}

	for _, tt := range testCases {
		req, err := makeRequest(tt.query, "s~fake", "v12")

		if err != nil {
			t.Errorf("%s: got err %v, want nil", tt.desc, err)
			continue
		}
		if !proto.Equal(req, tt.want) {
			t.Errorf("%s request:\ngot  %v\nwant %v", tt.desc, req, tt.want)
		}
	}
}

func TestProtoToRecord(t *testing.T) {
	// We deliberately leave ModuleId and other optional fields unset.
	p := &pb.RequestLog{
		AppId:        proto.String("s~fake"),
		VersionId:    proto.String("1"),
		RequestId:    []byte("deadbeef"),
		Ip:           proto.String("127.0.0.1"),
		StartTime:    proto.Int64(431044244000000),
		EndTime:      proto.Int64(431044724000000),
		Latency:      proto.Int64(480000000),
		Mcycles:      proto.Int64(7),
		Method:       proto.String("GET"),
		Resource:     proto.String("/app"),
		HttpVersion:  proto.String("1.1"),
		Status:       proto.Int32(418),
		ResponseSize: proto.Int64(1337),
		UrlMapEntry:  proto.String("_go_app"),
		Combined:     proto.String("apache log"),
	}
	// Sanity check that all required fields are set.
	if _, err := proto.Marshal(p); err != nil {
		t.Fatalf("proto.Marshal: %v", err)
	}
	want := &Record{
		AppID:        "s~fake",
		ModuleID:     "default",
		VersionID:    "1",
		RequestID:    []byte("deadbeef"),
		IP:           "127.0.0.1",
		StartTime:    time.Date(1983, 8, 29, 22, 30, 44, 0, time.UTC),
		EndTime:      time.Date(1983, 8, 29, 22, 38, 44, 0, time.UTC),
		Latency:      8 * time.Minute,
		MCycles:      7,
		Method:       "GET",
		Resource:     "/app",
		HTTPVersion:  "1.1",
		Status:       418,
		ResponseSize: 1337,
		URLMapEntry:  "_go_app",
		Combined:     "apache log",
		Finished:     true,
		AppLogs:      []AppLog{},
	}
	got := protoToRecord(p)
	// Coerce locations to UTC since otherwise they will be in local.
	got.StartTime, got.EndTime = got.StartTime.UTC(), got.EndTime.UTC()
	if !reflect.DeepEqual(got, want) {
		t.Errorf("protoToRecord:\ngot:  %v\nwant: %v", got, want)
	}
}


text:
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package channel

import (
	"testing"

	"google.golang.org/appengine/internal"
)

func TestRemapError(t *testing.T) {
	err := &internal.APIError{
		Service: "xmpp",
	}
	err = remapError(err).(*internal.APIError)
	if err.Service != "channel" {
		t.Errorf("err.Service = %q, want %q", err.Service, "channel")
	}
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

/*
Package channel implements the server side of App Engine's Channel API.

Create creates a new channel associated with the given clientID,
which must be unique to the client that will use the returned token.

	token, err := channel.Create(c, "player1")
	if err != nil {
		// handle error
	}
	// return token to the client in an HTTP response

Send sends a message to the client over the channel identified by clientID.

	channel.Send(c, "player1", "Game over!")
*/
package channel // import "google.golang.org/appengine/channel"

import (
	"encoding/json"

	"golang.org/x/net/context"

	"google.golang.org/appengine"
	"google.golang.org/appengine/internal"
	basepb "google.golang.org/appengine/internal/base"
	pb "google.golang.org/appengine/internal/channel"
)

// Create creates a channel and returns a token for use by the client.
// The clientID is an application-provided string used to identify the client.
func Create(c context.Context, clientID string) (token string, err error) {
	req := &pb.CreateChannelRequest{
		ApplicationKey: &clientID,
	}
	resp := &pb.CreateChannelResponse{}
	err = internal.Call(c, service, "CreateChannel", req, resp)
	token = resp.GetToken()
	return token, remapError(err)
}

// Send sends a message on the channel associated with clientID.
func Send(c context.Context, clientID, message string) error {
	req := &pb.SendMessageRequest{
		ApplicationKey: &clientID,
		Message:        &message,
	}
	resp := &basepb.VoidProto{}
	return remapError(internal.Call(c, service, "SendChannelMessage", req, resp))
}

// SendJSON is a helper function that sends a JSON-encoded value
// on the channel associated with clientID.
func SendJSON(c context.Context, clientID string, value interface{}) error {
	m, err := json.Marshal(value)
	if err != nil {
		return err
	}
	return Send(c, clientID, string(m))
}

// remapError fixes any APIError referencing "xmpp" into one referencing "channel".
func remapError(err error) error {
	if e, ok := err.(*internal.APIError); ok {
		if e.Service == "xmpp" {
			e.Service = "channel"
		}
	}
	return err
}

var service = "xmpp" // prod

func init() {
	if appengine.IsDevAppServer() {
		service = "channel" // dev
	}
	internal.RegisterErrorCodeMap("channel", pb.ChannelServiceError_ErrorCode_name)
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build !appengine

package internal

import (
	"net/http"
	"os"

	netcontext "golang.org/x/net/context"
)

// These functions are implementations of the wrapper functions
// in ../appengine/identity.go. See that file for commentary.

const (
	hDefaultVersionHostname = "X-AppEngine-Default-Version-Hostname"
	hRequestLogId           = "X-AppEngine-Request-Log-Id"
	hDatacenter             = "X-AppEngine-Datacenter"
)

func ctxHeaders(ctx netcontext.Context) http.Header {
	return fromContext(ctx).Request().Header
}

func DefaultVersionHostname(ctx netcontext.Context) string {
	return ctxHeaders(ctx).Get(hDefaultVersionHostname)
}

func RequestID(ctx netcontext.Context) string {
	return ctxHeaders(ctx).Get(hRequestLogId)
}

func Datacenter(ctx netcontext.Context) string {
	return ctxHeaders(ctx).Get(hDatacenter)
}

func ServerSoftware() string {
	// TODO(dsymonds): Remove fallback when we've verified this.
	if s := os.Getenv("SERVER_SOFTWARE"); s != "" {
		return s
	}
	return "Google App Engine/1.x.x"
}

// TODO(dsymonds): Remove the metadata fetches.

func ModuleName(_ netcontext.Context) string {
	if s := os.Getenv("GAE_MODULE_NAME"); s != "" {
		return s
	}
	return string(mustGetMetadata("instance/attributes/gae_backend_name"))
}

func VersionID(_ netcontext.Context) string {
	if s1, s2 := os.Getenv("GAE_MODULE_VERSION"), os.Getenv("GAE_MINOR_VERSION"); s1 != "" && s2 != "" {
		return s1 + "." + s2
	}
	return string(mustGetMetadata("instance/attributes/gae_backend_version")) + "." + string(mustGetMetadata("instance/attributes/gae_backend_minor_version"))
}

func InstanceID() string {
	if s := os.Getenv("GAE_MODULE_INSTANCE"); s != "" {
		return s
	}
	return string(mustGetMetadata("instance/attributes/gae_backend_instance"))
}

func partitionlessAppID() string {
	// gae_project has everything except the partition prefix.
	appID := os.Getenv("GAE_LONG_APP_ID")
	if appID == "" {
		appID = string(mustGetMetadata("instance/attributes/gae_project"))
	}
	return appID
}

func fullyQualifiedAppID(_ netcontext.Context) string {
	appID := partitionlessAppID()

	part := os.Getenv("GAE_PARTITION")
	if part == "" {
		part = string(mustGetMetadata("instance/attributes/gae_partition"))
	}

	if part != "" {
		appID = part + "~" + appID
	}
	return appID
}

func IsDevAppServer() bool {
	return os.Getenv("RUN_WITH_DEVAPPSERVER") != ""
}


text:
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build appengine

package internal

import (
	"errors"
	"fmt"
	"net/http"
	"time"

	"appengine"
	"appengine_internal"
	basepb "appengine_internal/base"

	"github.com/golang/protobuf/proto"
	netcontext "golang.org/x/net/context"
)

var contextKey = "holds an appengine.Context"

func fromContext(ctx netcontext.Context) appengine.Context {
	c, _ := ctx.Value(&contextKey).(appengine.Context)
	return c
}

// This is only for classic App Engine adapters.
func ClassicContextFromContext(ctx netcontext.Context) appengine.Context {
	return fromContext(ctx)
}

func withContext(parent netcontext.Context, c appengine.Context) netcontext.Context {
	ctx := netcontext.WithValue(parent, &contextKey, c)

	s := &basepb.StringProto{}
	c.Call("__go__", "GetNamespace", &basepb.VoidProto{}, s, nil)
	if ns := s.GetValue(); ns != "" {
		ctx = NamespacedContext(ctx, ns)
	}

	return ctx
}

func IncomingHeaders(ctx netcontext.Context) http.Header {
	if c := fromContext(ctx); c != nil {
		if req, ok := c.Request().(*http.Request); ok {
			return req.Header
		}
	}
	return nil
}

func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context {
	c := appengine.NewContext(req)
	return withContext(parent, c)
}

type testingContext struct {
	appengine.Context

	req *http.Request
}

func (t *testingContext) FullyQualifiedAppID() string { return "dev~testcontext" }
func (t *testingContext) Call(service, method string, _, _ appengine_internal.ProtoMessage, _ *appengine_internal.CallOptions) error {
	if service == "__go__" && method == "GetNamespace" {
		return nil
	}
	return fmt.Errorf("testingContext: unsupported Call")
}
func (t *testingContext) Request() interface{} { return t.req }

func ContextForTesting(req *http.Request) netcontext.Context {
	return withContext(netcontext.Background(), &testingContext{req: req})
}

func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error {
	if ns := NamespaceFromContext(ctx); ns != "" {
		if fn, ok := NamespaceMods[service]; ok {
			fn(in, ns)
		}
	}

	if f, ctx, ok := callOverrideFromContext(ctx); ok {
		return f(ctx, service, method, in, out)
	}

	// Handle already-done contexts quickly.
	select {
	case <-ctx.Done():
		return ctx.Err()
	default:
	}

	c := fromContext(ctx)
	if c == nil {
		// Give a good error message rather than a panic lower down.
		return errors.New("not an App Engine context")
	}

	// Apply transaction modifications if we're in a transaction.
	if t := transactionFromContext(ctx); t != nil {
		if t.finished {
			return errors.New("transaction context has expired")
		}
		applyTransaction(in, &t.transaction)
	}

	var opts *appengine_internal.CallOptions
	if d, ok := ctx.Deadline(); ok {
		opts = &appengine_internal.CallOptions{
			Timeout: d.Sub(time.Now()),
		}
	}

	err := c.Call(service, method, in, out, opts)
	switch v := err.(type) {
	case *appengine_internal.APIError:
		return &APIError{
			Service: v.Service,
			Detail:  v.Detail,
			Code:    v.Code,
		}
	case *appengine_internal.CallError:
		return &CallError{
			Detail:  v.Detail,
			Code:    v.Code,
			Timeout: v.Timeout,
		}
	}
	return err
}

func handleHTTP(w http.ResponseWriter, r *http.Request) {
	panic("handleHTTP called; this should be impossible")
}

func logf(c appengine.Context, level int64, format string, args ...interface{}) {
	var fn func(format string, args ...interface{})
	switch level {
	case 0:
		fn = c.Debugf
	case 1:
		fn = c.Infof
	case 2:
		fn = c.Warningf
	case 3:
		fn = c.Errorf
	case 4:
		fn = c.Criticalf
	default:
		// This shouldn't happen.
		fn = c.Criticalf
	}
	fn(format, args...)
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build !appengine

package internal

import (
	"io"
	"log"
	"net/http"
	"net/url"
	"os"
)

func Main() {
	installHealthChecker(http.DefaultServeMux)

	port := "8080"
	if s := os.Getenv("PORT"); s != "" {
		port = s
	}

	if err := http.ListenAndServe(":"+port, http.HandlerFunc(handleHTTP)); err != nil {
		log.Fatalf("http.ListenAndServe: %v", err)
	}
}

func installHealthChecker(mux *http.ServeMux) {
	// If no health check handler has been installed by this point, add a trivial one.
	const healthPath = "/_ah/health"
	hreq := &http.Request{
		Method: "GET",
		URL: &url.URL{
			Path: healthPath,
		},
	}
	if _, pat := mux.Handler(hreq); pat != healthPath {
		mux.HandleFunc(healthPath, func(w http.ResponseWriter, r *http.Request) {
			io.WriteString(w, "ok")
		})
	}
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build !appengine

package internal

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/url"
	"os"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/golang/protobuf/proto"
	netcontext "golang.org/x/net/context"

	basepb "google.golang.org/appengine/internal/base"
	logpb "google.golang.org/appengine/internal/log"
	remotepb "google.golang.org/appengine/internal/remote_api"
)

const (
	apiPath = "/rpc_http"
)

var (
	// Incoming headers.
	ticketHeader       = http.CanonicalHeaderKey("X-AppEngine-API-Ticket")
	dapperHeader       = http.CanonicalHeaderKey("X-Google-DapperTraceInfo")
	traceHeader        = http.CanonicalHeaderKey("X-Cloud-Trace-Context")
	curNamespaceHeader = http.CanonicalHeaderKey("X-AppEngine-Current-Namespace")
	userIPHeader       = http.CanonicalHeaderKey("X-AppEngine-User-IP")
	remoteAddrHeader   = http.CanonicalHeaderKey("X-AppEngine-Remote-Addr")

	// Outgoing headers.
	apiEndpointHeader      = http.CanonicalHeaderKey("X-Google-RPC-Service-Endpoint")
	apiEndpointHeaderValue = []string{"app-engine-apis"}
	apiMethodHeader        = http.CanonicalHeaderKey("X-Google-RPC-Service-Method")
	apiMethodHeaderValue   = []string{"/VMRemoteAPI.CallRemoteAPI"}
	apiDeadlineHeader      = http.CanonicalHeaderKey("X-Google-RPC-Service-Deadline")
	apiContentType         = http.CanonicalHeaderKey("Content-Type")
	apiContentTypeValue    = []string{"application/octet-stream"}
	logFlushHeader         = http.CanonicalHeaderKey("X-AppEngine-Log-Flush-Count")

	apiHTTPClient = &http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			Dial:  limitDial,
		},
	}
)

func apiURL() *url.URL {
	host, port := "appengine.googleapis.internal", "10001"
	if h := os.Getenv("API_HOST"); h != "" {
		host = h
	}
	if p := os.Getenv("API_PORT"); p != "" {
		port = p
	}
	return &url.URL{
		Scheme: "http",
		Host:   host + ":" + port,
		Path:   apiPath,
	}
}

func handleHTTP(w http.ResponseWriter, r *http.Request) {
	c := &context{
		req:       r,
		outHeader: w.Header(),
		apiURL:    apiURL(),
	}
	stopFlushing := make(chan int)

	ctxs.Lock()
	ctxs.m[r] = c
	ctxs.Unlock()
	defer func() {
		ctxs.Lock()
		delete(ctxs.m, r)
		ctxs.Unlock()
	}()

	// Patch up RemoteAddr so it looks reasonable.
	if addr := r.Header.Get(userIPHeader); addr != "" {
		r.RemoteAddr = addr
	} else if addr = r.Header.Get(remoteAddrHeader); addr != "" {
		r.RemoteAddr = addr
	} else {
		// Should not normally reach here, but pick a sensible default anyway.
		r.RemoteAddr = "127.0.0.1"
	}
	// The address in the headers will most likely be of these forms:
	//	123.123.123.123
	//	2001:db8::1
	// net/http.Request.RemoteAddr is specified to be in "IP:port" form.
	if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil {
		// Assume the remote address is only a host; add a default port.
		r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80")
	}

	// Start goroutine responsible for flushing app logs.
	// This is done after adding c to ctx.m (and stopped before removing it)
	// because flushing logs requires making an API call.
	go c.logFlusher(stopFlushing)

	executeRequestSafely(c, r)
	c.outHeader = nil // make sure header changes aren't respected any more

	stopFlushing <- 1 // any logging beyond this point will be dropped

	// Flush any pending logs asynchronously.
	c.pendingLogs.Lock()
	flushes := c.pendingLogs.flushes
	if len(c.pendingLogs.lines) > 0 {
		flushes++
	}
	c.pendingLogs.Unlock()
	go c.flushLog(false)
	w.Header().Set(logFlushHeader, strconv.Itoa(flushes))

	// Avoid nil Write call if c.Write is never called.
	if c.outCode != 0 {
		w.WriteHeader(c.outCode)
	}
	if c.outBody != nil {
		w.Write(c.outBody)
	}
}

func executeRequestSafely(c *context, r *http.Request) {
	defer func() {
		if x := recover(); x != nil {
			logf(c, 4, "%s", renderPanic(x)) // 4 == critical
			c.outCode = 500
		}
	}()

	http.DefaultServeMux.ServeHTTP(c, r)
}

func renderPanic(x interface{}) string {
	buf := make([]byte, 16<<10) // 16 KB should be plenty
	buf = buf[:runtime.Stack(buf, false)]

	// Remove the first few stack frames:
	//   this func
	//   the recover closure in the caller
	// That will root the stack trace at the site of the panic.
	const (
		skipStart  = "internal.renderPanic"
		skipFrames = 2
	)
	start := bytes.Index(buf, []byte(skipStart))
	p := start
	for i := 0; i < skipFrames*2 && p+1 < len(buf); i++ {
		p = bytes.IndexByte(buf[p+1:], '\n') + p + 1
		if p < 0 {
			break
		}
	}
	if p >= 0 {
		// buf[start:p+1] is the block to remove.
		// Copy buf[p+1:] over buf[start:] and shrink buf.
		copy(buf[start:], buf[p+1:])
		buf = buf[:len(buf)-(p+1-start)]
	}

	// Add panic heading.
	head := fmt.Sprintf("panic: %v\n\n", x)
	if len(head) > len(buf) {
		// Extremely unlikely to happen.
		return head
	}
	copy(buf[len(head):], buf)
	copy(buf, head)

	return string(buf)
}

var ctxs = struct {
	sync.Mutex
	m  map[*http.Request]*context
	bg *context // background context, lazily initialized
	// dec is used by tests to decorate the netcontext.Context returned
	// for a given request. This allows tests to add overrides (such as
	// WithAppIDOverride) to the context. The map is nil outside tests.
	dec map[*http.Request]func(netcontext.Context) netcontext.Context
}{
	m: make(map[*http.Request]*context),
}

// context represents the context of an in-flight HTTP request.
// It implements the appengine.Context and http.ResponseWriter interfaces.
type context struct {
	req *http.Request

	outCode   int
	outHeader http.Header
	outBody   []byte

	pendingLogs struct {
		sync.Mutex
		lines   []*logpb.UserAppLogLine
		flushes int
	}

	apiURL *url.URL
}

var contextKey = "holds a *context"

func fromContext(ctx netcontext.Context) *context {
	c, _ := ctx.Value(&contextKey).(*context)
	return c
}

func withContext(parent netcontext.Context, c *context) netcontext.Context {
	ctx := netcontext.WithValue(parent, &contextKey, c)
	if ns := c.req.Header.Get(curNamespaceHeader); ns != "" {
		ctx = withNamespace(ctx, ns)
	}
	return ctx
}

func toContext(c *context) netcontext.Context {
	return withContext(netcontext.Background(), c)
}

func IncomingHeaders(ctx netcontext.Context) http.Header {
	if c := fromContext(ctx); c != nil {
		return c.req.Header
	}
	return nil
}

func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context {
	ctxs.Lock()
	c := ctxs.m[req]
	d := ctxs.dec[req]
	ctxs.Unlock()

	if d != nil {
		parent = d(parent)
	}

	if c == nil {
		// Someone passed in an http.Request that is not in-flight.
		// We panic here rather than panicking at a later point
		// so that stack traces will be more sensible.
		log.Panic("appengine: NewContext passed an unknown http.Request")
	}
	return withContext(parent, c)
}

func BackgroundContext() netcontext.Context {
	ctxs.Lock()
	defer ctxs.Unlock()

	if ctxs.bg != nil {
		return toContext(ctxs.bg)
	}

	// Compute background security ticket.
	appID := partitionlessAppID()
	escAppID := strings.Replace(strings.Replace(appID, ":", "_", -1), ".", "_", -1)
	majVersion := VersionID(nil)
	if i := strings.Index(majVersion, "."); i > 0 {
		majVersion = majVersion[:i]
	}
	ticket := fmt.Sprintf("%s/%s.%s.%s", escAppID, ModuleName(nil), majVersion, InstanceID())

	ctxs.bg = &context{
		req: &http.Request{
			Header: http.Header{
				ticketHeader: []string{ticket},
			},
		},
		apiURL: apiURL(),
	}

	// TODO(dsymonds): Wire up the shutdown handler to do a final flush.
	go ctxs.bg.logFlusher(make(chan int))

	return toContext(ctxs.bg)
}

// RegisterTestRequest registers the HTTP request req for testing, such that
// any API calls are sent to the provided URL. It returns a closure to delete
// the registration.
// It should only be used by aetest package.
func RegisterTestRequest(req *http.Request, apiURL *url.URL, decorate func(netcontext.Context) netcontext.Context) func() {
	c := &context{
		req:    req,
		apiURL: apiURL,
	}
	ctxs.Lock()
	defer ctxs.Unlock()
	if _, ok := ctxs.m[req]; ok {
		log.Panic("req already associated with context")
	}
	if _, ok := ctxs.dec[req]; ok {
		log.Panic("req already associated with context")
	}
	if ctxs.dec == nil {
		ctxs.dec = make(map[*http.Request]func(netcontext.Context) netcontext.Context)
	}
	ctxs.m[req] = c
	ctxs.dec[req] = decorate

	return func() {
		ctxs.Lock()
		delete(ctxs.m, req)
		delete(ctxs.dec, req)
		ctxs.Unlock()
	}
}

var errTimeout = &CallError{
	Detail:  "Deadline exceeded",
	Code:    int32(remotepb.RpcError_CANCELLED),
	Timeout: true,
}

func (c *context) Header() http.Header { return c.outHeader }

// Copied from $GOROOT/src/pkg/net/http/transfer.go. Some response status
// codes do not permit a response body (nor response entity headers such as
// Content-Length, Content-Type, etc).
func bodyAllowedForStatus(status int) bool {
	switch {
	case status >= 100 && status <= 199:
		return false
	case status == 204:
		return false
	case status == 304:
		return false
	}
	return true
}

func (c *context) Write(b []byte) (int, error) {
	if c.outCode == 0 {
		c.WriteHeader(http.StatusOK)
	}
	if len(b) > 0 && !bodyAllowedForStatus(c.outCode) {
		return 0, http.ErrBodyNotAllowed
	}
	c.outBody = append(c.outBody, b...)
	return len(b), nil
}

func (c *context) WriteHeader(code int) {
	if c.outCode != 0 {
		logf(c, 3, "WriteHeader called multiple times on request.") // error level
		return
	}
	c.outCode = code
}

func (c *context) post(body []byte, timeout time.Duration) (b []byte, err error) {
	hreq := &http.Request{
		Method: "POST",
		URL:    c.apiURL,
		Header: http.Header{
			apiEndpointHeader: apiEndpointHeaderValue,
			apiMethodHeader:   apiMethodHeaderValue,
			apiContentType:    apiContentTypeValue,
			apiDeadlineHeader: []string{strconv.FormatFloat(timeout.Seconds(), 'f', -1, 64)},
		},
		Body:          ioutil.NopCloser(bytes.NewReader(body)),
		ContentLength: int64(len(body)),
		Host:          c.apiURL.Host,
	}
	if info := c.req.Header.Get(dapperHeader); info != "" {
		hreq.Header.Set(dapperHeader, info)
	}
	if info := c.req.Header.Get(traceHeader); info != "" {
		hreq.Header.Set(traceHeader, info)
	}

	tr := apiHTTPClient.Transport.(*http.Transport)

	var timedOut int32 // atomic; set to 1 if timed out
	t := time.AfterFunc(timeout, func() {
		atomic.StoreInt32(&timedOut, 1)
		tr.CancelRequest(hreq)
	})
	defer t.Stop()
	defer func() {
		// Check if timeout was exceeded.
		if atomic.LoadInt32(&timedOut) != 0 {
			err = errTimeout
		}
	}()

	hresp, err := apiHTTPClient.Do(hreq)
	if err != nil {
		return nil, &CallError{
			Detail: fmt.Sprintf("service bridge HTTP failed: %v", err),
			Code:   int32(remotepb.RpcError_UNKNOWN),
		}
	}
	defer hresp.Body.Close()
	hrespBody, err := ioutil.ReadAll(hresp.Body)
	if hresp.StatusCode != 200 {
		return nil, &CallError{
			Detail: fmt.Sprintf("service bridge returned HTTP %d (%q)", hresp.StatusCode, hrespBody),
			Code:   int32(remotepb.RpcError_UNKNOWN),
		}
	}
	if err != nil {
		return nil, &CallError{
			Detail: fmt.Sprintf("service bridge response bad: %v", err),
			Code:   int32(remotepb.RpcError_UNKNOWN),
		}
	}
	return hrespBody, nil
}

func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error {
	if ns := NamespaceFromContext(ctx); ns != "" {
		if fn, ok := NamespaceMods[service]; ok {
			fn(in, ns)
		}
	}

	if f, ctx, ok := callOverrideFromContext(ctx); ok {
		return f(ctx, service, method, in, out)
	}

	// Handle already-done contexts quickly.
	select {
	case <-ctx.Done():
		return ctx.Err()
	default:
	}

	c := fromContext(ctx)
	if c == nil {
		// Give a good error message rather than a panic lower down.
		return errors.New("not an App Engine context")
	}

	// Apply transaction modifications if we're in a transaction.
	if t := transactionFromContext(ctx); t != nil {
		if t.finished {
			return errors.New("transaction context has expired")
		}
		applyTransaction(in, &t.transaction)
	}

	// Default RPC timeout is 60s.
	timeout := 60 * time.Second
	if deadline, ok := ctx.Deadline(); ok {
		timeout = deadline.Sub(time.Now())
	}

	data, err := proto.Marshal(in)
	if err != nil {
		return err
	}

	ticket := c.req.Header.Get(ticketHeader)
	req := &remotepb.Request{
		ServiceName: &service,
		Method:      &method,
		Request:     data,
		RequestId:   &ticket,
	}
	hreqBody, err := proto.Marshal(req)
	if err != nil {
		return err
	}

	hrespBody, err := c.post(hreqBody, timeout)
	if err != nil {
		return err
	}

	res := &remotepb.Response{}
	if err := proto.Unmarshal(hrespBody, res); err != nil {
		return err
	}
	if res.RpcError != nil {
		ce := &CallError{
			Detail: res.RpcError.GetDetail(),
			Code:   *res.RpcError.Code,
		}
		switch remotepb.RpcError_ErrorCode(ce.Code) {
		case remotepb.RpcError_CANCELLED, remotepb.RpcError_DEADLINE_EXCEEDED:
			ce.Timeout = true
		}
		return ce
	}
	if res.ApplicationError != nil {
		return &APIError{
			Service: *req.ServiceName,
			Detail:  res.ApplicationError.GetDetail(),
			Code:    *res.ApplicationError.Code,
		}
	}
	if res.Exception != nil || res.JavaException != nil {
		// This shouldn't happen, but let's be defensive.
		return &CallError{
			Detail: "service bridge returned exception",
			Code:   int32(remotepb.RpcError_UNKNOWN),
		}
	}
	return proto.Unmarshal(res.Response, out)
}

func (c *context) Request() *http.Request {
	return c.req
}

func (c *context) addLogLine(ll *logpb.UserAppLogLine) {
	// Truncate long log lines.
	// TODO(dsymonds): Check if this is still necessary.
	const lim = 8 << 10
	if len(*ll.Message) > lim {
		suffix := fmt.Sprintf("...(length %d)", len(*ll.Message))
		ll.Message = proto.String((*ll.Message)[:lim-len(suffix)] + suffix)
	}

	c.pendingLogs.Lock()
	c.pendingLogs.lines = append(c.pendingLogs.lines, ll)
	c.pendingLogs.Unlock()
}

var logLevelName = map[int64]string{
	0: "DEBUG",
	1: "INFO",
	2: "WARNING",
	3: "ERROR",
	4: "CRITICAL",
}

func logf(c *context, level int64, format string, args ...interface{}) {
	s := fmt.Sprintf(format, args...)
	s = strings.TrimRight(s, "\n") // Remove any trailing newline characters.
	c.addLogLine(&logpb.UserAppLogLine{
		TimestampUsec: proto.Int64(time.Now().UnixNano() / 1e3),
		Level:         &level,
		Message:       &s,
	})
	log.Print(logLevelName[level] + ": " + s)
}

// flushLog attempts to flush any pending logs to the appserver.
// It should not be called concurrently.
func (c *context) flushLog(force bool) (flushed bool) {
	c.pendingLogs.Lock()
	// Grab up to 30 MB. We can get away with up to 32 MB, but let's be cautious.
	n, rem := 0, 30<<20
	for ; n < len(c.pendingLogs.lines); n++ {
		ll := c.pendingLogs.lines[n]
		// Each log line will require about 3 bytes of overhead.
		nb := proto.Size(ll) + 3
		if nb > rem {
			break
		}
		rem -= nb
	}
	lines := c.pendingLogs.lines[:n]
	c.pendingLogs.lines = c.pendingLogs.lines[n:]
	c.pendingLogs.Unlock()

	if len(lines) == 0 && !force {
		// Nothing to flush.
		return false
	}

	rescueLogs := false
	defer func() {
		if rescueLogs {
			c.pendingLogs.Lock()
			c.pendingLogs.lines = append(lines, c.pendingLogs.lines...)
			c.pendingLogs.Unlock()
		}
	}()

	buf, err := proto.Marshal(&logpb.UserAppLogGroup{
		LogLine: lines,
	})
	if err != nil {
		log.Printf("internal.flushLog: marshaling UserAppLogGroup: %v", err)
		rescueLogs = true
		return false
	}

	req := &logpb.FlushRequest{
		Logs: buf,
	}
	res := &basepb.VoidProto{}
	c.pendingLogs.Lock()
	c.pendingLogs.flushes++
	c.pendingLogs.Unlock()
	if err := Call(toContext(c), "logservice", "Flush", req, res); err != nil {
		log.Printf("internal.flushLog: Flush RPC: %v", err)
		rescueLogs = true
		return false
	}
	return true
}

const (
	// Log flushing parameters.
	flushInterval      = 1 * time.Second
	forceFlushInterval = 60 * time.Second
)

func (c *context) logFlusher(stop <-chan int) {
	lastFlush := time.Now()
	tick := time.NewTicker(flushInterval)
	for {
		select {
		case <-stop:
			// Request finished.
			tick.Stop()
			return
		case <-tick.C:
			force := time.Now().Sub(lastFlush) > forceFlushInterval
			if c.flushLog(force) {
				lastFlush = time.Now()
			}
		}
	}
}

func ContextForTesting(req *http.Request) netcontext.Context {
	return toContext(&context{req: req})
}


text:
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package internal

// This file implements hooks for applying datastore transactions.

import (
	"errors"
	"reflect"

	"github.com/golang/protobuf/proto"
	netcontext "golang.org/x/net/context"

	basepb "google.golang.org/appengine/internal/base"
	pb "google.golang.org/appengine/internal/datastore"
)

var transactionSetters = make(map[reflect.Type]reflect.Value)

// RegisterTransactionSetter registers a function that sets transaction information
// in a protocol buffer message. f should be a function with two arguments,
// the first being a protocol buffer type, and the second being *datastore.Transaction.
func RegisterTransactionSetter(f interface{}) {
	v := reflect.ValueOf(f)
	transactionSetters[v.Type().In(0)] = v
}

// applyTransaction applies the transaction t to message pb
// by using the relevant setter passed to RegisterTransactionSetter.
func applyTransaction(pb proto.Message, t *pb.Transaction) {
	v := reflect.ValueOf(pb)
	if f, ok := transactionSetters[v.Type()]; ok {
		f.Call([]reflect.Value{v, reflect.ValueOf(t)})
	}
}

var transactionKey = "used for *Transaction"

func transactionFromContext(ctx netcontext.Context) *transaction {
	t, _ := ctx.Value(&transactionKey).(*transaction)
	return t
}

func withTransaction(ctx netcontext.Context, t *transaction) netcontext.Context {
	return netcontext.WithValue(ctx, &transactionKey, t)
}

type transaction struct {
	transaction pb.Transaction
	finished    bool
}

var ErrConcurrentTransaction = errors.New("internal: concurrent transaction")

func RunTransactionOnce(c netcontext.Context, f func(netcontext.Context) error, xg bool) error {
	if transactionFromContext(c) != nil {
		return errors.New("nested transactions are not supported")
	}

	// Begin the transaction.
	t := &transaction{}
	req := &pb.BeginTransactionRequest{
		App: proto.String(FullyQualifiedAppID(c)),
	}
	if xg {
		req.AllowMultipleEg = proto.Bool(true)
	}
	if err := Call(c, "datastore_v3", "BeginTransaction", req, &t.transaction); err != nil {
		return err
	}

	// Call f, rolling back the transaction if f returns a non-nil error, or panics.
	// The panic is not recovered.
	defer func() {
		if t.finished {
			return
		}
		t.finished = true
		// Ignore the error return value, since we are already returning a non-nil
		// error (or we're panicking).
		Call(c, "datastore_v3", "Rollback", &t.transaction, &basepb.VoidProto{})
	}()
	if err := f(withTransaction(c, t)); err != nil {
		return err
	}
	t.finished = true

	// Commit the transaction.
	res := &pb.CommitResponse{}
	err := Call(c, "datastore_v3", "Commit", &t.transaction, res)
	if ae, ok := err.(*APIError); ok {
		/* TODO: restore this conditional
		if appengine.IsDevAppServer() {
		*/
		// The Python Dev AppServer raises an ApplicationError with error code 2 (which is
		// Error.CONCURRENT_TRANSACTION) and message "Concurrency exception.".
		if ae.Code == int32(pb.Error_BAD_REQUEST) && ae.Detail == "ApplicationError: 2 Concurrency exception." {
			return ErrConcurrentTransaction
		}
		if ae.Code == int32(pb.Error_CONCURRENT_TRANSACTION) {
			return ErrConcurrentTransaction
		}
	}
	return err
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package internal

import (
	"strings"
)

func parseFullAppID(appid string) (partition, domain, displayID string) {
	if i := strings.Index(appid, "~"); i != -1 {
		partition, appid = appid[:i], appid[i+1:]
	}
	if i := strings.Index(appid, ":"); i != -1 {
		domain, appid = appid[:i], appid[i+1:]
	}
	return partition, domain, appid
}

// appID returns "appid" or "domain.com:appid".
func appID(fullAppID string) string {
	_, dom, dis := parseFullAppID(fullAppID)
	if dom != "" {
		return dom + ":" + dis
	}
	return dis
}


text:
// Copyright 2011 Google Inc. All Rights Reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package internal

import (
	"testing"
)

func TestAppIDParsing(t *testing.T) {
	testCases := []struct {
		in                           string
		partition, domain, displayID string
	}{
		{"simple-app-id", "", "", "simple-app-id"},
		{"domain.com:domain-app-id", "", "domain.com", "domain-app-id"},
		{"part~partition-app-id", "part", "", "partition-app-id"},
		{"part~domain.com:display", "part", "domain.com", "display"},
	}

	for _, tc := range testCases {
		part, dom, dis := parseFullAppID(tc.in)
		if part != tc.partition {
			t.Errorf("partition of %q: got %q, want %q", tc.in, part, tc.partition)
		}
		if dom != tc.domain {
			t.Errorf("domain of %q: got %q, want %q", tc.in, dom, tc.domain)
		}
		if dis != tc.displayID {
			t.Errorf("displayID of %q: got %q, want %q", tc.in, dis, tc.displayID)
		}
	}
}


text:
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build !appengine

package internal

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"os/exec"
	"strings"
	"sync/atomic"
	"testing"
	"time"

	"github.com/golang/protobuf/proto"
	netcontext "golang.org/x/net/context"

	basepb "google.golang.org/appengine/internal/base"
	remotepb "google.golang.org/appengine/internal/remote_api"
)

const testTicketHeader = "X-Magic-Ticket-Header"

func init() {
	ticketHeader = testTicketHeader
}

type fakeAPIHandler struct {
	hang chan int // used for RunSlowly RPC

	LogFlushes int32 // atomic
}

func (f *fakeAPIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	writeResponse := func(res *remotepb.Response) {
		hresBody, err := proto.Marshal(res)
		if err != nil {
			http.Error(w, fmt.Sprintf("Failed encoding API response: %v", err), 500)
			return
		}
		w.Write(hresBody)
	}

	if r.URL.Path != "/rpc_http" {
		http.NotFound(w, r)
		return
	}
	hreqBody, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, fmt.Sprintf("Bad body: %v", err), 500)
		return
	}
	apiReq := &remotepb.Request{}
	if err := proto.Unmarshal(hreqBody, apiReq); err != nil {
		http.Error(w, fmt.Sprintf("Bad encoded API request: %v", err), 500)
		return
	}
	if *apiReq.RequestId != "s3cr3t" {
		writeResponse(&remotepb.Response{
			RpcError: &remotepb.RpcError{
				Code:   proto.Int32(int32(remotepb.RpcError_SECURITY_VIOLATION)),
				Detail: proto.String("bad security ticket"),
			},
		})
		return
	}
	if got, want := r.Header.Get(dapperHeader), "trace-001"; got != want {
		writeResponse(&remotepb.Response{
			RpcError: &remotepb.RpcError{
				Code:   proto.Int32(int32(remotepb.RpcError_BAD_REQUEST)),
				Detail: proto.String(fmt.Sprintf("trace info = %q, want %q", got, want)),
			},
		})
		return
	}

	service, method := *apiReq.ServiceName, *apiReq.Method
	var resOut proto.Message
	if service == "actordb" && method == "LookupActor" {
		req := &basepb.StringProto{}
		res := &basepb.StringProto{}
		if err := proto.Unmarshal(apiReq.Request, req); err != nil {
			http.Error(w, fmt.Sprintf("Bad encoded request: %v", err), 500)
			return
		}
		if *req.Value == "Doctor Who" {
			res.Value = proto.String("David Tennant")
		}
		resOut = res
	}
	if service == "errors" {
		switch method {
		case "Non200":
			http.Error(w, "I'm a little teapot.", 418)
			return
		case "ShortResponse":
			w.Header().Set("Content-Length", "100")
			w.Write([]byte("way too short"))
			return
		case "OverQuota":
			writeResponse(&remotepb.Response{
				RpcError: &remotepb.RpcError{
					Code:   proto.Int32(int32(remotepb.RpcError_OVER_QUOTA)),
					Detail: proto.String("you are hogging the resources!"),
				},
			})
			return
		case "RunSlowly":
			// TestAPICallRPCFailure creates f.hang, but does not strobe it
			// until Call returns with remotepb.RpcError_CANCELLED.
			// This is here to force a happens-before relationship between
			// the httptest server handler and shutdown.
			<-f.hang
			resOut = &basepb.VoidProto{}
		}
	}
	if service == "logservice" && method == "Flush" {
		// Pretend log flushing is slow.
		time.Sleep(50 * time.Millisecond)
		atomic.AddInt32(&f.LogFlushes, 1)
		resOut = &basepb.VoidProto{}
	}

	encOut, err := proto.Marshal(resOut)
	if err != nil {
		http.Error(w, fmt.Sprintf("Failed encoding response: %v", err), 500)
		return
	}
	writeResponse(&remotepb.Response{
		Response: encOut,
	})
}

func setup() (f *fakeAPIHandler, c *context, cleanup func()) {
	f = &fakeAPIHandler{}
	srv := httptest.NewServer(f)
	u, err := url.Parse(srv.URL + apiPath)
	if err != nil {
		panic(fmt.Sprintf("url.Parse(%q): %v", srv.URL+apiPath, err))
	}
	return f, &context{
		req: &http.Request{
			Header: http.Header{
				ticketHeader: []string{"s3cr3t"},
				dapperHeader: []string{"trace-001"},
			},
		},
		apiURL: u,
	}, srv.Close
}

func TestAPICall(t *testing.T) {
	_, c, cleanup := setup()
	defer cleanup()

	req := &basepb.StringProto{
		Value: proto.String("Doctor Who"),
	}
	res := &basepb.StringProto{}
	err := Call(toContext(c), "actordb", "LookupActor", req, res)
	if err != nil {
		t.Fatalf("API call failed: %v", err)
	}
	if got, want := *res.Value, "David Tennant"; got != want {
		t.Errorf("Response is %q, want %q", got, want)
	}
}

func TestAPICallRPCFailure(t *testing.T) {
	f, c, cleanup := setup()
	defer cleanup()

	testCases := []struct {
		method string
		code   remotepb.RpcError_ErrorCode
	}{
		{"Non200", remotepb.RpcError_UNKNOWN},
		{"ShortResponse", remotepb.RpcError_UNKNOWN},
		{"OverQuota", remotepb.RpcError_OVER_QUOTA},
		{"RunSlowly", remotepb.RpcError_CANCELLED},
	}
	f.hang = make(chan int) // only for RunSlowly
	for _, tc := range testCases {
		ctx, _ := netcontext.WithTimeout(toContext(c), 100*time.Millisecond)
		err := Call(ctx, "errors", tc.method, &basepb.VoidProto{}, &basepb.VoidProto{})
		ce, ok := err.(*CallError)
		if !ok {
			t.Errorf("%s: API call error is %T (%v), want *CallError", tc.method, err, err)
			continue
		}
		if ce.Code != int32(tc.code) {
			t.Errorf("%s: ce.Code = %d, want %d", tc.method, ce.Code, tc.code)
		}
		if tc.method == "RunSlowly" {
			f.hang <- 1 // release the HTTP handler
		}
	}
}

func TestAPICallDialFailure(t *testing.T) {
	// See what happens if the API host is unresponsive.
	// This should time out quickly, not hang forever.
	_, c, cleanup := setup()
	defer cleanup()
	// Reset the URL to the production address so that dialing fails.
	c.apiURL = apiURL()

	start := time.Now()
	err := Call(toContext(c), "foo", "bar", &basepb.VoidProto{}, &basepb.VoidProto{})
	const max = 1 * time.Second
	if taken := time.Since(start); taken > max {
		t.Errorf("Dial hang took too long: %v > %v", taken, max)
	}
	if err == nil {
		t.Error("Call did not fail")
	}
}

func TestDelayedLogFlushing(t *testing.T) {
	f, c, cleanup := setup()
	defer cleanup()

	http.HandleFunc("/quick_log", func(w http.ResponseWriter, r *http.Request) {
		logC := WithContext(netcontext.Background(), r)
		fromContext(logC).apiURL = c.apiURL // Otherwise it will try to use the default URL.
		Logf(logC, 1, "It's a lovely day.")
		w.WriteHeader(200)
		w.Write(make([]byte, 100<<10)) // write 100 KB to force HTTP flush
	})

	r := &http.Request{
		Method: "GET",
		URL: &url.URL{
			Scheme: "http",
			Path:   "/quick_log",
		},
		Header: c.req.Header,
		Body:   ioutil.NopCloser(bytes.NewReader(nil)),
	}
	w := httptest.NewRecorder()

	// Check that log flushing does not hold up the HTTP response.
	start := time.Now()
	handleHTTP(w, r)
	if d := time.Since(start); d > 10*time.Millisecond {
		t.Errorf("handleHTTP took %v, want under 10ms", d)
	}
	const hdr = "X-AppEngine-Log-Flush-Count"
	if h := w.HeaderMap.Get(hdr); h != "1" {
		t.Errorf("%s header = %q, want %q", hdr, h, "1")
	}
	if f := atomic.LoadInt32(&f.LogFlushes); f != 0 {
		t.Errorf("After HTTP response: f.LogFlushes = %d, want 0", f)
	}

	// Check that the log flush eventually comes in.
	time.Sleep(100 * time.Millisecond)
	if f := atomic.LoadInt32(&f.LogFlushes); f != 1 {
		t.Errorf("After 100ms: f.LogFlushes = %d, want 1", f)
	}
}

func TestRemoteAddr(t *testing.T) {
	var addr string
	http.HandleFunc("/remote_addr", func(w http.ResponseWriter, r *http.Request) {
		addr = r.RemoteAddr
	})

	testCases := []struct {
		headers http.Header
		addr    string
	}{
		{http.Header{"X-Appengine-User-Ip": []string{"10.5.2.1"}}, "10.5.2.1:80"},
		{http.Header{"X-Appengine-Remote-Addr": []string{"1.2.3.4"}}, "1.2.3.4:80"},
		{http.Header{"X-Appengine-Remote-Addr": []string{"1.2.3.4:8080"}}, "1.2.3.4:8080"},
		{
			http.Header{"X-Appengine-Remote-Addr": []string{"2401:fa00:9:1:7646:a0ff:fe90:ca66"}},
			"[2401:fa00:9:1:7646:a0ff:fe90:ca66]:80",
		},
		{
			http.Header{"X-Appengine-Remote-Addr": []string{"[::1]:http"}},
			"[::1]:http",
		},
		{http.Header{}, "127.0.0.1:80"},
	}

	for _, tc := range testCases {
		r := &http.Request{
			Method: "GET",
			URL:    &url.URL{Scheme: "http", Path: "/remote_addr"},
			Header: tc.headers,
			Body:   ioutil.NopCloser(bytes.NewReader(nil)),
		}
		handleHTTP(httptest.NewRecorder(), r)
		if addr != tc.addr {
			t.Errorf("Header %v, got %q, want %q", tc.headers, addr, tc.addr)
		}
	}
}

func TestPanickingHandler(t *testing.T) {
	http.HandleFunc("/panic", func(http.ResponseWriter, *http.Request) {
		panic("whoops!")
	})
	r := &http.Request{
		Method: "GET",
		URL:    &url.URL{Scheme: "http", Path: "/panic"},
		Body:   ioutil.NopCloser(bytes.NewReader(nil)),
	}
	rec := httptest.NewRecorder()
	handleHTTP(rec, r)
	if rec.Code != 500 {
		t.Errorf("Panicking handler returned HTTP %d, want HTTP %d", rec.Code, 500)
	}
}

var raceDetector = false

func TestAPICallAllocations(t *testing.T) {
	if raceDetector {
		t.Skip("not running under race detector")
	}

	// Run the test API server in a subprocess so we aren't counting its allocations.
	u, cleanup := launchHelperProcess(t)
	defer cleanup()
	c := &context{
		req: &http.Request{
			Header: http.Header{
				ticketHeader: []string{"s3cr3t"},
				dapperHeader: []string{"trace-001"},
			},
		},
		apiURL: u,
	}

	req := &basepb.StringProto{
		Value: proto.String("Doctor Who"),
	}
	res := &basepb.StringProto{}
	var apiErr error
	avg := testing.AllocsPerRun(100, func() {
		ctx, _ := netcontext.WithTimeout(toContext(c), 100*time.Millisecond)
		if err := Call(ctx, "actordb", "LookupActor", req, res); err != nil && apiErr == nil {
			apiErr = err // get the first error only
		}
	})
	if apiErr != nil {
		t.Errorf("API call failed: %v", apiErr)
	}

	// Lots of room for improvement...
	// TODO(djd): Reduce maximum to 85 once the App Engine SDK is based on 1.6.
	const min, max float64 = 70, 90
	if avg < min || max < avg {
		t.Errorf("Allocations per API call = %g, want in [%g,%g]", avg, min, max)
	}
}

func launchHelperProcess(t *testing.T) (apiURL *url.URL, cleanup func()) {
	cmd := exec.Command(os.Args[0], "-test.run=TestHelperProcess")
	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
	stdin, err := cmd.StdinPipe()
	if err != nil {
		t.Fatalf("StdinPipe: %v", err)
	}
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		t.Fatalf("StdoutPipe: %v", err)
	}
	if err := cmd.Start(); err != nil {
		t.Fatalf("Starting helper process: %v", err)
	}

	scan := bufio.NewScanner(stdout)
	var u *url.URL
	for scan.Scan() {
		line := scan.Text()
		if hp := strings.TrimPrefix(line, helperProcessMagic); hp != line {
			var err error
			u, err = url.Parse(hp)
			if err != nil {
				t.Fatalf("Failed to parse %q: %v", hp, err)
			}
			break
		}
	}
	if err := scan.Err(); err != nil {
		t.Fatalf("Scanning helper process stdout: %v", err)
	}
	if u == nil {
		t.Fatal("Helper process never reported")
	}

	return u, func() {
		stdin.Close()
		if err := cmd.Wait(); err != nil {
			t.Errorf("Helper process did not exit cleanly: %v", err)
		}
	}
}

const helperProcessMagic = "A lovely helper process is listening at "

// This isn't a real test. It's used as a helper process.
func TestHelperProcess(*testing.T) {
	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
		return
	}
	defer os.Exit(0)

	f := &fakeAPIHandler{}
	srv := httptest.NewServer(f)
	defer srv.Close()
	fmt.Println(helperProcessMagic + srv.URL + apiPath)

	// Wait for stdin to be closed.
	io.Copy(ioutil.Discard, os.Stdin)
}

func TestBackgroundContext(t *testing.T) {
	environ := []struct {
		key, value string
	}{
		{"GAE_LONG_APP_ID", "my-app-id"},
		{"GAE_MINOR_VERSION", "067924799508853122"},
		{"GAE_MODULE_INSTANCE", "0"},
		{"GAE_MODULE_NAME", "default"},
		{"GAE_MODULE_VERSION", "20150612t184001"},
	}
	for _, v := range environ {
		old := os.Getenv(v.key)
		os.Setenv(v.key, v.value)
		v.value = old
	}
	defer func() { // Restore old environment after the test completes.
		for _, v := range environ {
			if v.value == "" {
				os.Unsetenv(v.key)
				continue
			}
			os.Setenv(v.key, v.value)
		}
	}()

	ctx, key := fromContext(BackgroundContext()), "X-Magic-Ticket-Header"
	if g, w := ctx.req.Header.Get(key), "my-app-id/default.20150612t184001.0"; g != w {
		t.Errorf("%v = %q, want %q", key, g, w)
	}

	// Check that using the background context doesn't panic.
	req := &basepb.StringProto{
		Value: proto.String("Doctor Who"),
	}
	res := &basepb.StringProto{}
	Call(BackgroundContext(), "actordb", "LookupActor", req, res) // expected to fail
}


text:
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build !appengine

package internal

import (
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestInstallingHealthChecker(t *testing.T) {
	try := func(desc string, mux *http.ServeMux, wantCode int, wantBody string) {
		installHealthChecker(mux)
		srv := httptest.NewServer(mux)
		defer srv.Close()

		resp, err := http.Get(srv.URL + "/_ah/health")
		if err != nil {
			t.Errorf("%s: http.Get: %v", desc, err)
			return
		}
		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			t.Errorf("%s: reading body: %v", desc, err)
			return
		}

		if resp.StatusCode != wantCode {
			t.Errorf("%s: got HTTP %d, want %d", desc, resp.StatusCode, wantCode)
			return
		}
		if wantBody != "" && string(body) != wantBody {
			t.Errorf("%s: got HTTP body %q, want %q", desc, body, wantBody)
			return
		}
	}

	// If there's no handlers, or only a root handler, a health checker should be installed.
	try("empty mux", http.NewServeMux(), 200, "ok")
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		io.WriteString(w, "root handler")
	})
	try("mux with root handler", mux, 200, "ok")

	// If there's a custom health check handler, one should not be installed.
	mux = http.NewServeMux()
	mux.HandleFunc("/_ah/health", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(418)
		io.WriteString(w, "I'm short and stout!")
	})
	try("mux with custom health checker", mux, 418, "I'm short and stout!")
}


text:
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build race

package internal

func init() { raceDetector = true }


text:
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build !appengine

package internal

import (
	"sync"
	"testing"
	"time"

	netcontext "golang.org/x/net/context"

	basepb "google.golang.org/appengine/internal/base"
)

func TestDialLimit(t *testing.T) {
	// Fill up semaphore with false acquisitions to permit only two TCP connections at a time.
	// We don't replace limitSem because that results in a data race when net/http lazily closes connections.
	nFake := cap(limitSem) - 2
	for i := 0; i < nFake; i++ {
		limitSem <- 1
	}
	defer func() {
		for i := 0; i < nFake; i++ {
			<-limitSem
		}
	}()

	f, c, cleanup := setup() // setup is in api_test.go
	defer cleanup()
	f.hang = make(chan int)

	// If we make two RunSlowly RPCs (which will wait for f.hang to be strobed),
	// then the simple Non200 RPC should hang.
	var wg sync.WaitGroup
	wg.Add(2)
	for i := 0; i < 2; i++ {
		go func() {
			defer wg.Done()
			Call(toContext(c), "errors", "RunSlowly", &basepb.VoidProto{}, &basepb.VoidProto{})
		}()
	}
	time.Sleep(50 * time.Millisecond) // let those two RPCs start

	ctx, _ := netcontext.WithTimeout(toContext(c), 50*time.Millisecond)
	err := Call(ctx, "errors", "Non200", &basepb.VoidProto{}, &basepb.VoidProto{})
	if err != errTimeout {
		t.Errorf("Non200 RPC returned with err %v, want errTimeout", err)
	}

	// Drain the two RunSlowly calls.
	f.hang <- 1
	f.hang <- 1
	wg.Wait()
}


text:
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build appengine

package internal

import (
	"appengine"

	netcontext "golang.org/x/net/context"
)

func DefaultVersionHostname(ctx netcontext.Context) string {
	return appengine.DefaultVersionHostname(fromContext(ctx))
}

func RequestID(ctx netcontext.Context) string  { return appengine.RequestID(fromContext(ctx)) }
func Datacenter(_ netcontext.Context) string   { return appengine.Datacenter() }
func ServerSoftware() string                   { return appengine.ServerSoftware() }
func ModuleName(ctx netcontext.Context) string { return appengine.ModuleName(fromContext(ctx)) }
func VersionID(ctx netcontext.Context) string  { return appengine.VersionID(fromContext(ctx)) }
func InstanceID() string                       { return appengine.InstanceID() }
func IsDevAppServer() bool                     { return appengine.IsDevAppServer() }

func fullyQualifiedAppID(ctx netcontext.Context) string { return fromContext(ctx).FullyQualifiedAppID() }


text:
#!/bin/bash -e
#
# This script rebuilds the generated code for the protocol buffers.
# To run this you will need protoc and goprotobuf installed;
# see https://github.com/golang/protobuf for instructions.

PKG=google.golang.org/appengine

function die() {
	echo 1>&2 $*
	exit 1
}

# Sanity check that the right tools are accessible.
for tool in go protoc protoc-gen-go; do
	q=$(which $tool) || die "didn't find $tool"
	echo 1>&2 "$tool: $q"
done

echo -n 1>&2 "finding package dir... "
pkgdir=$(go list -f '{{.Dir}}' $PKG)
echo 1>&2 $pkgdir
base=$(echo $pkgdir | sed "s,/$PKG\$,,")
echo 1>&2 "base: $base"
cd $base

# Run protoc once per package.
for dir in $(find $PKG/internal -name '*.proto' | xargs dirname | sort | uniq); do
	echo 1>&2 "* $dir"
	protoc --go_out=. $dir/*.proto
done

for f in $(find $PKG/internal -name '*.pb.go'); do
  # Remove proto.RegisterEnum calls.
  # These cause duplicate registration panics when these packages
  # are used on classic App Engine. proto.RegisterEnum only affects
  # parsing the text format; we don't care about that.
  # https://code.google.com/p/googleappengine/issues/detail?id=11670#c17
  sed -i '/proto.RegisterEnum/d' $f
done


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build appengine

package internal

import (
	"appengine_internal"
)

func Main() {
	appengine_internal.Main()
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// Package internal provides support for package appengine.
//
// Programs should not use this package directly. Its API is not stable.
// Use packages appengine and appengine/* instead.
package internal

import (
	"fmt"

	"github.com/golang/protobuf/proto"

	remotepb "google.golang.org/appengine/internal/remote_api"
)

// errorCodeMaps is a map of service name to the error code map for the service.
var errorCodeMaps = make(map[string]map[int32]string)

// RegisterErrorCodeMap is called from API implementations to register their
// error code map. This should only be called from init functions.
func RegisterErrorCodeMap(service string, m map[int32]string) {
	errorCodeMaps[service] = m
}

type timeoutCodeKey struct {
	service string
	code    int32
}

// timeoutCodes is the set of service+code pairs that represent timeouts.
var timeoutCodes = make(map[timeoutCodeKey]bool)

func RegisterTimeoutErrorCode(service string, code int32) {
	timeoutCodes[timeoutCodeKey{service, code}] = true
}

// APIError is the type returned by appengine.Context's Call method
// when an API call fails in an API-specific way. This may be, for instance,
// a taskqueue API call failing with TaskQueueServiceError::UNKNOWN_QUEUE.
type APIError struct {
	Service string
	Detail  string
	Code    int32 // API-specific error code
}

func (e *APIError) Error() string {
	if e.Code == 0 {
		if e.Detail == "" {
			return "APIError <empty>"
		}
		return e.Detail
	}
	s := fmt.Sprintf("API error %d", e.Code)
	if m, ok := errorCodeMaps[e.Service]; ok {
		s += " (" + e.Service + ": " + m[e.Code] + ")"
	} else {
		// Shouldn't happen, but provide a bit more detail if it does.
		s = e.Service + " " + s
	}
	if e.Detail != "" {
		s += ": " + e.Detail
	}
	return s
}

func (e *APIError) IsTimeout() bool {
	return timeoutCodes[timeoutCodeKey{e.Service, e.Code}]
}

// CallError is the type returned by appengine.Context's Call method when an
// API call fails in a generic way, such as RpcError::CAPABILITY_DISABLED.
type CallError struct {
	Detail string
	Code   int32
	// TODO: Remove this if we get a distinguishable error code.
	Timeout bool
}

func (e *CallError) Error() string {
	var msg string
	switch remotepb.RpcError_ErrorCode(e.Code) {
	case remotepb.RpcError_UNKNOWN:
		return e.Detail
	case remotepb.RpcError_OVER_QUOTA:
		msg = "Over quota"
	case remotepb.RpcError_CAPABILITY_DISABLED:
		msg = "Capability disabled"
	case remotepb.RpcError_CANCELLED:
		msg = "Canceled"
	default:
		msg = fmt.Sprintf("Call error %d", e.Code)
	}
	s := msg + ": " + e.Detail
	if e.Timeout {
		s += " (timeout)"
	}
	return s
}

func (e *CallError) IsTimeout() bool {
	return e.Timeout
}

// NamespaceMods is a map from API service to a function that will mutate an RPC request to attach a namespace.
// The function should be prepared to be called on the same message more than once; it should only modify the
// RPC request the first time.
var NamespaceMods = make(map[string]func(m proto.Message, namespace string))


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package internal

import netcontext "golang.org/x/net/context"

// These functions are implementations of the wrapper functions
// in ../appengine/identity.go. See that file for commentary.

func AppID(c netcontext.Context) string {
	return appID(FullyQualifiedAppID(c))
}


text:
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package internal

// This file implements a network dialer that limits the number of concurrent connections.
// It is only used for API calls.

import (
	"log"
	"net"
	"runtime"
	"sync"
	"time"
)

var limitSem = make(chan int, 100) // TODO(dsymonds): Use environment variable.

func limitRelease() {
	// non-blocking
	select {
	case <-limitSem:
	default:
		// This should not normally happen.
		log.Print("appengine: unbalanced limitSem release!")
	}
}

func limitDial(network, addr string) (net.Conn, error) {
	limitSem <- 1

	// Dial with a timeout in case the API host is MIA.
	// The connection should normally be very fast.
	conn, err := net.DialTimeout(network, addr, 500*time.Millisecond)
	if err != nil {
		limitRelease()
		return nil, err
	}
	lc := &limitConn{Conn: conn}
	runtime.SetFinalizer(lc, (*limitConn).Close) // shouldn't usually be required
	return lc, nil
}

type limitConn struct {
	close sync.Once
	net.Conn
}

func (lc *limitConn) Close() error {
	defer lc.close.Do(func() {
		limitRelease()
		runtime.SetFinalizer(lc, nil)
	})
	return lc.Conn.Close()
}


text:
// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package internal

// This file has code for accessing metadata.
//
// References:
//	https://cloud.google.com/compute/docs/metadata

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
)

const (
	metadataHost = "metadata"
	metadataPath = "/computeMetadata/v1/"
)

var (
	metadataRequestHeaders = http.Header{
		"Metadata-Flavor": []string{"Google"},
	}
)

// TODO(dsymonds): Do we need to support default values, like Python?
func mustGetMetadata(key string) []byte {
	b, err := getMetadata(key)
	if err != nil {
		log.Fatalf("Metadata fetch failed: %v", err)
	}
	return b
}

func getMetadata(key string) ([]byte, error) {
	// TODO(dsymonds): May need to use url.Parse to support keys with query args.
	req := &http.Request{
		Method: "GET",
		URL: &url.URL{
			Scheme: "http",
			Host:   metadataHost,
			Path:   metadataPath + key,
		},
		Header: metadataRequestHeaders,
		Host:   metadataHost,
	}
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("metadata server returned HTTP %d", resp.StatusCode)
	}
	return ioutil.ReadAll(resp.Body)
}


text:
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package internal

import (
	"github.com/golang/protobuf/proto"
	netcontext "golang.org/x/net/context"
)

type CallOverrideFunc func(ctx netcontext.Context, service, method string, in, out proto.Message) error

var callOverrideKey = "holds []CallOverrideFunc"

func WithCallOverride(ctx netcontext.Context, f CallOverrideFunc) netcontext.Context {
	// We avoid appending to any existing call override
	// so we don't risk overwriting a popped stack below.
	var cofs []CallOverrideFunc
	if uf, ok := ctx.Value(&callOverrideKey).([]CallOverrideFunc); ok {
		cofs = append(cofs, uf...)
	}
	cofs = append(cofs, f)
	return netcontext.WithValue(ctx, &callOverrideKey, cofs)
}

func callOverrideFromContext(ctx netcontext.Context) (CallOverrideFunc, netcontext.Context, bool) {
	cofs, _ := ctx.Value(&callOverrideKey).([]CallOverrideFunc)
	if len(cofs) == 0 {
		return nil, nil, false
	}
	// We found a list of overrides; grab the last, and reconstitute a
	// context that will hide it.
	f := cofs[len(cofs)-1]
	ctx = netcontext.WithValue(ctx, &callOverrideKey, cofs[:len(cofs)-1])
	return f, ctx, true
}

type logOverrideFunc func(level int64, format string, args ...interface{})

var logOverrideKey = "holds a logOverrideFunc"

func WithLogOverride(ctx netcontext.Context, f logOverrideFunc) netcontext.Context {
	return netcontext.WithValue(ctx, &logOverrideKey, f)
}

var appIDOverrideKey = "holds a string, being the full app ID"

func WithAppIDOverride(ctx netcontext.Context, appID string) netcontext.Context {
	return netcontext.WithValue(ctx, &appIDOverrideKey, appID)
}

var namespaceKey = "holds the namespace string"

func withNamespace(ctx netcontext.Context, ns string) netcontext.Context {
	return netcontext.WithValue(ctx, &namespaceKey, ns)
}

func NamespaceFromContext(ctx netcontext.Context) string {
	// If there's no namespace, return the empty string.
	ns, _ := ctx.Value(&namespaceKey).(string)
	return ns
}

// FullyQualifiedAppID returns the fully-qualified application ID.
// This may contain a partition prefix (e.g. "s~" for High Replication apps),
// or a domain prefix (e.g. "example.com:").
func FullyQualifiedAppID(ctx netcontext.Context) string {
	if id, ok := ctx.Value(&appIDOverrideKey).(string); ok {
		return id
	}
	return fullyQualifiedAppID(ctx)
}

func Logf(ctx netcontext.Context, level int64, format string, args ...interface{}) {
	if f, ok := ctx.Value(&logOverrideKey).(logOverrideFunc); ok {
		f(level, format, args...)
		return
	}
	logf(fromContext(ctx), level, format, args...)
}

// NamespacedContext wraps a Context to support namespaces.
func NamespacedContext(ctx netcontext.Context, namespace string) netcontext.Context {
	return withNamespace(ctx, namespace)
}


text:
// Code generated by protoc-gen-go.
// source: google.golang.org/appengine/internal/system/system_service.proto
// DO NOT EDIT!

/*
Package system is a generated protocol buffer package.

It is generated from these files:
	google.golang.org/appengine/internal/system/system_service.proto

It has these top-level messages:
	SystemServiceError
	SystemStat
	GetSystemStatsRequest
	GetSystemStatsResponse
	StartBackgroundRequestRequest
	StartBackgroundRequestResponse
*/
package system

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

type SystemServiceError_ErrorCode int32

const (
	SystemServiceError_OK               SystemServiceError_ErrorCode = 0
	SystemServiceError_INTERNAL_ERROR   SystemServiceError_ErrorCode = 1
	SystemServiceError_BACKEND_REQUIRED SystemServiceError_ErrorCode = 2
	SystemServiceError_LIMIT_REACHED    SystemServiceError_ErrorCode = 3
)

var SystemServiceError_ErrorCode_name = map[int32]string{
	0: "OK",
	1: "INTERNAL_ERROR",
	2: "BACKEND_REQUIRED",
	3: "LIMIT_REACHED",
}
var SystemServiceError_ErrorCode_value = map[string]int32{
	"OK":               0,
	"INTERNAL_ERROR":   1,
	"BACKEND_REQUIRED": 2,
	"LIMIT_REACHED":    3,
}

func (x SystemServiceError_ErrorCode) Enum() *SystemServiceError_ErrorCode {
	p := new(SystemServiceError_ErrorCode)
	*p = x
	return p
}
func (x SystemServiceError_ErrorCode) String() string {
	return proto.EnumName(SystemServiceError_ErrorCode_name, int32(x))
}
func (x *SystemServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
	value, err := proto.UnmarshalJSONEnum(SystemServiceError_ErrorCode_value, data, "SystemServiceError_ErrorCode")
	if err != nil {
		return err
	}
	*x = SystemServiceError_ErrorCode(value)
	return nil
}

type SystemServiceError struct {
	XXX_unrecognized []byte `json:"-"`
}

func (m *SystemServiceError) Reset()         { *m = SystemServiceError{} }
func (m *SystemServiceError) String() string { return proto.CompactTextString(m) }
func (*SystemServiceError) ProtoMessage()    {}

type SystemStat struct {
	// Instaneous value of this stat.
	Current *float64 `protobuf:"fixed64,1,opt,name=current" json:"current,omitempty"`
	// Average over time, if this stat has an instaneous value.
	Average1M  *float64 `protobuf:"fixed64,3,opt,name=average1m" json:"average1m,omitempty"`
	Average10M *float64 `protobuf:"fixed64,4,opt,name=average10m" json:"average10m,omitempty"`
	// Total value, if the stat accumulates over time.
	Total *float64 `protobuf:"fixed64,2,opt,name=total" json:"total,omitempty"`
	// Rate over time, if this stat accumulates.
	Rate1M           *float64 `protobuf:"fixed64,5,opt,name=rate1m" json:"rate1m,omitempty"`
	Rate10M          *float64 `protobuf:"fixed64,6,opt,name=rate10m" json:"rate10m,omitempty"`
	XXX_unrecognized []byte   `json:"-"`
}

func (m *SystemStat) Reset()         { *m = SystemStat{} }
func (m *SystemStat) String() string { return proto.CompactTextString(m) }
func (*SystemStat) ProtoMessage()    {}

func (m *SystemStat) GetCurrent() float64 {
	if m != nil && m.Current != nil {
		return *m.Current
	}
	return 0
}

func (m *SystemStat) GetAverage1M() float64 {
	if m != nil && m.Average1M != nil {
		return *m.Average1M
	}
	return 0
}

func (m *SystemStat) GetAverage10M() float64 {
	if m != nil && m.Average10M != nil {
		return *m.Average10M
	}
	return 0
}

func (m *SystemStat) GetTotal() float64 {
	if m != nil && m.Total != nil {
		return *m.Total
	}
	return 0
}

func (m *SystemStat) GetRate1M() float64 {
	if m != nil && m.Rate1M != nil {
		return *m.Rate1M
	}
	return 0
}

func (m *SystemStat) GetRate10M() float64 {
	if m != nil && m.Rate10M != nil {
		return *m.Rate10M
	}
	return 0
}

type GetSystemStatsRequest struct {
	XXX_unrecognized []byte `json:"-"`
}

func (m *GetSystemStatsRequest) Reset()         { *m = GetSystemStatsRequest{} }
func (m *GetSystemStatsRequest) String() string { return proto.CompactTextString(m) }
func (*GetSystemStatsRequest) ProtoMessage()    {}

type GetSystemStatsResponse struct {
	// CPU used by this instance, in mcycles.
	Cpu *SystemStat `protobuf:"bytes,1,opt,name=cpu" json:"cpu,omitempty"`
	// Physical memory (RAM) used by this instance, in megabytes.
	Memory           *SystemStat `protobuf:"bytes,2,opt,name=memory" json:"memory,omitempty"`
	XXX_unrecognized []byte      `json:"-"`
}

func (m *GetSystemStatsResponse) Reset()         { *m = GetSystemStatsResponse{} }
func (m *GetSystemStatsResponse) String() string { return proto.CompactTextString(m) }
func (*GetSystemStatsResponse) ProtoMessage()    {}

func (m *GetSystemStatsResponse) GetCpu() *SystemStat {
	if m != nil {
		return m.Cpu
	}
	return nil
}

func (m *GetSystemStatsResponse) GetMemory() *SystemStat {
	if m != nil {
		return m.Memory
	}
	return nil
}

type StartBackgroundRequestRequest struct {
	XXX_unrecognized []byte `json:"-"`
}

func (m *StartBackgroundRequestRequest) Reset()         { *m = StartBackgroundRequestRequest{} }
func (m *StartBackgroundRequestRequest) String() string { return proto.CompactTextString(m) }
func (*StartBackgroundRequestRequest) ProtoMessage()    {}

type StartBackgroundRequestResponse struct {
	// Every /_ah/background request will have an X-AppEngine-BackgroundRequest
	// header, whose value will be equal to this parameter, the request_id.
	RequestId        *string `protobuf:"bytes,1,opt,name=request_id" json:"request_id,omitempty"`
	XXX_unrecognized []byte  `json:"-"`
}

func (m *StartBackgroundRequestResponse) Reset()         { *m = StartBackgroundRequestResponse{} }
func (m *StartBackgroundRequestResponse) String() string { return proto.CompactTextString(m) }
func (*StartBackgroundRequestResponse) ProtoMessage()    {}

func (m *StartBackgroundRequestResponse) GetRequestId() string {
	if m != nil && m.RequestId != nil {
		return *m.RequestId
	}
	return ""
}

func init() {
}


text:
syntax = "proto2";
option go_package = "system";

package appengine;

message SystemServiceError {
  enum ErrorCode {
    OK = 0;
    INTERNAL_ERROR = 1;
    BACKEND_REQUIRED = 2;
    LIMIT_REACHED = 3;
  }
}

message SystemStat {
  // Instaneous value of this stat.
  optional double current = 1;

  // Average over time, if this stat has an instaneous value.
  optional double average1m = 3;
  optional double average10m = 4;

  // Total value, if the stat accumulates over time.
  optional double total = 2;

  // Rate over time, if this stat accumulates.
  optional double rate1m = 5;
  optional double rate10m = 6;
}

message GetSystemStatsRequest {
}

message GetSystemStatsResponse {
  // CPU used by this instance, in mcycles.
  optional SystemStat cpu = 1;

  // Physical memory (RAM) used by this instance, in megabytes.
  optional SystemStat memory = 2;
}

message StartBackgroundRequestRequest {
}

message StartBackgroundRequestResponse {
  // Every /_ah/background request will have an X-AppEngine-BackgroundRequest
  // header, whose value will be equal to this parameter, the request_id.
  optional string request_id = 1;
}


text:
syntax = "proto2";
option go_package = "memcache";

package appengine;

message MemcacheServiceError {
  enum ErrorCode {
    OK = 0;
    UNSPECIFIED_ERROR = 1;
    NAMESPACE_NOT_SET = 2;
    PERMISSION_DENIED = 3;
    INVALID_VALUE = 6;
  }
}

message AppOverride {
  required string app_id = 1;

  optional int32 num_memcacheg_backends = 2 [deprecated=true];
  optional bool ignore_shardlock = 3 [deprecated=true];
  optional string memcache_pool_hint = 4 [deprecated=true];
  optional bytes memcache_sharding_strategy = 5 [deprecated=true];
}

message MemcacheGetRequest {
  repeated bytes key = 1;
  optional string name_space = 2 [default = ""];
  optional bool for_cas = 4;
  optional AppOverride override = 5;
}

message MemcacheGetResponse {
  repeated group Item = 1 {
    required bytes key = 2;
    required bytes value = 3;
    optional fixed32 flags = 4;
    optional fixed64 cas_id = 5;
    optional int32 expires_in_seconds = 6;
  }
}

message MemcacheSetRequest {
  enum SetPolicy {
    SET = 1;
    ADD = 2;
    REPLACE = 3;
    CAS = 4;
  }
  repeated group Item = 1 {
    required bytes key = 2;
    required bytes value = 3;

    optional fixed32 flags = 4;
    optional SetPolicy set_policy = 5 [default = SET];
    optional fixed32 expiration_time = 6 [default = 0];

    optional fixed64 cas_id = 8;
    optional bool for_cas = 9;
  }
  optional string name_space = 7 [default = ""];
  optional AppOverride override = 10;
}

message MemcacheSetResponse {
  enum SetStatusCode {
    STORED = 1;
    NOT_STORED = 2;
    ERROR = 3;
    EXISTS = 4;
  }
  repeated SetStatusCode set_status = 1;
}

message MemcacheDeleteRequest {
  repeated group Item = 1 {
    required bytes key = 2;
    optional fixed32 delete_time = 3 [default = 0];
  }
  optional string name_space = 4 [default = ""];
  optional AppOverride override = 5;
}

message MemcacheDeleteResponse {
  enum DeleteStatusCode {
    DELETED = 1;
    NOT_FOUND = 2;
  }
  repeated DeleteStatusCode delete_status = 1;
}

message MemcacheIncrementRequest {
  enum Direction {
    INCREMENT = 1;
    DECREMENT = 2;
  }
  required bytes key = 1;
  optional string name_space = 4 [default = ""];

  optional uint64 delta = 2 [default = 1];
  optional Direction direction = 3 [default = INCREMENT];

  optional uint64 initial_value = 5;
  optional fixed32 initial_flags = 6;
  optional AppOverride override = 7;
}

message MemcacheIncrementResponse {
  enum IncrementStatusCode {
    OK = 1;
    NOT_CHANGED = 2;
    ERROR = 3;
  }

  optional uint64 new_value = 1;
  optional IncrementStatusCode increment_status = 2;
}

message MemcacheBatchIncrementRequest {
  optional string name_space = 1 [default = ""];
  repeated MemcacheIncrementRequest item = 2;
  optional AppOverride override = 3;
}

message MemcacheBatchIncrementResponse {
  repeated MemcacheIncrementResponse item = 1;
}

message MemcacheFlushRequest {
  optional AppOverride override = 1;
}

message MemcacheFlushResponse {
}

message MemcacheStatsRequest {
  optional AppOverride override = 1;
}

message MergedNamespaceStats {
  required uint64 hits = 1;
  required uint64 misses = 2;
  required uint64 byte_hits = 3;

  required uint64 items = 4;
  required uint64 bytes = 5;

  required fixed32 oldest_item_age = 6;
}

message MemcacheStatsResponse {
  optional MergedNamespaceStats stats = 1;
}

message MemcacheGrabTailRequest {
  required int32 item_count = 1;
  optional string name_space = 2 [default = ""];
  optional AppOverride override = 3;
}

message MemcacheGrabTailResponse {
  repeated group Item = 1 {
    required bytes value = 2;
    optional fixed32 flags = 3;
  }
}