Merge branch 'master' into merge-qa
diff --git a/aetest/instance_vm.go b/aetest/instance_vm.go
index 89ff8b1..d2e5d29 100644
--- a/aetest/instance_vm.go
+++ b/aetest/instance_vm.go
@@ -192,6 +192,11 @@
 		return err
 	}
 
+	datastorePath := os.Getenv("APPENGINE_DEV_APPSERVER_DATASTORE_PATH")
+	if len(datastorePath) == 0 {
+		datastorePath = filepath.Join(i.appDir, "datastore")
+	}
+
 	appserverArgs = append(appserverArgs,
 		"--port=0",
 		"--api_port=0",
@@ -200,7 +205,7 @@
 		"--skip_sdk_update_check=true",
 		"--clear_datastore=true",
 		"--clear_search_indexes=true",
-		"--datastore_path", filepath.Join(i.appDir, "datastore"),
+		"--datastore_path", datastorePath,
 	)
 	if i.opts != nil && i.opts.StronglyConsistentDatastore {
 		appserverArgs = append(appserverArgs, "--datastore_consistency_policy=consistent")
diff --git a/appengine.go b/appengine.go
index 8c96976..f65f94a 100644
--- a/appengine.go
+++ b/appengine.go
@@ -54,6 +54,9 @@
 	internal.Main()
 }
 
+// Middleware wraps an http handler so that it can make GAE API calls
+var Middleware func(http.Handler) http.Handler = internal.Middleware
+
 // IsDevAppServer reports whether the App Engine app is running in the
 // development App Server.
 func IsDevAppServer() bool {
diff --git a/appengine_vm.go b/appengine_vm.go
index f4b645a..4893e52 100644
--- a/appengine_vm.go
+++ b/appengine_vm.go
@@ -13,8 +13,6 @@
 )
 
 // BackgroundContext returns a context not associated with a request.
-// This should only be used when not servicing a request.
-// This only works in App Engine "flexible environment".
 func BackgroundContext() context.Context {
 	return internal.BackgroundContext()
 }
diff --git a/internal/api.go b/internal/api.go
index 2748318..7be64e2 100644
--- a/internal/api.go
+++ b/internal/api.go
@@ -87,88 +87,98 @@
 	}
 }
 
-func handleHTTP(w http.ResponseWriter, r *http.Request) {
-	c := &context{
-		req:       r,
-		outHeader: w.Header(),
-		apiURL:    apiURL(),
-	}
-	r = r.WithContext(withContext(r.Context(), c))
-	c.req = r
-
-	stopFlushing := make(chan int)
-
-	// 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")
-	}
-
-	if logToLogservice() {
-		// 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
-
-	flushed := make(chan struct{})
-	if logToLogservice() {
-		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 func() {
-			defer close(flushed)
-			// Force a log flush, because with very short requests we
-			// may not ever flush logs.
-			c.flushLog(true)
-		}()
-		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)
-	}
-	if logToLogservice() {
-		// Wait for the last flush to complete before returning,
-		// otherwise the security ticket will not be valid.
-		<-flushed
-	}
+// Middleware wraps an http handler so that it can make GAE API calls
+func Middleware(next http.Handler) http.Handler {
+	return handleHTTPMiddleware(executeRequestSafelyMiddleware(next))
 }
 
-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
+func handleHTTPMiddleware(next http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		c := &context{
+			req:       r,
+			outHeader: w.Header(),
+			apiURL:    apiURL(),
 		}
-	}()
+		r = r.WithContext(withContext(r.Context(), c))
+		c.req = r
 
-	http.DefaultServeMux.ServeHTTP(c, r)
+		stopFlushing := make(chan int)
+
+		// 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")
+		}
+
+		if logToLogservice() {
+			// 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)
+		}
+
+		next.ServeHTTP(c, r)
+		c.outHeader = nil // make sure header changes aren't respected any more
+
+		flushed := make(chan struct{})
+		if logToLogservice() {
+			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 func() {
+				defer close(flushed)
+				// Force a log flush, because with very short requests we
+				// may not ever flush logs.
+				c.flushLog(true)
+			}()
+			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)
+		}
+		if logToLogservice() {
+			// Wait for the last flush to complete before returning,
+			// otherwise the security ticket will not be valid.
+			<-flushed
+		}
+	})
+}
+
+func executeRequestSafelyMiddleware(next http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		defer func() {
+			if x := recover(); x != nil {
+				c := w.(*context)
+				logf(c, 4, "%s", renderPanic(x)) // 4 == critical
+				c.outCode = 500
+			}
+		}()
+
+		next.ServeHTTP(w, r)
+	})
 }
 
 func renderPanic(x interface{}) string {
diff --git a/internal/api_classic.go b/internal/api_classic.go
index f0f40b2..a9beece 100644
--- a/internal/api_classic.go
+++ b/internal/api_classic.go
@@ -144,8 +144,8 @@
 	return err
 }
 
-func handleHTTP(w http.ResponseWriter, r *http.Request) {
-	panic("handleHTTP called; this should be impossible")
+func Middleware(next http.Handler) http.Handler {
+	panic("Middleware called; this should be impossible")
 }
 
 func logf(c appengine.Context, level int64, format string, args ...interface{}) {
diff --git a/internal/api_test.go b/internal/api_test.go
index 5b025cf..d4af31b 100644
--- a/internal/api_test.go
+++ b/internal/api_test.go
@@ -302,7 +302,7 @@
 			handled := make(chan struct{})
 			go func() {
 				defer close(handled)
-				handleHTTP(w, r)
+				Middleware(http.DefaultServeMux).ServeHTTP(w, r)
 			}()
 			// Check that the log flush eventually comes in.
 			time.Sleep(1200 * time.Millisecond)
@@ -360,7 +360,7 @@
 			}
 			w := httptest.NewRecorder()
 
-			handleHTTP(w, r)
+			Middleware(http.DefaultServeMux).ServeHTTP(w, r)
 			const hdr = "X-AppEngine-Log-Flush-Count"
 			if got := w.HeaderMap.Get(hdr); got != tc.wantHeader {
 				t.Errorf("%s header = %q, want %q", hdr, got, tc.wantHeader)
@@ -403,7 +403,7 @@
 			Header: tc.headers,
 			Body:   ioutil.NopCloser(bytes.NewReader(nil)),
 		}
-		handleHTTP(httptest.NewRecorder(), r)
+		Middleware(http.DefaultServeMux).ServeHTTP(httptest.NewRecorder(), r)
 		if addr != tc.addr {
 			t.Errorf("Header %v, got %q, want %q", tc.headers, addr, tc.addr)
 		}
@@ -420,7 +420,7 @@
 		Body:   ioutil.NopCloser(bytes.NewReader(nil)),
 	}
 	rec := httptest.NewRecorder()
-	handleHTTP(rec, r)
+	Middleware(http.DefaultServeMux).ServeHTTP(rec, r)
 	if rec.Code != 500 {
 		t.Errorf("Panicking handler returned HTTP %d, want HTTP %d", rec.Code, 500)
 	}
diff --git a/internal/main_vm.go b/internal/main_vm.go
index ddb79a3..2c53daf 100644
--- a/internal/main_vm.go
+++ b/internal/main_vm.go
@@ -29,7 +29,7 @@
 	if IsDevAppServer() {
 		host = "127.0.0.1"
 	}
-	if err := http.ListenAndServe(host+":"+port, http.HandlerFunc(handleHTTP)); err != nil {
+	if err := http.ListenAndServe(host+":"+port, Middleware(http.DefaultServeMux)); err != nil {
 		log.Fatalf("http.ListenAndServe: %v", err)
 	}
 }
diff --git a/urlfetch/urlfetch.go b/urlfetch/urlfetch.go
index 6ffe1e6..8d44bfe 100644
--- a/urlfetch/urlfetch.go
+++ b/urlfetch/urlfetch.go
@@ -44,11 +44,10 @@
 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.
+// client 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.
+// Any deadline of the provided context will be used for requests through this client.
+// If the client does not have a deadline, then an App Engine default of 60 second is used.
 func Client(ctx context.Context) *http.Client {
 	return &http.Client{
 		Transport: &Transport{
diff --git a/v2/appengine.go b/v2/appengine.go
index 58a52c1..b2ab1aa 100644
--- a/v2/appengine.go
+++ b/v2/appengine.go
@@ -135,8 +135,6 @@
 }
 
 // BackgroundContext returns a context not associated with a request.
-// This should only be used when not servicing a request.
-// This only works in App Engine "flexible environment".
 func BackgroundContext() context.Context {
 	return internal.BackgroundContext()
 }