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 user

import (
	"fmt"
	"net/http"
	"testing"

	"github.com/golang/protobuf/proto"

	"google.golang.org/appengine/internal"
	"google.golang.org/appengine/internal/aetesting"
	pb "google.golang.org/appengine/internal/user"
)

func baseReq() *http.Request {
	return &http.Request{
		Header: http.Header{},
	}
}

type basicUserTest struct {
	nickname, email, authDomain, admin string
	// expectations
	isNil, isAdmin bool
	displayName    string
}

var basicUserTests = []basicUserTest{
	{"", "", "", "0", true, false, ""},
	{"ken", "ken@example.com", "example.com", "0", false, false, "ken"},
	{"ken", "ken@example.com", "auth_domain.com", "1", false, true, "ken@example.com"},
}

func TestBasicUserAPI(t *testing.T) {
	for i, tc := range basicUserTests {
		req := baseReq()
		req.Header.Set("X-AppEngine-User-Nickname", tc.nickname)
		req.Header.Set("X-AppEngine-User-Email", tc.email)
		req.Header.Set("X-AppEngine-Auth-Domain", tc.authDomain)
		req.Header.Set("X-AppEngine-User-Is-Admin", tc.admin)

		c := internal.ContextForTesting(req)

		if ga := IsAdmin(c); ga != tc.isAdmin {
			t.Errorf("test %d: expected IsAdmin(c) = %v, got %v", i, tc.isAdmin, ga)
		}

		u := Current(c)
		if tc.isNil {
			if u != nil {
				t.Errorf("test %d: expected u == nil, got %+v", i, u)
			}
			continue
		}
		if u == nil {
			t.Errorf("test %d: expected u != nil, got nil", i)
			continue
		}
		if u.Email != tc.email {
			t.Errorf("test %d: expected u.Email = %q, got %q", i, tc.email, u.Email)
		}
		if gs := u.String(); gs != tc.displayName {
			t.Errorf("test %d: expected u.String() = %q, got %q", i, tc.displayName, gs)
		}
		if u.Admin != tc.isAdmin {
			t.Errorf("test %d: expected u.Admin = %v, got %v", i, tc.isAdmin, u.Admin)
		}
	}
}

func TestLoginURL(t *testing.T) {
	expectedQuery := &pb.CreateLoginURLRequest{
		DestinationUrl: proto.String("/destination"),
	}
	const expectedDest = "/redir/dest"
	c := aetesting.FakeSingleContext(t, "user", "CreateLoginURL", func(req *pb.CreateLoginURLRequest, res *pb.CreateLoginURLResponse) error {
		if !proto.Equal(req, expectedQuery) {
			return fmt.Errorf("got %v, want %v", req, expectedQuery)
		}
		res.LoginUrl = proto.String(expectedDest)
		return nil
	})

	url, err := LoginURL(c, "/destination")
	if err != nil {
		t.Fatalf("LoginURL failed: %v", err)
	}
	if url != expectedDest {
		t.Errorf("got %v, want %v", url, expectedDest)
	}
}

// TODO(dsymonds): Add test for LogoutURL.


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 user

import (
	"appengine/user"

	"golang.org/x/net/context"

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

func Current(ctx context.Context) *User {
	u := user.Current(internal.ClassicContextFromContext(ctx))
	if u == nil {
		return nil
	}
	// Map appengine/user.User to this package's User type.
	return &User{
		Email:             u.Email,
		AuthDomain:        u.AuthDomain,
		Admin:             u.Admin,
		ID:                u.ID,
		FederatedIdentity: u.FederatedIdentity,
		FederatedProvider: u.FederatedProvider,
	}
}

func IsAdmin(ctx context.Context) bool {
	return user.IsAdmin(internal.ClassicContextFromContext(ctx))
}

repo_name: dan-v/dosxvpn

repo_language: Go

mime_type: text/x-shellscript


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 user

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

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

// Current returns the currently logged-in user,
// or nil if the user is not signed in.
func Current(c context.Context) *User {
	h := internal.IncomingHeaders(c)
	u := &User{
		Email:             h.Get("X-AppEngine-User-Email"),
		AuthDomain:        h.Get("X-AppEngine-Auth-Domain"),
		ID:                h.Get("X-AppEngine-User-Id"),
		Admin:             h.Get("X-AppEngine-User-Is-Admin") == "1",
		FederatedIdentity: h.Get("X-AppEngine-Federated-Identity"),
		FederatedProvider: h.Get("X-AppEngine-Federated-Provider"),
	}
	if u.Email == "" && u.FederatedIdentity == "" {
		return nil
	}
	return u
}

// IsAdmin returns true if the current user is signed in and
// is currently registered as an administrator of the application.
func IsAdmin(c context.Context) bool {
	h := internal.IncomingHeaders(c)
	return h.Get("X-AppEngine-User-Is-Admin") == "1"
}


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 blobstore provides a client for App Engine's persistent blob
// storage service.
package blobstore // import "google.golang.org/appengine/blobstore"

import (
	"bufio"
	"encoding/base64"
	"fmt"
	"io"
	"io/ioutil"
	"mime"
	"mime/multipart"
	"net/http"
	"net/textproto"
	"net/url"
	"strconv"
	"strings"
	"time"

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

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

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

const (
	blobInfoKind      = "__BlobInfo__"
	blobFileIndexKind = "__BlobFileIndex__"
	zeroKey           = appengine.BlobKey("")
)

// BlobInfo is the blob metadata that is stored in the datastore.
// Filename may be empty.
type BlobInfo struct {
	BlobKey      appengine.BlobKey
	ContentType  string    `datastore:"content_type"`
	CreationTime time.Time `datastore:"creation"`
	Filename     string    `datastore:"filename"`
	Size         int64     `datastore:"size"`
	MD5          string    `datastore:"md5_hash"`

	// ObjectName is the Google Cloud Storage name for this blob.
	ObjectName string `datastore:"gs_object_name"`
}

// isErrFieldMismatch returns whether err is a datastore.ErrFieldMismatch.
//
// The blobstore stores blob metadata in the datastore. When loading that
// metadata, it may contain fields that we don't care about. datastore.Get will
// return datastore.ErrFieldMismatch in that case, so we ignore that specific
// error.
func isErrFieldMismatch(err error) bool {
	_, ok := err.(*datastore.ErrFieldMismatch)
	return ok
}

// Stat returns the BlobInfo for a provided blobKey. If no blob was found for
// that key, Stat returns datastore.ErrNoSuchEntity.
func Stat(c context.Context, blobKey appengine.BlobKey) (*BlobInfo, error) {
	c, _ = appengine.Namespace(c, "") // Blobstore is always in the empty string namespace
	dskey := datastore.NewKey(c, blobInfoKind, string(blobKey), 0, nil)
	bi := &BlobInfo{
		BlobKey: blobKey,
	}
	if err := datastore.Get(c, dskey, bi); err != nil && !isErrFieldMismatch(err) {
		return nil, err
	}
	return bi, nil
}

// Send sets the headers on response to instruct App Engine to send a blob as
// the response body. This is more efficient than reading and writing it out
// manually and isn't subject to normal response size limits.
func Send(response http.ResponseWriter, blobKey appengine.BlobKey) {
	hdr := response.Header()
	hdr.Set("X-AppEngine-BlobKey", string(blobKey))

	if hdr.Get("Content-Type") == "" {
		// This value is known to dev_appserver to mean automatic.
		// In production this is remapped to the empty value which
		// means automatic.
		hdr.Set("Content-Type", "application/vnd.google.appengine.auto")
	}
}

// UploadURL creates an upload URL for the form that the user will
// fill out, passing the application path to load when the POST of the
// form is completed. These URLs expire and should not be reused. The
// opts parameter may be nil.
func UploadURL(c context.Context, successPath string, opts *UploadURLOptions) (*url.URL, error) {
	req := &blobpb.CreateUploadURLRequest{
		SuccessPath: proto.String(successPath),
	}
	if opts != nil {
		if n := opts.MaxUploadBytes; n != 0 {
			req.MaxUploadSizeBytes = &n
		}
		if n := opts.MaxUploadBytesPerBlob; n != 0 {
			req.MaxUploadSizePerBlobBytes = &n
		}
		if s := opts.StorageBucket; s != "" {
			req.GsBucketName = &s
		}
	}
	res := &blobpb.CreateUploadURLResponse{}
	if err := internal.Call(c, "blobstore", "CreateUploadURL", req, res); err != nil {
		return nil, err
	}
	return url.Parse(*res.Url)
}

// UploadURLOptions are the options to create an upload URL.
type UploadURLOptions struct {
	MaxUploadBytes        int64 // optional
	MaxUploadBytesPerBlob int64 // optional

	// StorageBucket specifies the Google Cloud Storage bucket in which
	// to store the blob.
	// This is required if you use Cloud Storage instead of Blobstore.
	// Your application must have permission to write to the bucket.
	// You may optionally specify a bucket name and path in the format
	// "bucket_name/path", in which case the included path will be the
	// prefix of the uploaded object's name.
	StorageBucket string
}

// Delete deletes a blob.
func Delete(c context.Context, blobKey appengine.BlobKey) error {
	return DeleteMulti(c, []appengine.BlobKey{blobKey})
}

// DeleteMulti deletes multiple blobs.
func DeleteMulti(c context.Context, blobKey []appengine.BlobKey) error {
	s := make([]string, len(blobKey))
	for i, b := range blobKey {
		s[i] = string(b)
	}
	req := &blobpb.DeleteBlobRequest{
		BlobKey: s,
	}
	res := &basepb.VoidProto{}
	if err := internal.Call(c, "blobstore", "DeleteBlob", req, res); err != nil {
		return err
	}
	return nil
}

func errorf(format string, args ...interface{}) error {
	return fmt.Errorf("blobstore: "+format, args...)
}

// ParseUpload parses the synthetic POST request that your app gets from
// App Engine after a user's successful upload of blobs. Given the request,
// ParseUpload returns a map of the blobs received (keyed by HTML form
// element name) and other non-blob POST parameters.
func ParseUpload(req *http.Request) (blobs map[string][]*BlobInfo, other url.Values, err error) {
	_, params, err := mime.ParseMediaType(req.Header.Get("Content-Type"))
	if err != nil {
		return nil, nil, err
	}
	boundary := params["boundary"]
	if boundary == "" {
		return nil, nil, errorf("did not find MIME multipart boundary")
	}

	blobs = make(map[string][]*BlobInfo)
	other = make(url.Values)

	mreader := multipart.NewReader(io.MultiReader(req.Body, strings.NewReader("\r\n\r\n")), boundary)
	for {
		part, perr := mreader.NextPart()
		if perr == io.EOF {
			break
		}
		if perr != nil {
			return nil, nil, errorf("error reading next mime part with boundary %q (len=%d): %v",
				boundary, len(boundary), perr)
		}

		bi := &BlobInfo{}
		ctype, params, err := mime.ParseMediaType(part.Header.Get("Content-Disposition"))
		if err != nil {
			return nil, nil, err
		}
		bi.Filename = params["filename"]
		formKey := params["name"]

		ctype, params, err = mime.ParseMediaType(part.Header.Get("Content-Type"))
		if err != nil {
			return nil, nil, err
		}
		bi.BlobKey = appengine.BlobKey(params["blob-key"])
		if ctype != "message/external-body" || bi.BlobKey == "" {
			if formKey != "" {
				slurp, serr := ioutil.ReadAll(part)
				if serr != nil {
					return nil, nil, errorf("error reading %q MIME part", formKey)
				}
				other[formKey] = append(other[formKey], string(slurp))
			}
			continue
		}

		// App Engine sends a MIME header as the body of each MIME part.
		tp := textproto.NewReader(bufio.NewReader(part))
		header, mimeerr := tp.ReadMIMEHeader()
		if mimeerr != nil {
			return nil, nil, mimeerr
		}
		bi.Size, err = strconv.ParseInt(header.Get("Content-Length"), 10, 64)
		if err != nil {
			return nil, nil, err
		}
		bi.ContentType = header.Get("Content-Type")

		// Parse the time from the MIME header like:
		// X-AppEngine-Upload-Creation: 2011-03-15 21:38:34.712136
		createDate := header.Get("X-AppEngine-Upload-Creation")
		if createDate == "" {
			return nil, nil, errorf("expected to find an X-AppEngine-Upload-Creation header")
		}
		bi.CreationTime, err = time.Parse("2006-01-02 15:04:05.000000", createDate)
		if err != nil {
			return nil, nil, errorf("error parsing X-AppEngine-Upload-Creation: %s", err)
		}

		if hdr := header.Get("Content-MD5"); hdr != "" {
			md5, err := base64.URLEncoding.DecodeString(hdr)
			if err != nil {
				return nil, nil, errorf("bad Content-MD5 %q: %v", hdr, err)
			}
			bi.MD5 = string(md5)
		}

		// If the GCS object name was provided, record it.
		bi.ObjectName = header.Get("X-AppEngine-Cloud-Storage-Object")

		blobs[formKey] = append(blobs[formKey], bi)
	}
	return
}

// Reader is a blob reader.
type Reader interface {
	io.Reader
	io.ReaderAt
	io.Seeker
}

// NewReader returns a reader for a blob. It always succeeds; if the blob does
// not exist then an error will be reported upon first read.
func NewReader(c context.Context, blobKey appengine.BlobKey) Reader {
	return openBlob(c, blobKey)
}

// BlobKeyForFile returns a BlobKey for a Google Storage file.
// The filename should be of the form "/gs/bucket_name/object_name".
func BlobKeyForFile(c context.Context, filename string) (appengine.BlobKey, error) {
	req := &blobpb.CreateEncodedGoogleStorageKeyRequest{
		Filename: &filename,
	}
	res := &blobpb.CreateEncodedGoogleStorageKeyResponse{}
	if err := internal.Call(c, "blobstore", "CreateEncodedGoogleStorageKey", req, res); err != nil {
		return "", err
	}
	return appengine.BlobKey(*res.BlobKey), nil
}


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 blobstore

import (
	"io"
	"os"
	"strconv"
	"strings"
	"testing"

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

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

const rbs = readBufferSize

func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

func fakeFetchData(req *pb.FetchDataRequest, res *pb.FetchDataResponse) error {
	i0 := int(*req.StartIndex)
	i1 := int(*req.EndIndex + 1) // Blobstore's end-indices are inclusive; Go's are exclusive.
	bk := *req.BlobKey
	if i := strings.Index(bk, "."); i != -1 {
		// Strip everything past the ".".
		bk = bk[:i]
	}
	switch bk {
	case "a14p":
		const s = "abcdefghijklmnop"
		i0 := min(len(s), i0)
		i1 := min(len(s), i1)
		res.Data = []byte(s[i0:i1])
	case "longBlob":
		res.Data = make([]byte, i1-i0)
		for i := range res.Data {
			res.Data[i] = 'A' + uint8(i0/rbs)
			i0++
		}
	}
	return nil
}

// step is one step of a readerTest.
// It consists of a Reader method to call, the method arguments
// (lenp, offset, whence) and the expected results.
type step struct {
	method  string
	lenp    int
	offset  int64
	whence  int
	want    string
	wantErr error
}

var readerTest = []struct {
	blobKey string
	step    []step
}{
	{"noSuchBlobKey", []step{
		{"Read", 8, 0, 0, "", io.EOF},
	}},
	{"a14p.0", []step{
		// Test basic reads.
		{"Read", 1, 0, 0, "a", nil},
		{"Read", 3, 0, 0, "bcd", nil},
		{"Read", 1, 0, 0, "e", nil},
		{"Read", 2, 0, 0, "fg", nil},
		// Test Seek.
		{"Seek", 0, 2, os.SEEK_SET, "2", nil},
		{"Read", 5, 0, 0, "cdefg", nil},
		{"Seek", 0, 2, os.SEEK_CUR, "9", nil},
		{"Read", 1, 0, 0, "j", nil},
		// Test reads up to and past EOF.
		{"Read", 5, 0, 0, "klmno", nil},
		{"Read", 5, 0, 0, "p", nil},
		{"Read", 5, 0, 0, "", io.EOF},
		// Test ReadAt.
		{"ReadAt", 4, 0, 0, "abcd", nil},
		{"ReadAt", 4, 3, 0, "defg", nil},
		{"ReadAt", 4, 12, 0, "mnop", nil},
		{"ReadAt", 4, 13, 0, "nop", io.EOF},
		{"ReadAt", 4, 99, 0, "", io.EOF},
	}},
	{"a14p.1", []step{
		// Test Seek before any reads.
		{"Seek", 0, 2, os.SEEK_SET, "2", nil},
		{"Read", 1, 0, 0, "c", nil},
		// Test that ReadAt doesn't affect the Read offset.
		{"ReadAt", 3, 9, 0, "jkl", nil},
		{"Read", 3, 0, 0, "def", nil},
	}},
	{"a14p.2", []step{
		// Test ReadAt before any reads or seeks.
		{"ReadAt", 2, 14, 0, "op", nil},
	}},
	{"longBlob.0", []step{
		// Test basic read.
		{"Read", 1, 0, 0, "A", nil},
		// Test that Read returns early when the buffer is exhausted.
		{"Seek", 0, rbs - 2, os.SEEK_SET, strconv.Itoa(rbs - 2), nil},
		{"Read", 5, 0, 0, "AA", nil},
		{"Read", 3, 0, 0, "BBB", nil},
		// Test that what we just read is still in the buffer.
		{"Seek", 0, rbs - 2, os.SEEK_SET, strconv.Itoa(rbs - 2), nil},
		{"Read", 5, 0, 0, "AABBB", nil},
		// Test ReadAt.
		{"ReadAt", 3, rbs - 4, 0, "AAA", nil},
		{"ReadAt", 6, rbs - 4, 0, "AAAABB", nil},
		{"ReadAt", 8, rbs - 4, 0, "AAAABBBB", nil},
		{"ReadAt", 5, rbs - 4, 0, "AAAAB", nil},
		{"ReadAt", 2, rbs - 4, 0, "AA", nil},
		// Test seeking backwards from the Read offset.
		{"Seek", 0, 2*rbs - 8, os.SEEK_SET, strconv.Itoa(2*rbs - 8), nil},
		{"Read", 1, 0, 0, "B", nil},
		{"Read", 1, 0, 0, "B", nil},
		{"Read", 1, 0, 0, "B", nil},
		{"Read", 1, 0, 0, "B", nil},
		{"Read", 8, 0, 0, "BBBBCCCC", nil},
	}},
	{"longBlob.1", []step{
		// Test ReadAt with a slice larger than the buffer size.
		{"LargeReadAt", 2*rbs - 2, 0, 0, strconv.Itoa(2*rbs - 2), nil},
		{"LargeReadAt", 2*rbs - 1, 0, 0, strconv.Itoa(2*rbs - 1), nil},
		{"LargeReadAt", 2*rbs + 0, 0, 0, strconv.Itoa(2*rbs + 0), nil},
		{"LargeReadAt", 2*rbs + 1, 0, 0, strconv.Itoa(2*rbs + 1), nil},
		{"LargeReadAt", 2*rbs + 2, 0, 0, strconv.Itoa(2*rbs + 2), nil},
		{"LargeReadAt", 2*rbs - 2, 1, 0, strconv.Itoa(2*rbs - 2), nil},
		{"LargeReadAt", 2*rbs - 1, 1, 0, strconv.Itoa(2*rbs - 1), nil},
		{"LargeReadAt", 2*rbs + 0, 1, 0, strconv.Itoa(2*rbs + 0), nil},
		{"LargeReadAt", 2*rbs + 1, 1, 0, strconv.Itoa(2*rbs + 1), nil},
		{"LargeReadAt", 2*rbs + 2, 1, 0, strconv.Itoa(2*rbs + 2), nil},
	}},
}

func TestReader(t *testing.T) {
	for _, rt := range readerTest {
		c := aetesting.FakeSingleContext(t, "blobstore", "FetchData", fakeFetchData)
		r := NewReader(c, appengine.BlobKey(rt.blobKey))
		for i, step := range rt.step {
			var (
				got    string
				gotErr error
				n      int
				offset int64
			)
			switch step.method {
			case "LargeReadAt":
				p := make([]byte, step.lenp)
				n, gotErr = r.ReadAt(p, step.offset)
				got = strconv.Itoa(n)
			case "Read":
				p := make([]byte, step.lenp)
				n, gotErr = r.Read(p)
				got = string(p[:n])
			case "ReadAt":
				p := make([]byte, step.lenp)
				n, gotErr = r.ReadAt(p, step.offset)
				got = string(p[:n])
			case "Seek":
				offset, gotErr = r.Seek(step.offset, step.whence)
				got = strconv.FormatInt(offset, 10)
			default:
				t.Fatalf("unknown method: %s", step.method)
			}
			if gotErr != step.wantErr {
				t.Fatalf("%s step %d: got error %v want %v", rt.blobKey, i, gotErr, step.wantErr)
			}
			if got != step.want {
				t.Fatalf("%s step %d: got %q want %q", rt.blobKey, i, got, step.want)
			}
		}
	}
}


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 blobstore

import (
	"errors"
	"fmt"
	"io"
	"os"
	"sync"

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

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

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

// openBlob returns a reader for a blob. It always succeeds; if the blob does
// not exist then an error will be reported upon first read.
func openBlob(c context.Context, blobKey appengine.BlobKey) Reader {
	return &reader{
		c:       c,
		blobKey: blobKey,
	}
}

const readBufferSize = 256 * 1024

// reader is a blob reader. It implements the Reader interface.
type reader struct {
	c context.Context

	// Either blobKey or filename is set:
	blobKey  appengine.BlobKey
	filename string

	closeFunc func() // is nil if unavailable or already closed.

	// buf is the read buffer. r is how much of buf has been read.
	// off is the offset of buf[0] relative to the start of the blob.
	// An invariant is 0 <= r && r <= len(buf).
	// Reads that don't require an RPC call will increment r but not off.
	// Seeks may modify r without discarding the buffer, but only if the
	// invariant can be maintained.
	mu  sync.Mutex
	buf []byte
	r   int
	off int64
}

func (r *reader) Close() error {
	if f := r.closeFunc; f != nil {
		f()
	}
	r.closeFunc = nil
	return nil
}

func (r *reader) Read(p []byte) (int, error) {
	if len(p) == 0 {
		return 0, nil
	}
	r.mu.Lock()
	defer r.mu.Unlock()
	if r.r == len(r.buf) {
		if err := r.fetch(r.off + int64(r.r)); err != nil {
			return 0, err
		}
	}
	n := copy(p, r.buf[r.r:])
	r.r += n
	return n, nil
}

func (r *reader) ReadAt(p []byte, off int64) (int, error) {
	if len(p) == 0 {
		return 0, nil
	}
	r.mu.Lock()
	defer r.mu.Unlock()
	// Convert relative offsets to absolute offsets.
	ab0 := r.off + int64(r.r)
	ab1 := r.off + int64(len(r.buf))
	ap0 := off
	ap1 := off + int64(len(p))
	// Check if we can satisfy the read entirely out of the existing buffer.
	if r.off <= ap0 && ap1 <= ab1 {
		// Convert off from an absolute offset to a relative offset.
		rp0 := int(ap0 - r.off)
		return copy(p, r.buf[rp0:]), nil
	}
	// Restore the original Read/Seek offset after ReadAt completes.
	defer r.seek(ab0)
	// Repeatedly fetch and copy until we have filled p.
	n := 0
	for len(p) > 0 {
		if err := r.fetch(off + int64(n)); err != nil {
			return n, err
		}
		r.r = copy(p, r.buf)
		n += r.r
		p = p[r.r:]
	}
	return n, nil
}

func (r *reader) Seek(offset int64, whence int) (ret int64, err error) {
	r.mu.Lock()
	defer r.mu.Unlock()
	switch whence {
	case os.SEEK_SET:
		ret = offset
	case os.SEEK_CUR:
		ret = r.off + int64(r.r) + offset
	case os.SEEK_END:
		return 0, errors.New("seeking relative to the end of a blob isn't supported")
	default:
		return 0, fmt.Errorf("invalid Seek whence value: %d", whence)
	}
	if ret < 0 {
		return 0, errors.New("negative Seek offset")
	}
	return r.seek(ret)
}

// fetch fetches readBufferSize bytes starting at the given offset. On success,
// the data is saved as r.buf.
func (r *reader) fetch(off int64) error {
	req := &blobpb.FetchDataRequest{
		BlobKey:    proto.String(string(r.blobKey)),
		StartIndex: proto.Int64(off),
		EndIndex:   proto.Int64(off + readBufferSize - 1), // EndIndex is inclusive.
	}
	res := &blobpb.FetchDataResponse{}
	if err := internal.Call(r.c, "blobstore", "FetchData", req, res); err != nil {
		return err
	}
	if len(res.Data) == 0 {
		return io.EOF
	}
	r.buf, r.r, r.off = res.Data, 0, off
	return nil
}

// seek seeks to the given offset with an effective whence equal to SEEK_SET.
// It discards the read buffer if the invariant cannot be maintained.
func (r *reader) seek(off int64) (int64, error) {
	delta := off - r.off
	if delta >= 0 && delta < int64(len(r.buf)) {
		r.r = int(delta)
		return off, nil
	}
	r.buf, r.r, r.off = nil, 0, off
	return off, nil
}


text:
package aetest

import (
	"os"
	"testing"

	"google.golang.org/appengine"
	"google.golang.org/appengine/datastore"
	"google.golang.org/appengine/memcache"
	"google.golang.org/appengine/user"
)

func TestBasicAPICalls(t *testing.T) {
	// Only run the test if APPENGINE_DEV_APPSERVER is explicitly set.
	if os.Getenv("APPENGINE_DEV_APPSERVER") == "" {
		t.Skip("APPENGINE_DEV_APPSERVER not set")
	}

	inst, err := NewInstance(nil)
	if err != nil {
		t.Fatalf("NewInstance: %v", err)
	}
	defer inst.Close()

	req, err := inst.NewRequest("GET", "http://example.com/page", nil)
	if err != nil {
		t.Fatalf("NewRequest: %v", err)
	}
	ctx := appengine.NewContext(req)

	it := &memcache.Item{
		Key:   "some-key",
		Value: []byte("some-value"),
	}
	err = memcache.Set(ctx, it)
	if err != nil {
		t.Fatalf("Set err: %v", err)
	}
	it, err = memcache.Get(ctx, "some-key")
	if err != nil {
		t.Fatalf("Get err: %v; want no error", err)
	}
	if g, w := string(it.Value), "some-value"; g != w {
		t.Errorf("retrieved Item.Value = %q, want %q", g, w)
	}

	type Entity struct{ Value string }
	e := &Entity{Value: "foo"}
	k := datastore.NewIncompleteKey(ctx, "Entity", nil)
	k, err = datastore.Put(ctx, k, e)
	if err != nil {
		t.Fatalf("datastore.Put: %v", err)
	}
	e = new(Entity)
	if err := datastore.Get(ctx, k, e); err != nil {
		t.Fatalf("datastore.Get: %v", err)
	}
	if g, w := e.Value, "foo"; g != w {
		t.Errorf("retrieved Entity.Value = %q, want %q", g, w)
	}
}

func TestContext(t *testing.T) {
	// Only run the test if APPENGINE_DEV_APPSERVER is explicitly set.
	if os.Getenv("APPENGINE_DEV_APPSERVER") == "" {
		t.Skip("APPENGINE_DEV_APPSERVER not set")
	}

	// Check that the context methods work.
	_, done, err := NewContext()
	if err != nil {
		t.Fatalf("NewContext: %v", err)
	}
	done()
}

func TestUsers(t *testing.T) {
	// Only run the test if APPENGINE_DEV_APPSERVER is explicitly set.
	if os.Getenv("APPENGINE_DEV_APPSERVER") == "" {
		t.Skip("APPENGINE_DEV_APPSERVER not set")
	}

	inst, err := NewInstance(nil)
	if err != nil {
		t.Fatalf("NewInstance: %v", err)
	}
	defer inst.Close()

	req, err := inst.NewRequest("GET", "http://example.com/page", nil)
	if err != nil {
		t.Fatalf("NewRequest: %v", err)
	}
	ctx := appengine.NewContext(req)

	if user := user.Current(ctx); user != nil {
		t.Errorf("user.Current initially %v, want nil", user)
	}

	u := &user.User{
		Email: "gopher@example.com",
		Admin: true,
	}
	Login(u, req)

	if got := user.Current(ctx); got.Email != u.Email {
		t.Errorf("user.Current: %v, want %v", got, u)
	}
	if admin := user.IsAdmin(ctx); !admin {
		t.Errorf("user.IsAdmin: %t, want true", admin)
	}

	Logout(req)
	if user := user.Current(ctx); user != nil {
		t.Errorf("user.Current after logout %v, want nil", user)
	}
}


text:
package aetest

import (
	"io"
	"net/http"

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

// Instance represents a running instance of the development API Server.
type Instance interface {
	// Close kills the child api_server.py process, releasing its resources.
	io.Closer
	// NewRequest returns an *http.Request associated with this instance.
	NewRequest(method, urlStr string, body io.Reader) (*http.Request, error)
}

// Options is used to specify options when creating an Instance.
type Options struct {
	// AppID specifies the App ID to use during tests.
	// By default, "testapp".
	AppID string
	// StronglyConsistentDatastore is whether the local datastore should be
	// strongly consistent. This will diverge from production behaviour.
	StronglyConsistentDatastore bool
}

// NewContext starts an instance of the development API server, and returns
// a context that will route all API calls to that server, as well as a
// closure that must be called when the Context is no longer required.
func NewContext() (context.Context, func(), error) {
	inst, err := NewInstance(nil)
	if err != nil {
		return nil, nil, err
	}
	req, err := inst.NewRequest("GET", "/", nil)
	if err != nil {
		inst.Close()
		return nil, nil, err
	}
	ctx := appengine.NewContext(req)
	return ctx, func() {
		inst.Close()
	}, nil
}

// PrepareDevAppserver is a hook which, if set, will be called before the
// dev_appserver.py is started, each time it is started. If aetest.NewContext
// is invoked from the goapp test tool, this hook is unnecessary.
var PrepareDevAppserver func() error


text:
package aetest

import (
	"hash/crc32"
	"net/http"
	"strconv"

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

// Login causes the provided Request to act as though issued by the given user.
func Login(u *user.User, req *http.Request) {
	req.Header.Set("X-AppEngine-User-Email", u.Email)
	id := u.ID
	if id == "" {
		id = strconv.Itoa(int(crc32.Checksum([]byte(u.Email), crc32.IEEETable)))
	}
	req.Header.Set("X-AppEngine-User-Id", id)
	req.Header.Set("X-AppEngine-User-Federated-Identity", u.Email)
	req.Header.Set("X-AppEngine-User-Federated-Provider", u.FederatedProvider)
	if u.Admin {
		req.Header.Set("X-AppEngine-User-Is-Admin", "1")
	} else {
		req.Header.Set("X-AppEngine-User-Is-Admin", "0")
	}
}

// Logout causes the provided Request to act as though issued by a logged-out
// user.
func Logout(req *http.Request) {
	req.Header.Del("X-AppEngine-User-Email")
	req.Header.Del("X-AppEngine-User-Id")
	req.Header.Del("X-AppEngine-User-Is-Admin")
	req.Header.Del("X-AppEngine-User-Federated-Identity")
	req.Header.Del("X-AppEngine-User-Federated-Provider")
}


text:
// +build appengine

package aetest

import "appengine/aetest"

// NewInstance launches a running instance of api_server.py which can be used
// for multiple test Contexts that delegate all App Engine API calls to that
// instance.
// If opts is nil the default values are used.
func NewInstance(opts *Options) (Instance, error) {
	aetest.PrepareDevAppserver = PrepareDevAppserver
	var aeOpts *aetest.Options
	if opts != nil {
		aeOpts = &aetest.Options{
			AppID: opts.AppID,
			StronglyConsistentDatastore: opts.StronglyConsistentDatastore,
		}
	}
	return aetest.NewInstance(aeOpts)
}


text:
// +build !appengine

package aetest

import (
	"bufio"
	"crypto/rand"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"time"

	"golang.org/x/net/context"
	"google.golang.org/appengine/internal"
)

// NewInstance launches a running instance of api_server.py which can be used
// for multiple test Contexts that delegate all App Engine API calls to that
// instance.
// If opts is nil the default values are used.
func NewInstance(opts *Options) (Instance, error) {
	i := &instance{
		opts:  opts,
		appID: "testapp",
	}
	if opts != nil && opts.AppID != "" {
		i.appID = opts.AppID
	}
	if err := i.startChild(); err != nil {
		return nil, err
	}
	return i, nil
}

func newSessionID() string {
	var buf [16]byte
	io.ReadFull(rand.Reader, buf[:])
	return fmt.Sprintf("%x", buf[:])
}

// instance implements the Instance interface.
type instance struct {
	opts     *Options
	child    *exec.Cmd
	apiURL   *url.URL // base URL of API HTTP server
	adminURL string   // base URL of admin HTTP server
	appDir   string
	appID    string
	relFuncs []func() // funcs to release any associated contexts
}

// NewRequest returns an *http.Request associated with this instance.
func (i *instance) NewRequest(method, urlStr string, body io.Reader) (*http.Request, error) {
	req, err := http.NewRequest(method, urlStr, body)
	if err != nil {
		return nil, err
	}

	// Associate this request.
	release := internal.RegisterTestRequest(req, i.apiURL, func(ctx context.Context) context.Context {
		ctx = internal.WithAppIDOverride(ctx, "dev~"+i.appID)
		return ctx
	})
	i.relFuncs = append(i.relFuncs, release)

	return req, nil
}

// Close kills the child api_server.py process, releasing its resources.
func (i *instance) Close() (err error) {
	for _, rel := range i.relFuncs {
		rel()
	}
	i.relFuncs = nil
	if i.child == nil {
		return nil
	}
	defer func() {
		i.child = nil
		err1 := os.RemoveAll(i.appDir)
		if err == nil {
			err = err1
		}
	}()

	if p := i.child.Process; p != nil {
		errc := make(chan error, 1)
		go func() {
			errc <- i.child.Wait()
		}()

		// Call the quit handler on the admin server.
		res, err := http.Get(i.adminURL + "/quit")
		if err != nil {
			p.Kill()
			return fmt.Errorf("unable to call /quit handler: %v", err)
		}
		res.Body.Close()

		select {
		case <-time.After(15 * time.Second):
			p.Kill()
			return errors.New("timeout killing child process")
		case err = <-errc:
			// Do nothing.
		}
	}
	return
}

func fileExists(path string) bool {
	_, err := os.Stat(path)
	return err == nil
}

func findPython() (path string, err error) {
	for _, name := range []string{"python2.7", "python"} {
		path, err = exec.LookPath(name)
		if err == nil {
			return
		}
	}
	return
}

func findDevAppserver() (string, error) {
	if p := os.Getenv("APPENGINE_DEV_APPSERVER"); p != "" {
		if fileExists(p) {
			return p, nil
		}
		return "", fmt.Errorf("invalid APPENGINE_DEV_APPSERVER environment variable; path %q doesn't exist", p)
	}
	return exec.LookPath("dev_appserver.py")
}

var apiServerAddrRE = regexp.MustCompile(`Starting API server at: (\S+)`)
var adminServerAddrRE = regexp.MustCompile(`Starting admin server at: (\S+)`)

func (i *instance) startChild() (err error) {
	if PrepareDevAppserver != nil {
		if err := PrepareDevAppserver(); err != nil {
			return err
		}
	}
	python, err := findPython()
	if err != nil {
		return fmt.Errorf("Could not find python interpreter: %v", err)
	}
	devAppserver, err := findDevAppserver()
	if err != nil {
		return fmt.Errorf("Could not find dev_appserver.py: %v", err)
	}

	i.appDir, err = ioutil.TempDir("", "appengine-aetest")
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			os.RemoveAll(i.appDir)
		}
	}()
	err = os.Mkdir(filepath.Join(i.appDir, "app"), 0755)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filepath.Join(i.appDir, "app", "app.yaml"), []byte(i.appYAML()), 0644)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filepath.Join(i.appDir, "app", "stubapp.go"), []byte(appSource), 0644)
	if err != nil {
		return err
	}

	appserverArgs := []string{
		devAppserver,
		"--port=0",
		"--api_port=0",
		"--admin_port=0",
		"--automatic_restart=false",
		"--skip_sdk_update_check=true",
		"--clear_datastore=true",
		"--clear_search_indexes=true",
		"--datastore_path", filepath.Join(i.appDir, "datastore"),
	}
	if i.opts != nil && i.opts.StronglyConsistentDatastore {
		appserverArgs = append(appserverArgs, "--datastore_consistency_policy=consistent")
	}
	appserverArgs = append(appserverArgs, filepath.Join(i.appDir, "app"))

	i.child = exec.Command(python,
		appserverArgs...,
	)
	i.child.Stdout = os.Stdout
	var stderr io.Reader
	stderr, err = i.child.StderrPipe()
	if err != nil {
		return err
	}
	stderr = io.TeeReader(stderr, os.Stderr)
	if err = i.child.Start(); err != nil {
		return err
	}

	// Read stderr until we have read the URLs of the API server and admin interface.
	errc := make(chan error, 1)
	go func() {
		s := bufio.NewScanner(stderr)
		for s.Scan() {
			if match := apiServerAddrRE.FindStringSubmatch(s.Text()); match != nil {
				u, err := url.Parse(match[1])
				if err != nil {
					errc <- fmt.Errorf("failed to parse API URL %q: %v", match[1], err)
					return
				}
				i.apiURL = u
			}
			if match := adminServerAddrRE.FindStringSubmatch(s.Text()); match != nil {
				i.adminURL = match[1]
			}
			if i.adminURL != "" && i.apiURL != nil {
				break
			}
		}
		errc <- s.Err()
	}()

	select {
	case <-time.After(15 * time.Second):
		if p := i.child.Process; p != nil {
			p.Kill()
		}
		return errors.New("timeout starting child process")
	case err := <-errc:
		if err != nil {
			return fmt.Errorf("error reading child process stderr: %v", err)
		}
	}
	if i.adminURL == "" {
		return errors.New("unable to find admin server URL")
	}
	if i.apiURL == nil {
		return errors.New("unable to find API server URL")
	}
	return nil
}

func (i *instance) appYAML() string {
	return fmt.Sprintf(appYAMLTemplate, i.appID)
}

const appYAMLTemplate = `
application: %s
version: 1
runtime: go
api_version: go1
vm: true

handlers:
- url: /.*
  script: _go_app
`

const appSource = `
package main
import "google.golang.org/appengine"
func main() { appengine.Main() }
`


text:
/*
Package aetest provides an API for running dev_appserver for use in tests.

An example test file:

	package foo_test

	import (
		"testing"

		"google.golang.org/appengine/memcache"
		"google.golang.org/appengine/aetest"
	)

	func TestFoo(t *testing.T) {
		ctx, done, err := aetest.NewContext()
		if err != nil {
			t.Fatal(err)
		}
		defer done()

		it := &memcache.Item{
			Key:   "some-key",
			Value: []byte("some-value"),
		}
		err = memcache.Set(ctx, it)
		if err != nil {
			t.Fatalf("Set err: %v", err)
		}
		it, err = memcache.Get(ctx, "some-key")
		if err != nil {
			t.Fatalf("Get err: %v; want no error", err)
		}
		if g, w := string(it.Value), "some-value" ; g != w {
			t.Errorf("retrieved Item.Value = %q, want %q", g, w)
		}
	}

The environment variable APPENGINE_DEV_APPSERVER specifies the location of the
dev_appserver.py executable to use. If unset, the system PATH is consulted.
*/
package aetest


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 image provides image services.
package image // import "google.golang.org/appengine/image"

import (
	"fmt"
	"net/url"

	"golang.org/x/net/context"

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

type ServingURLOptions struct {
	Secure bool // whether the URL should use HTTPS

	// Size must be between zero and 1600.
	// If Size is non-zero, a resized version of the image is served,
	// and Size is the served image's longest dimension. The aspect ratio is preserved.
	// If Crop is true the image is cropped from the center instead of being resized.
	Size int
	Crop bool
}

// ServingURL returns a URL that will serve an image from Blobstore.
func ServingURL(c context.Context, key appengine.BlobKey, opts *ServingURLOptions) (*url.URL, error) {
	req := &pb.ImagesGetUrlBaseRequest{
		BlobKey: (*string)(&key),
	}
	if opts != nil && opts.Secure {
		req.CreateSecureUrl = &opts.Secure
	}
	res := &pb.ImagesGetUrlBaseResponse{}
	if err := internal.Call(c, "images", "GetUrlBase", req, res); err != nil {
		return nil, err
	}

	// The URL may have suffixes added to dynamically resize or crop:
	// - adding "=s32" will serve the image resized to 32 pixels, preserving the aspect ratio.
	// - adding "=s32-c" is the same as "=s32" except it will be cropped.
	u := *res.Url
	if opts != nil && opts.Size > 0 {
		u += fmt.Sprintf("=s%d", opts.Size)
		if opts.Crop {
			u += "-c"
		}
	}
	return url.Parse(u)
}

// DeleteServingURL deletes the serving URL for an image.
func DeleteServingURL(c context.Context, key appengine.BlobKey) error {
	req := &pb.ImagesDeleteUrlBaseRequest{
		BlobKey: (*string)(&key),
	}
	res := &pb.ImagesDeleteUrlBaseResponse{}
	return internal.Call(c, "images", "DeleteUrlBase", req, res)
}

func init() {
	internal.RegisterErrorCodeMap("images", pb.ImagesServiceError_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.

// Package urlfetch provides an http.RoundTripper implementation
// for fetching URLs via App Engine's urlfetch service.
package urlfetch // import "google.golang.org/appengine/urlfetch"

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"

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

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

// Transport is an implementation of http.RoundTripper for
// App Engine. Users should generally create an http.Client using
// this transport and use the Client rather than using this transport
// directly.
type Transport struct {
	Context context.Context

	// Controls whether the application checks the validity of SSL certificates
	// over HTTPS connections. A value of false (the default) instructs the
	// application to send a request to the server only if the certificate is
	// valid and signed by a trusted certificate authority (CA), and also
	// includes a hostname that matches the certificate. A value of true
	// instructs the application to perform no certificate validation.
	AllowInvalidServerCertificate bool
}

// Verify statically that *Transport implements http.RoundTripper.
var _ http.RoundTripper = (*Transport)(nil)

// Client returns an *http.Client using a default urlfetch Transport. This
// client will have the default deadline of 5 seconds, and will check the
// validity of SSL certificates.
//
// Any deadline of the provided context will be used for requests through this client;
// if the client does not have a deadline then a 5 second default is used.
func Client(ctx context.Context) *http.Client {
	return &http.Client{
		Transport: &Transport{
			Context: ctx,
		},
	}
}

type bodyReader struct {
	content   []byte
	truncated bool
	closed    bool
}

// ErrTruncatedBody is the error returned after the final Read() from a
// response's Body if the body has been truncated by App Engine's proxy.
var ErrTruncatedBody = errors.New("urlfetch: truncated body")

func statusCodeToText(code int) string {
	if t := http.StatusText(code); t != "" {
		return t
	}
	return strconv.Itoa(code)
}

func (br *bodyReader) Read(p []byte) (n int, err error) {
	if br.closed {
		if br.truncated {
			return 0, ErrTruncatedBody
		}
		return 0, io.EOF
	}
	n = copy(p, br.content)
	if n > 0 {
		br.content = br.content[n:]
		return
	}
	if br.truncated {
		br.closed = true
		return 0, ErrTruncatedBody
	}
	return 0, io.EOF
}

func (br *bodyReader) Close() error {
	br.closed = true
	br.content = nil
	return nil
}

// A map of the URL Fetch-accepted methods that take a request body.
var methodAcceptsRequestBody = map[string]bool{
	"POST":  true,
	"PUT":   true,
	"PATCH": true,
}

// urlString returns a valid string given a URL. This function is necessary because
// the String method of URL doesn't correctly handle URLs with non-empty Opaque values.
// See http://code.google.com/p/go/issues/detail?id=4860.
func urlString(u *url.URL) string {
	if u.Opaque == "" || strings.HasPrefix(u.Opaque, "//") {
		return u.String()
	}
	aux := *u
	aux.Opaque = "//" + aux.Host + aux.Opaque
	return aux.String()
}

// RoundTrip issues a single HTTP request and returns its response. Per the
// http.RoundTripper interface, RoundTrip only returns an error if there
// was an unsupported request or the URL Fetch proxy fails.
// Note that HTTP response codes such as 5xx, 403, 404, etc are not
// errors as far as the transport is concerned and will be returned
// with err set to nil.
func (t *Transport) RoundTrip(req *http.Request) (res *http.Response, err error) {
	methNum, ok := pb.URLFetchRequest_RequestMethod_value[req.Method]
	if !ok {
		return nil, fmt.Errorf("urlfetch: unsupported HTTP method %q", req.Method)
	}

	method := pb.URLFetchRequest_RequestMethod(methNum)

	freq := &pb.URLFetchRequest{
		Method:                        &method,
		Url:                           proto.String(urlString(req.URL)),
		FollowRedirects:               proto.Bool(false), // http.Client's responsibility
		MustValidateServerCertificate: proto.Bool(!t.AllowInvalidServerCertificate),
	}
	if deadline, ok := t.Context.Deadline(); ok {
		freq.Deadline = proto.Float64(deadline.Sub(time.Now()).Seconds())
	}

	for k, vals := range req.Header {
		for _, val := range vals {
			freq.Header = append(freq.Header, &pb.URLFetchRequest_Header{
				Key:   proto.String(k),
				Value: proto.String(val),
			})
		}
	}
	if methodAcceptsRequestBody[req.Method] && req.Body != nil {
		// Avoid a []byte copy if req.Body has a Bytes method.
		switch b := req.Body.(type) {
		case interface {
			Bytes() []byte
		}:
			freq.Payload = b.Bytes()
		default:
			freq.Payload, err = ioutil.ReadAll(req.Body)
			if err != nil {
				return nil, err
			}
		}
	}

	fres := &pb.URLFetchResponse{}
	if err := internal.Call(t.Context, "urlfetch", "Fetch", freq, fres); err != nil {
		return nil, err
	}

	res = &http.Response{}
	res.StatusCode = int(*fres.StatusCode)
	res.Status = fmt.Sprintf("%d %s", res.StatusCode, statusCodeToText(res.StatusCode))
	res.Header = make(http.Header)
	res.Request = req

	// Faked:
	res.ProtoMajor = 1
	res.ProtoMinor = 1
	res.Proto = "HTTP/1.1"
	res.Close = true

	for _, h := range fres.Header {
		hkey := http.CanonicalHeaderKey(*h.Key)
		hval := *h.Value
		if hkey == "Content-Length" {
			// Will get filled in below for all but HEAD requests.
			if req.Method == "HEAD" {
				res.ContentLength, _ = strconv.ParseInt(hval, 10, 64)
			}
			continue
		}
		res.Header.Add(hkey, hval)
	}

	if req.Method != "HEAD" {
		res.ContentLength = int64(len(fres.Content))
	}

	truncated := fres.GetContentWasTruncated()
	res.Body = &bodyReader{content: fres.Content, truncated: truncated}
	return
}

func init() {
	internal.RegisterErrorCodeMap("urlfetch", pb.URLFetchServiceError_ErrorCode_name)
	internal.RegisterTimeoutErrorCode("urlfetch", int32(pb.URLFetchServiceError_DEADLINE_EXCEEDED))
}


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.

// Program aedeploy assists with deploying App Engine "flexible environment" Go apps to production.
// A temporary directory is created; the app, its subdirectories, and all its
// dependencies from $GOPATH are copied into the directory; then the app
// is deployed to production with the provided command.
//
// The app must be in "package main".
//
// This command must be issued from within the root directory of the app
// (where the app.yaml file is located).
package main

import (
	"flag"
	"fmt"
	"go/build"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var (
	skipFiles = map[string]bool{
		".git":        true,
		".gitconfig":  true,
		".hg":         true,
		".travis.yml": true,
	}

	gopathCache = map[string]string{}
)

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	fmt.Fprintf(os.Stderr, "\t%s gcloud --verbosity debug preview app deploy --version myversion ./app.yaml\tDeploy app to production\n", os.Args[0])
}

func main() {
	flag.Usage = usage
	flag.Parse()
	if flag.NArg() < 1 {
		usage()
		os.Exit(1)
	}

	if err := aedeploy(); err != nil {
		fmt.Fprintf(os.Stderr, os.Args[0]+": Error: %v\n", err)
		os.Exit(1)
	}
}

func aedeploy() error {
	tags := []string{"appenginevm"}
	app, err := analyze(tags)
	if err != nil {
		return err
	}

	tmpDir, err := app.bundle()
	if tmpDir != "" {
		defer os.RemoveAll(tmpDir)
	}
	if err != nil {
		return err
	}

	if err := os.Chdir(tmpDir); err != nil {
		return fmt.Errorf("unable to chdir to %v: %v", tmpDir, err)
	}
	return deploy()
}

// deploy calls the provided command to deploy the app from the temporary directory.
func deploy() error {
	cmd := exec.Command(flag.Arg(0), flag.Args()[1:]...)
	cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("unable to run %q: %v", strings.Join(flag.Args(), " "), err)
	}
	return nil
}

type app struct {
	appFiles []string
	imports  map[string]string
}

// analyze checks the app for building with the given build tags and returns
// app files, and a map of full directory import names to original import names.
func analyze(tags []string) (*app, error) {
	ctxt := buildContext(tags)
	appFiles, err := appFiles(ctxt)
	if err != nil {
		return nil, err
	}
	gopath := filepath.SplitList(ctxt.GOPATH)
	im, err := imports(ctxt, ".", gopath)
	return &app{
		appFiles: appFiles,
		imports:  im,
	}, err
}

// buildContext returns the context for building the source.
func buildContext(tags []string) *build.Context {
	return &build.Context{
		GOARCH:    "amd64",
		GOOS:      "linux",
		GOROOT:    build.Default.GOROOT,
		GOPATH:    build.Default.GOPATH,
		Compiler:  build.Default.Compiler,
		BuildTags: append(defaultBuildTags, tags...),
	}
}

// All build tags except go1.7, since Go 1.6 is the runtime version.
var defaultBuildTags = []string{
	"go1.1", "go1.2", "go1.3", "go1.4", "go1.5", "go1.6"}

// bundle bundles the app into a temporary directory.
func (s *app) bundle() (tmpdir string, err error) {
	workDir, err := ioutil.TempDir("", "aedeploy")
	if err != nil {
		return "", fmt.Errorf("unable to create tmpdir: %v", err)
	}

	for srcDir, importName := range s.imports {
		dstDir := "_gopath/src/" + importName
		if err := copyTree(workDir, dstDir, srcDir); err != nil {
			return workDir, fmt.Errorf("unable to copy directory %v to %v: %v", srcDir, dstDir, err)
		}
	}
	if err := copyTree(workDir, ".", "."); err != nil {
		return workDir, fmt.Errorf("unable to copy root directory to /app: %v", err)
	}
	return workDir, nil
}

// imports returns a map of all import directories (recursively) used by the app.
// The return value maps full directory names to original import names.
func imports(ctxt *build.Context, srcDir string, gopath []string) (map[string]string, error) {
	pkg, err := ctxt.ImportDir(srcDir, 0)
	if err != nil {
		return nil, err
	}

	// Resolve all non-standard-library imports
	result := make(map[string]string)
	for _, v := range pkg.Imports {
		if !strings.Contains(v, ".") {
			continue
		}
		src, err := findInGopath(v, gopath)
		if err != nil {
			return nil, fmt.Errorf("unable to find import %v in gopath %v: %v", v, gopath, err)
		}
		if _, ok := result[src]; ok { // Already processed
			continue
		}
		result[src] = v
		im, err := imports(ctxt, src, gopath)
		if err != nil {
			return nil, fmt.Errorf("unable to parse package %v: %v", src, err)
		}
		for k, v := range im {
			result[k] = v
		}
	}
	return result, nil
}

// findInGopath searches the gopath for the named import directory.
func findInGopath(dir string, gopath []string) (string, error) {
	if v, ok := gopathCache[dir]; ok {
		return v, nil
	}
	for _, v := range gopath {
		dst := filepath.Join(v, "src", dir)
		if _, err := os.Stat(dst); err == nil {
			gopathCache[dir] = dst
			return dst, nil
		}
	}
	return "", fmt.Errorf("unable to find package %v in gopath %v", dir, gopath)
}

// copyTree copies srcDir to dstDir relative to dstRoot, ignoring skipFiles.
func copyTree(dstRoot, dstDir, srcDir string) error {
	d := filepath.Join(dstRoot, dstDir)
	if err := os.MkdirAll(d, 0755); err != nil {
		return fmt.Errorf("unable to create directory %q: %v", d, err)
	}

	entries, err := ioutil.ReadDir(srcDir)
	if err != nil {
		return fmt.Errorf("unable to read dir %q: %v", srcDir, err)
	}
	for _, entry := range entries {
		n := entry.Name()
		if skipFiles[n] {
			continue
		}
		s := filepath.Join(srcDir, n)
		if entry.Mode()&os.ModeSymlink == os.ModeSymlink {
			if entry, err = os.Stat(s); err != nil {
				return fmt.Errorf("unable to stat %v: %v", s, err)
			}
		}
		d := filepath.Join(dstDir, n)
		if entry.IsDir() {
			if err := copyTree(dstRoot, d, s); err != nil {
				return fmt.Errorf("unable to copy dir %q to %q: %v", s, d, err)
			}
			continue
		}
		if err := copyFile(dstRoot, d, s); err != nil {
			return fmt.Errorf("unable to copy dir %q to %q: %v", s, d, err)
		}
	}
	return nil
}

// copyFile copies src to dst relative to dstRoot.
func copyFile(dstRoot, dst, src string) error {
	s, err := os.Open(src)
	if err != nil {
		return fmt.Errorf("unable to open %q: %v", src, err)
	}
	defer s.Close()

	dst = filepath.Join(dstRoot, dst)
	d, err := os.Create(dst)
	if err != nil {
		return fmt.Errorf("unable to create %q: %v", dst, err)
	}
	_, err = io.Copy(d, s)
	if err != nil {
		d.Close() // ignore error, copy already failed.
		return fmt.Errorf("unable to copy %q to %q: %v", src, dst, err)
	}
	if err := d.Close(); err != nil {
		return fmt.Errorf("unable to close %q: %v", dst, err)
	}
	return nil
}

// appFiles returns a list of all Go source files in the app.
func appFiles(ctxt *build.Context) ([]string, error) {
	pkg, err := ctxt.ImportDir(".", 0)
	if err != nil {
		return nil, err
	}
	if !pkg.IsCommand() {
		return nil, fmt.Errorf(`the root of your app needs to be package "main" (currently %q). Please see https://cloud.google.com/appengine/docs/flexible/go/ for more details on structuring your app.`, pkg.Name)
	}
	var appFiles []string
	for _, f := range pkg.GoFiles {
		n := filepath.Join(".", f)
		appFiles = append(appFiles, n)
	}
	return appFiles, nil
}


text:
// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"go/ast"
	"go/parser"
	"strings"
	"testing"
)

type testCase struct {
	Name string
	Fn   func(*ast.File) bool
	In   string
	Out  string
}

var testCases []testCase

func addTestCases(t []testCase, fn func(*ast.File) bool) {
	// Fill in fn to avoid repetition in definitions.
	if fn != nil {
		for i := range t {
			if t[i].Fn == nil {
				t[i].Fn = fn
			}
		}
	}
	testCases = append(testCases, t...)
}

func fnop(*ast.File) bool { return false }

func parseFixPrint(t *testing.T, fn func(*ast.File) bool, desc, in string, mustBeGofmt bool) (out string, fixed, ok bool) {
	file, err := parser.ParseFile(fset, desc, in, parserMode)
	if err != nil {
		t.Errorf("%s: parsing: %v", desc, err)
		return
	}

	outb, err := gofmtFile(file)
	if err != nil {
		t.Errorf("%s: printing: %v", desc, err)
		return
	}
	if s := string(outb); in != s && mustBeGofmt {
		t.Errorf("%s: not gofmt-formatted.\n--- %s\n%s\n--- %s | gofmt\n%s",
			desc, desc, in, desc, s)
		tdiff(t, in, s)
		return
	}

	if fn == nil {
		for _, fix := range fixes {
			if fix.f(file) {
				fixed = true
			}
		}
	} else {
		fixed = fn(file)
	}

	outb, err = gofmtFile(file)
	if err != nil {
		t.Errorf("%s: printing: %v", desc, err)
		return
	}

	return string(outb), fixed, true
}

func TestRewrite(t *testing.T) {
	for _, tt := range testCases {
		// Apply fix: should get tt.Out.
		out, fixed, ok := parseFixPrint(t, tt.Fn, tt.Name, tt.In, true)
		if !ok {
			continue
		}

		// reformat to get printing right
		out, _, ok = parseFixPrint(t, fnop, tt.Name, out, false)
		if !ok {
			continue
		}

		if out != tt.Out {
			t.Errorf("%s: incorrect output.\n", tt.Name)
			if !strings.HasPrefix(tt.Name, "testdata/") {
				t.Errorf("--- have\n%s\n--- want\n%s", out, tt.Out)
			}
			tdiff(t, out, tt.Out)
			continue
		}

		if changed := out != tt.In; changed != fixed {
			t.Errorf("%s: changed=%v != fixed=%v", tt.Name, changed, fixed)
			continue
		}

		// Should not change if run again.
		out2, fixed2, ok := parseFixPrint(t, tt.Fn, tt.Name+" output", out, true)
		if !ok {
			continue
		}

		if fixed2 {
			t.Errorf("%s: applied fixes during second round", tt.Name)
			continue
		}

		if out2 != out {
			t.Errorf("%s: changed output after second round of fixes.\n--- output after first round\n%s\n--- output after second round\n%s",
				tt.Name, out, out2)
			tdiff(t, out, out2)
		}
	}
}

func tdiff(t *testing.T, a, b string) {
	data, err := diff([]byte(a), []byte(b))
	if err != nil {
		t.Error(err)
		return
	}
	t.Error(string(data))
}


text:
// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"go/ast"
	"go/token"
	"os"
	"reflect"
	"strings"
)

// Partial type checker.
//
// The fact that it is partial is very important: the input is
// an AST and a description of some type information to
// assume about one or more packages, but not all the
// packages that the program imports.  The checker is
// expected to do as much as it can with what it has been
// given.  There is not enough information supplied to do
// a full type check, but the type checker is expected to
// apply information that can be derived from variable
// declarations, function and method returns, and type switches
// as far as it can, so that the caller can still tell the types
// of expression relevant to a particular fix.
//
// TODO(rsc,gri): Replace with go/typechecker.
// Doing that could be an interesting test case for go/typechecker:
// the constraints about working with partial information will
// likely exercise it in interesting ways.  The ideal interface would
// be to pass typecheck a map from importpath to package API text
// (Go source code), but for now we use data structures (TypeConfig, Type).
//
// The strings mostly use gofmt form.
//
// A Field or FieldList has as its type a comma-separated list
// of the types of the fields.  For example, the field list
//	x, y, z int
// has type "int, int, int".

// The prefix "type " is the type of a type.
// For example, given
//	var x int
//	type T int
// x's type is "int" but T's type is "type int".
// mkType inserts the "type " prefix.
// getType removes it.
// isType tests for it.

func mkType(t string) string {
	return "type " + t
}

func getType(t string) string {
	if !isType(t) {
		return ""
	}
	return t[len("type "):]
}

func isType(t string) bool {
	return strings.HasPrefix(t, "type ")
}

// TypeConfig describes the universe of relevant types.
// For ease of creation, the types are all referred to by string
// name (e.g., "reflect.Value").  TypeByName is the only place
// where the strings are resolved.

type TypeConfig struct {
	Type map[string]*Type
	Var  map[string]string
	Func map[string]string
}

// typeof returns the type of the given name, which may be of
// the form "x" or "p.X".
func (cfg *TypeConfig) typeof(name string) string {
	if cfg.Var != nil {
		if t := cfg.Var[name]; t != "" {
			return t
		}
	}
	if cfg.Func != nil {
		if t := cfg.Func[name]; t != "" {
			return "func()" + t
		}
	}
	return ""
}

// Type describes the Fields and Methods of a type.
// If the field or method cannot be found there, it is next
// looked for in the Embed list.
type Type struct {
	Field  map[string]string // map field name to type
	Method map[string]string // map method name to comma-separated return types (should start with "func ")
	Embed  []string          // list of types this type embeds (for extra methods)
	Def    string            // definition of named type
}

// dot returns the type of "typ.name", making its decision
// using the type information in cfg.
func (typ *Type) dot(cfg *TypeConfig, name string) string {
	if typ.Field != nil {
		if t := typ.Field[name]; t != "" {
			return t
		}
	}
	if typ.Method != nil {
		if t := typ.Method[name]; t != "" {
			return t
		}
	}

	for _, e := range typ.Embed {
		etyp := cfg.Type[e]
		if etyp != nil {
			if t := etyp.dot(cfg, name); t != "" {
				return t
			}
		}
	}

	return ""
}

// typecheck type checks the AST f assuming the information in cfg.
// It returns two maps with type information:
// typeof maps AST nodes to type information in gofmt string form.
// assign maps type strings to lists of expressions that were assigned
// to values of another type that were assigned to that type.
func typecheck(cfg *TypeConfig, f *ast.File) (typeof map[interface{}]string, assign map[string][]interface{}) {
	typeof = make(map[interface{}]string)
	assign = make(map[string][]interface{})
	cfg1 := &TypeConfig{}
	*cfg1 = *cfg // make copy so we can add locally
	copied := false

	// gather function declarations
	for _, decl := range f.Decls {
		fn, ok := decl.(*ast.FuncDecl)
		if !ok {
			continue
		}
		typecheck1(cfg, fn.Type, typeof, assign)
		t := typeof[fn.Type]
		if fn.Recv != nil {
			// The receiver must be a type.
			rcvr := typeof[fn.Recv]
			if !isType(rcvr) {
				if len(fn.Recv.List) != 1 {
					continue
				}
				rcvr = mkType(gofmt(fn.Recv.List[0].Type))
				typeof[fn.Recv.List[0].Type] = rcvr
			}
			rcvr = getType(rcvr)
			if rcvr != "" && rcvr[0] == '*' {
				rcvr = rcvr[1:]
			}
			typeof[rcvr+"."+fn.Name.Name] = t
		} else {
			if isType(t) {
				t = getType(t)
			} else {
				t = gofmt(fn.Type)
			}
			typeof[fn.Name] = t

			// Record typeof[fn.Name.Obj] for future references to fn.Name.
			typeof[fn.Name.Obj] = t
		}
	}

	// gather struct declarations
	for _, decl := range f.Decls {
		d, ok := decl.(*ast.GenDecl)
		if ok {
			for _, s := range d.Specs {
				switch s := s.(type) {
				case *ast.TypeSpec:
					if cfg1.Type[s.Name.Name] != nil {
						break
					}
					if !copied {
						copied = true
						// Copy map lazily: it's time.
						cfg1.Type = make(map[string]*Type)
						for k, v := range cfg.Type {
							cfg1.Type[k] = v
						}
					}
					t := &Type{Field: map[string]string{}}
					cfg1.Type[s.Name.Name] = t
					switch st := s.Type.(type) {
					case *ast.StructType:
						for _, f := range st.Fields.List {
							for _, n := range f.Names {
								t.Field[n.Name] = gofmt(f.Type)
							}
						}
					case *ast.ArrayType, *ast.StarExpr, *ast.MapType:
						t.Def = gofmt(st)
					}
				}
			}
		}
	}

	typecheck1(cfg1, f, typeof, assign)
	return typeof, assign
}

func makeExprList(a []*ast.Ident) []ast.Expr {
	var b []ast.Expr
	for _, x := range a {
		b = append(b, x)
	}
	return b
}

// Typecheck1 is the recursive form of typecheck.
// It is like typecheck but adds to the information in typeof
// instead of allocating a new map.
func typecheck1(cfg *TypeConfig, f interface{}, typeof map[interface{}]string, assign map[string][]interface{}) {
	// set sets the type of n to typ.
	// If isDecl is true, n is being declared.
	set := func(n ast.Expr, typ string, isDecl bool) {
		if typeof[n] != "" || typ == "" {
			if typeof[n] != typ {
				assign[typ] = append(assign[typ], n)
			}
			return
		}
		typeof[n] = typ

		// If we obtained typ from the declaration of x
		// propagate the type to all the uses.
		// The !isDecl case is a cheat here, but it makes
		// up in some cases for not paying attention to
		// struct fields.  The real type checker will be
		// more accurate so we won't need the cheat.
		if id, ok := n.(*ast.Ident); ok && id.Obj != nil && (isDecl || typeof[id.Obj] == "") {
			typeof[id.Obj] = typ
		}
	}

	// Type-check an assignment lhs = rhs.
	// If isDecl is true, this is := so we can update
	// the types of the objects that lhs refers to.
	typecheckAssign := func(lhs, rhs []ast.Expr, isDecl bool) {
		if len(lhs) > 1 && len(rhs) == 1 {
			if _, ok := rhs[0].(*ast.CallExpr); ok {
				t := split(typeof[rhs[0]])
				// Lists should have same length but may not; pair what can be paired.
				for i := 0; i < len(lhs) && i < len(t); i++ {
					set(lhs[i], t[i], isDecl)
				}
				return
			}
		}
		if len(lhs) == 1 && len(rhs) == 2 {
			// x = y, ok
			rhs = rhs[:1]
		} else if len(lhs) == 2 && len(rhs) == 1 {
			// x, ok = y
			lhs = lhs[:1]
		}

		// Match as much as we can.
		for i := 0; i < len(lhs) && i < len(rhs); i++ {
			x, y := lhs[i], rhs[i]
			if typeof[y] != "" {
				set(x, typeof[y], isDecl)
			} else {
				set(y, typeof[x], false)
			}
		}
	}

	expand := func(s string) string {
		typ := cfg.Type[s]
		if typ != nil && typ.Def != "" {
			return typ.Def
		}
		return s
	}

	// The main type check is a recursive algorithm implemented
	// by walkBeforeAfter(n, before, after).
	// Most of it is bottom-up, but in a few places we need
	// to know the type of the function we are checking.
	// The before function records that information on
	// the curfn stack.
	var curfn []*ast.FuncType

	before := func(n interface{}) {
		// push function type on stack
		switch n := n.(type) {
		case *ast.FuncDecl:
			curfn = append(curfn, n.Type)
		case *ast.FuncLit:
			curfn = append(curfn, n.Type)
		}
	}

	// After is the real type checker.
	after := func(n interface{}) {
		if n == nil {
			return
		}
		if false && reflect.TypeOf(n).Kind() == reflect.Ptr { // debugging trace
			defer func() {
				if t := typeof[n]; t != "" {
					pos := fset.Position(n.(ast.Node).Pos())
					fmt.Fprintf(os.Stderr, "%s: typeof[%s] = %s\n", pos, gofmt(n), t)
				}
			}()
		}

		switch n := n.(type) {
		case *ast.FuncDecl, *ast.FuncLit:
			// pop function type off stack
			curfn = curfn[:len(curfn)-1]

		case *ast.FuncType:
			typeof[n] = mkType(joinFunc(split(typeof[n.Params]), split(typeof[n.Results])))

		case *ast.FieldList:
			// Field list is concatenation of sub-lists.
			t := ""
			for _, field := range n.List {
				if t != "" {
					t += ", "
				}
				t += typeof[field]
			}
			typeof[n] = t

		case *ast.Field:
			// Field is one instance of the type per name.
			all := ""
			t := typeof[n.Type]
			if !isType(t) {
				// Create a type, because it is typically *T or *p.T
				// and we might care about that type.
				t = mkType(gofmt(n.Type))
				typeof[n.Type] = t
			}
			t = getType(t)
			if len(n.Names) == 0 {
				all = t
			} else {
				for _, id := range n.Names {
					if all != "" {
						all += ", "
					}
					all += t
					typeof[id.Obj] = t
					typeof[id] = t
				}
			}
			typeof[n] = all

		case *ast.ValueSpec:
			// var declaration.  Use type if present.
			if n.Type != nil {
				t := typeof[n.Type]
				if !isType(t) {
					t = mkType(gofmt(n.Type))
					typeof[n.Type] = t
				}
				t = getType(t)
				for _, id := range n.Names {
					set(id, t, true)
				}
			}
			// Now treat same as assignment.
			typecheckAssign(makeExprList(n.Names), n.Values, true)

		case *ast.AssignStmt:
			typecheckAssign(n.Lhs, n.Rhs, n.Tok == token.DEFINE)

		case *ast.Ident:
			// Identifier can take its type from underlying object.
			if t := typeof[n.Obj]; t != "" {
				typeof[n] = t
			}

		case *ast.SelectorExpr:
			// Field or method.
			name := n.Sel.Name
			if t := typeof[n.X]; t != "" {
				if strings.HasPrefix(t, "*") {
					t = t[1:] // implicit *
				}
				if typ := cfg.Type[t]; typ != nil {
					if t := typ.dot(cfg, name); t != "" {
						typeof[n] = t
						return
					}
				}
				tt := typeof[t+"."+name]
				if isType(tt) {
					typeof[n] = getType(tt)
					return
				}
			}
			// Package selector.
			if x, ok := n.X.(*ast.Ident); ok && x.Obj == nil {
				str := x.Name + "." + name
				if cfg.Type[str] != nil {
					typeof[n] = mkType(str)
					return
				}
				if t := cfg.typeof(x.Name + "." + name); t != "" {
					typeof[n] = t
					return
				}
			}

		case *ast.CallExpr:
			// make(T) has type T.
			if isTopName(n.Fun, "make") && len(n.Args) >= 1 {
				typeof[n] = gofmt(n.Args[0])
				return
			}
			// new(T) has type *T
			if isTopName(n.Fun, "new") && len(n.Args) == 1 {
				typeof[n] = "*" + gofmt(n.Args[0])
				return
			}
			// Otherwise, use type of function to determine arguments.
			t := typeof[n.Fun]
			in, out := splitFunc(t)
			if in == nil && out == nil {
				return
			}
			typeof[n] = join(out)
			for i, arg := range n.Args {
				if i >= len(in) {
					break
				}
				if typeof[arg] == "" {
					typeof[arg] = in[i]
				}
			}

		case *ast.TypeAssertExpr:
			// x.(type) has type of x.
			if n.Type == nil {
				typeof[n] = typeof[n.X]
				return
			}
			// x.(T) has type T.
			if t := typeof[n.Type]; isType(t) {
				typeof[n] = getType(t)
			} else {
				typeof[n] = gofmt(n.Type)
			}

		case *ast.SliceExpr:
			// x[i:j] has type of x.
			typeof[n] = typeof[n.X]

		case *ast.IndexExpr:
			// x[i] has key type of x's type.
			t := expand(typeof[n.X])
			if strings.HasPrefix(t, "[") || strings.HasPrefix(t, "map[") {
				// Lazy: assume there are no nested [] in the array
				// length or map key type.
				if i := strings.Index(t, "]"); i >= 0 {
					typeof[n] = t[i+1:]
				}
			}

		case *ast.StarExpr:
			// *x for x of type *T has type T when x is an expr.
			// We don't use the result when *x is a type, but
			// compute it anyway.
			t := expand(typeof[n.X])
			if isType(t) {
				typeof[n] = "type *" + getType(t)
			} else if strings.HasPrefix(t, "*") {
				typeof[n] = t[len("*"):]
			}

		case *ast.UnaryExpr:
			// &x for x of type T has type *T.
			t := typeof[n.X]
			if t != "" && n.Op == token.AND {
				typeof[n] = "*" + t
			}

		case *ast.CompositeLit:
			// T{...} has type T.
			typeof[n] = gofmt(n.Type)

		case *ast.ParenExpr:
			// (x) has type of x.
			typeof[n] = typeof[n.X]

		case *ast.RangeStmt:
			t := expand(typeof[n.X])
			if t == "" {
				return
			}
			var key, value string
			if t == "string" {
				key, value = "int", "rune"
			} else if strings.HasPrefix(t, "[") {
				key = "int"
				if i := strings.Index(t, "]"); i >= 0 {
					value = t[i+1:]
				}
			} else if strings.HasPrefix(t, "map[") {
				if i := strings.Index(t, "]"); i >= 0 {
					key, value = t[4:i], t[i+1:]
				}
			}
			changed := false
			if n.Key != nil && key != "" {
				changed = true
				set(n.Key, key, n.Tok == token.DEFINE)
			}
			if n.Value != nil && value != "" {
				changed = true
				set(n.Value, value, n.Tok == token.DEFINE)
			}
			// Ugly failure of vision: already type-checked body.
			// Do it again now that we have that type info.
			if changed {
				typecheck1(cfg, n.Body, typeof, assign)
			}

		case *ast.TypeSwitchStmt:
			// Type of variable changes for each case in type switch,
			// but go/parser generates just one variable.
			// Repeat type check for each case with more precise
			// type information.
			as, ok := n.Assign.(*ast.AssignStmt)
			if !ok {
				return
			}
			varx, ok := as.Lhs[0].(*ast.Ident)
			if !ok {
				return
			}
			t := typeof[varx]
			for _, cas := range n.Body.List {
				cas := cas.(*ast.CaseClause)
				if len(cas.List) == 1 {
					// Variable has specific type only when there is
					// exactly one type in the case list.
					if tt := typeof[cas.List[0]]; isType(tt) {
						tt = getType(tt)
						typeof[varx] = tt
						typeof[varx.Obj] = tt
						typecheck1(cfg, cas.Body, typeof, assign)
					}
				}
			}
			// Restore t.
			typeof[varx] = t
			typeof[varx.Obj] = t

		case *ast.ReturnStmt:
			if len(curfn) == 0 {
				// Probably can't happen.
				return
			}
			f := curfn[len(curfn)-1]
			res := n.Results
			if f.Results != nil {
				t := split(typeof[f.Results])
				for i := 0; i < len(res) && i < len(t); i++ {
					set(res[i], t[i], false)
				}
			}
		}
	}
	walkBeforeAfter(f, before, after)
}

// Convert between function type strings and lists of types.
// Using strings makes this a little harder, but it makes
// a lot of the rest of the code easier.  This will all go away
// when we can use go/typechecker directly.

// splitFunc splits "func(x,y,z) (a,b,c)" into ["x", "y", "z"] and ["a", "b", "c"].
func splitFunc(s string) (in, out []string) {
	if !strings.HasPrefix(s, "func(") {
		return nil, nil
	}

	i := len("func(") // index of beginning of 'in' arguments
	nparen := 0
	for j := i; j < len(s); j++ {
		switch s[j] {
		case '(':
			nparen++
		case ')':
			nparen--
			if nparen < 0 {
				// found end of parameter list
				out := strings.TrimSpace(s[j+1:])
				if len(out) >= 2 && out[0] == '(' && out[len(out)-1] == ')' {
					out = out[1 : len(out)-1]
				}
				return split(s[i:j]), split(out)
			}
		}
	}
	return nil, nil
}

// joinFunc is the inverse of splitFunc.
func joinFunc(in, out []string) string {
	outs := ""
	if len(out) == 1 {
		outs = " " + out[0]
	} else if len(out) > 1 {
		outs = " (" + join(out) + ")"
	}
	return "func(" + join(in) + ")" + outs
}

// split splits "int, float" into ["int", "float"] and splits "" into [].
func split(s string) []string {
	out := []string{}
	i := 0 // current type being scanned is s[i:j].
	nparen := 0
	for j := 0; j < len(s); j++ {
		switch s[j] {
		case ' ':
			if i == j {
				i++
			}
		case '(':
			nparen++
		case ')':
			nparen--
			if nparen < 0 {
				// probably can't happen
				return nil
			}
		case ',':
			if nparen == 0 {
				if i < j {
					out = append(out, s[i:j])
				}
				i = j + 1
			}
		}
	}
	if nparen != 0 {
		// probably can't happen
		return nil
	}
	if i < len(s) {
		out = append(out, s[i:])
	}
	return out
}

// join is the inverse of split.
func join(x []string) string {
	return strings.Join(x, ", ")
}


text:
// Copyright 2016 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 main

func init() {
	addTestCases(aeTests, nil)
}

var aeTests = []testCase{
	// Collection of fixes:
	//	- imports
	//	- appengine.Timeout -> context.WithTimeout
	//	- add ctx arg to appengine.Datacenter
	//	- logging API
	{
		Name: "ae.0",
		In: `package foo

import (
	"net/http"
	"time"

	"appengine"
	"appengine/datastore"
)

func f(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	c = appengine.Timeout(c, 5*time.Second)
	err := datastore.ErrNoSuchEntity
	c.Errorf("Something interesting happened: %v", err)
	_ = appengine.Datacenter()
}
`,
		Out: `package foo

import (
	"net/http"
	"time"

	"golang.org/x/net/context"
	"google.golang.org/appengine"
	"google.golang.org/appengine/datastore"
	"google.golang.org/appengine/log"
)

func f(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	c, _ = context.WithTimeout(c, 5*time.Second)
	err := datastore.ErrNoSuchEntity
	log.Errorf(c, "Something interesting happened: %v", err)
	_ = appengine.Datacenter(c)
}
`,
	},

	// Updating a function that takes an appengine.Context arg.
	{
		Name: "ae.1",
		In: `package foo

import (
	"appengine"
)

func LogSomething(c2 appengine.Context) {
	c2.Warningf("Stand back! I'm going to try science!")
}
`,
		Out: `package foo

import (
	"golang.org/x/net/context"
	"google.golang.org/appengine/log"
)

func LogSomething(c2 context.Context) {
	log.Warningf(c2, "Stand back! I'm going to try science!")
}
`,
	},

	// Less widely used API changes:
	//	- drop maxTasks arg to taskqueue.QueueStats
	{
		Name: "ae.2",
		In: `package foo

import (
	"appengine"
	"appengine/taskqueue"
)

func f(ctx appengine.Context) {
	stats, err := taskqueue.QueueStats(ctx, []string{"one", "two"}, 0)
}
`,
		Out: `package foo

import (
	"golang.org/x/net/context"
	"google.golang.org/appengine/taskqueue"
)

func f(ctx context.Context) {
	stats, err := taskqueue.QueueStats(ctx, []string{"one", "two"})
}
`,
	},

	// Check that the main "appengine" import will not be dropped
	// if an appengine.Context -> context.Context change happens
	// but the appengine package is still referenced.
	{
		Name: "ae.3",
		In: `package foo

import (
	"appengine"
	"io"
)

func f(ctx appengine.Context, w io.Writer) {
	_ = appengine.IsDevAppServer()
}
`,
		Out: `package foo

import (
	"golang.org/x/net/context"
	"google.golang.org/appengine"
	"io"
)

func f(ctx context.Context, w io.Writer) {
	_ = appengine.IsDevAppServer()
}
`,
	},
}


text:
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/scanner"
	"go/token"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strings"
)

var (
	fset     = token.NewFileSet()
	exitCode = 0
)

var allowedRewrites = flag.String("r", "",
	"restrict the rewrites to this comma-separated list")

var forceRewrites = flag.String("force", "",
	"force these fixes to run even if the code looks updated")

var allowed, force map[string]bool

var doDiff = flag.Bool("diff", false, "display diffs instead of rewriting files")

// enable for debugging fix failures
const debug = false // display incorrectly reformatted source and exit

func usage() {
	fmt.Fprintf(os.Stderr, "usage: aefix [-diff] [-r fixname,...] [-force fixname,...] [path ...]\n")
	flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, "\nAvailable rewrites are:\n")
	sort.Sort(byName(fixes))
	for _, f := range fixes {
		fmt.Fprintf(os.Stderr, "\n%s\n", f.name)
		desc := strings.TrimSpace(f.desc)
		desc = strings.Replace(desc, "\n", "\n\t", -1)
		fmt.Fprintf(os.Stderr, "\t%s\n", desc)
	}
	os.Exit(2)
}

func main() {
	flag.Usage = usage
	flag.Parse()

	sort.Sort(byDate(fixes))

	if *allowedRewrites != "" {
		allowed = make(map[string]bool)
		for _, f := range strings.Split(*allowedRewrites, ",") {
			allowed[f] = true
		}
	}

	if *forceRewrites != "" {
		force = make(map[string]bool)
		for _, f := range strings.Split(*forceRewrites, ",") {
			force[f] = true
		}
	}

	if flag.NArg() == 0 {
		if err := processFile("standard input", true); err != nil {
			report(err)
		}
		os.Exit(exitCode)
	}

	for i := 0; i < flag.NArg(); i++ {
		path := flag.Arg(i)
		switch dir, err := os.Stat(path); {
		case err != nil:
			report(err)
		case dir.IsDir():
			walkDir(path)
		default:
			if err := processFile(path, false); err != nil {
				report(err)
			}
		}
	}

	os.Exit(exitCode)
}

const parserMode = parser.ParseComments

func gofmtFile(f *ast.File) ([]byte, error) {
	var buf bytes.Buffer
	if err := format.Node(&buf, fset, f); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

func processFile(filename string, useStdin bool) error {
	var f *os.File
	var err error
	var fixlog bytes.Buffer

	if useStdin {
		f = os.Stdin
	} else {
		f, err = os.Open(filename)
		if err != nil {
			return err
		}
		defer f.Close()
	}

	src, err := ioutil.ReadAll(f)
	if err != nil {
		return err
	}

	file, err := parser.ParseFile(fset, filename, src, parserMode)
	if err != nil {
		return err
	}

	// Apply all fixes to file.
	newFile := file
	fixed := false
	for _, fix := range fixes {
		if allowed != nil && !allowed[fix.name] {
			continue
		}
		if fix.f(newFile) {
			fixed = true
			fmt.Fprintf(&fixlog, " %s", fix.name)

			// AST changed.
			// Print and parse, to update any missing scoping
			// or position information for subsequent fixers.
			newSrc, err := gofmtFile(newFile)
			if err != nil {
				return err
			}
			newFile, err = parser.ParseFile(fset, filename, newSrc, parserMode)
			if err != nil {
				if debug {
					fmt.Printf("%s", newSrc)
					report(err)
					os.Exit(exitCode)
				}
				return err
			}
		}
	}
	if !fixed {
		return nil
	}
	fmt.Fprintf(os.Stderr, "%s: fixed %s\n", filename, fixlog.String()[1:])

	// Print AST.  We did that after each fix, so this appears
	// redundant, but it is necessary to generate gofmt-compatible
	// source code in a few cases.  The official gofmt style is the
	// output of the printer run on a standard AST generated by the parser,
	// but the source we generated inside the loop above is the
	// output of the printer run on a mangled AST generated by a fixer.
	newSrc, err := gofmtFile(newFile)
	if err != nil {
		return err
	}

	if *doDiff {
		data, err := diff(src, newSrc)
		if err != nil {
			return fmt.Errorf("computing diff: %s", err)
		}
		fmt.Printf("diff %s fixed/%s\n", filename, filename)
		os.Stdout.Write(data)
		return nil
	}

	if useStdin {
		os.Stdout.Write(newSrc)
		return nil
	}

	return ioutil.WriteFile(f.Name(), newSrc, 0)
}

var gofmtBuf bytes.Buffer

func gofmt(n interface{}) string {
	gofmtBuf.Reset()
	if err := format.Node(&gofmtBuf, fset, n); err != nil {
		return "<" + err.Error() + ">"
	}
	return gofmtBuf.String()
}

func report(err error) {
	scanner.PrintError(os.Stderr, err)
	exitCode = 2
}

func walkDir(path string) {
	filepath.Walk(path, visitFile)
}

func visitFile(path string, f os.FileInfo, err error) error {
	if err == nil && isGoFile(f) {
		err = processFile(path, false)
	}
	if err != nil {
		report(err)
	}
	return nil
}

func isGoFile(f os.FileInfo) bool {
	// ignore non-Go files
	name := f.Name()
	return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
}

func diff(b1, b2 []byte) (data []byte, err error) {
	f1, err := ioutil.TempFile("", "go-fix")
	if err != nil {
		return nil, err
	}
	defer os.Remove(f1.Name())
	defer f1.Close()

	f2, err := ioutil.TempFile("", "go-fix")
	if err != nil {
		return nil, err
	}
	defer os.Remove(f2.Name())
	defer f2.Close()

	f1.Write(b1)
	f2.Write(b2)

	data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
	if len(data) > 0 {
		// diff exits with a non-zero status when the files don't match.
		// Ignore that failure as long as we get output.
		err = nil
	}
	return
}


text:
// Copyright 2016 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 main

import (
	"go/ast"
	"path"
	"strconv"
	"strings"
)

const (
	ctxPackage = "golang.org/x/net/context"

	newPackageBase = "google.golang.org/"
	stutterPackage = false
)

func init() {
	register(fix{
		"ae",
		"2016-04-15",
		aeFn,
		`Update old App Engine APIs to new App Engine APIs`,
	})
}

// logMethod is the set of methods on appengine.Context used for logging.
var logMethod = map[string]bool{
	"Debugf":    true,
	"Infof":     true,
	"Warningf":  true,
	"Errorf":    true,
	"Criticalf": true,
}

// mapPackage turns "appengine" into "google.golang.org/appengine", etc.
func mapPackage(s string) string {
	if stutterPackage {
		s += "/" + path.Base(s)
	}
	return newPackageBase + s
}

func aeFn(f *ast.File) bool {
	// During the walk, we track the last thing seen that looks like
	// an appengine.Context, and reset it once the walk leaves a func.
	var lastContext *ast.Ident

	fixed := false

	// Update imports.
	mainImp := "appengine"
	for _, imp := range f.Imports {
		pth, _ := strconv.Unquote(imp.Path.Value)
		if pth == "appengine" || strings.HasPrefix(pth, "appengine/") {
			newPth := mapPackage(pth)
			imp.Path.Value = strconv.Quote(newPth)
			fixed = true

			if pth == "appengine" {
				mainImp = newPth
			}
		}
	}

	// Update any API changes.
	walk(f, func(n interface{}) {
		if ft, ok := n.(*ast.FuncType); ok && ft.Params != nil {
			// See if this func has an `appengine.Context arg`.
			// If so, remember its identifier.
			for _, param := range ft.Params.List {
				if !isPkgDot(param.Type, "appengine", "Context") {
					continue
				}
				if len(param.Names) == 1 {
					lastContext = param.Names[0]
					break
				}
			}
			return
		}

		if as, ok := n.(*ast.AssignStmt); ok {
			if len(as.Lhs) == 1 && len(as.Rhs) == 1 {
				// If this node is an assignment from an appengine.NewContext invocation,
				// remember the identifier on the LHS.
				if isCall(as.Rhs[0], "appengine", "NewContext") {
					if ident, ok := as.Lhs[0].(*ast.Ident); ok {
						lastContext = ident
						return
					}
				}
				// x (=|:=) appengine.Timeout(y, z)
				//   should become
				// x, _ (=|:=) context.WithTimeout(y, z)
				if isCall(as.Rhs[0], "appengine", "Timeout") {
					addImport(f, ctxPackage)
					as.Lhs = append(as.Lhs, ast.NewIdent("_"))
					// isCall already did the type checking.
					sel := as.Rhs[0].(*ast.CallExpr).Fun.(*ast.SelectorExpr)
					sel.X = ast.NewIdent("context")
					sel.Sel = ast.NewIdent("WithTimeout")
					fixed = true
					return
				}
			}
			return
		}

		// If this node is a FuncDecl, we've finished the function, so reset lastContext.
		if _, ok := n.(*ast.FuncDecl); ok {
			lastContext = nil
			return
		}

		if call, ok := n.(*ast.CallExpr); ok {
			if isPkgDot(call.Fun, "appengine", "Datacenter") && len(call.Args) == 0 {
				insertContext(f, call, lastContext)
				fixed = true
				return
			}
			if isPkgDot(call.Fun, "taskqueue", "QueueStats") && len(call.Args) == 3 {
				call.Args = call.Args[:2] // drop last arg
				fixed = true
				return
			}

			sel, ok := call.Fun.(*ast.SelectorExpr)
			if !ok {
				return
			}
			if lastContext != nil && refersTo(sel.X, lastContext) && logMethod[sel.Sel.Name] {
				// c.Errorf(...)
				//   should become
				// log.Errorf(c, ...)
				addImport(f, mapPackage("appengine/log"))
				sel.X = &ast.Ident{ // ast.NewIdent doesn't preserve the position.
					NamePos: sel.X.Pos(),
					Name:    "log",
				}
				insertContext(f, call, lastContext)
				fixed = true
				return
			}
		}
	})

	// Change any `appengine.Context` to `context.Context`.
	// Do this in a separate walk because the previous walk
	// wants to identify "appengine.Context".
	walk(f, func(n interface{}) {
		expr, ok := n.(ast.Expr)
		if ok && isPkgDot(expr, "appengine", "Context") {
			addImport(f, ctxPackage)
			// isPkgDot did the type checking.
			n.(*ast.SelectorExpr).X.(*ast.Ident).Name = "context"
			fixed = true
			return
		}
	})

	// The changes above might remove the need to import "appengine".
	// Check if it's used, and drop it if it isn't.
	if fixed && !usesImport(f, mainImp) {
		deleteImport(f, mainImp)
	}

	return fixed
}

// ctx may be nil.
func insertContext(f *ast.File, call *ast.CallExpr, ctx *ast.Ident) {
	if ctx == nil {
		// context is unknown, so use a plain "ctx".
		ctx = ast.NewIdent("ctx")
	} else {
		// Create a fresh *ast.Ident so we drop the position information.
		ctx = ast.NewIdent(ctx.Name)
	}

	call.Args = append([]ast.Expr{ctx}, call.Args...)
}