playground: limit snippet size

Change-Id: If8c35f3f11e65f3ef4185aa125aad57cd14d0beb
Reviewed-on: https://go-review.googlesource.com/3070
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/app/goplay/share.go b/app/goplay/share.go
index d06d6c1..62ca356 100644
--- a/app/goplay/share.go
+++ b/app/goplay/share.go
@@ -5,18 +5,21 @@
 package goplay
 
 import (
-	"appengine"
-	"appengine/datastore"
 	"bytes"
 	"crypto/sha1"
 	"encoding/base64"
 	"fmt"
 	"io"
 	"net/http"
+
+	"appengine"
+	"appengine/datastore"
 )
 
 const salt = "[replace this with something unique]"
 
+const maxSnippetSize = 1 << 16 // 64KB
+
 type Snippet struct {
 	Body []byte
 }
@@ -43,13 +46,17 @@
 	c := appengine.NewContext(r)
 
 	var body bytes.Buffer
-	_, err := body.ReadFrom(r.Body)
+	_, err := io.Copy(&body, io.LimitReader(r.Body, maxSnippetSize+1))
+	r.Body.Close()
 	if err != nil {
 		c.Errorf("reading Body: %v", err)
 		http.Error(w, "Server Error", http.StatusInternalServerError)
 		return
 	}
-	r.Body.Close()
+	if body.Len() > maxSnippetSize {
+		http.Error(w, "Snippet is too large", http.StatusRequestEntityTooLarge)
+		return
+	}
 
 	snip := &Snippet{Body: body.Bytes()}
 	id := snip.Id()