| Index: tools/chromeproxy_testserver/server.go
|
| diff --git a/tools/chromeproxy_testserver/server.go b/tools/chromeproxy_testserver/server.go
|
| deleted file mode 100644
|
| index c40bc5ee04fcfa75d784a137ff2f56ec614082d5..0000000000000000000000000000000000000000
|
| --- a/tools/chromeproxy_testserver/server.go
|
| +++ /dev/null
|
| @@ -1,159 +0,0 @@
|
| -// Test server to facilitate the data reduction proxy Telemetry tests.
|
| -//
|
| -// The server runs at http://chromeproxy-test.appspot.com/. Please contact
|
| -// people in OWNERS for server issues.
|
| -//
|
| -// For running an AppEngine Go server, see:
|
| -// https://developers.google.com/appengine/docs/go/gettingstarted/introduction.
|
| -//
|
| -// The goal is to keep the test logic on the client side (Telemetry)
|
| -// as much as possible. This server will only return a resource
|
| -// and/or override the response as specified by the data encoded
|
| -// in the request URL queries.
|
| -//
|
| -// For example, on receiving the query
|
| -// /default?respBody=bmV3IGJvZHk=&respHeader=eyJWaWEiOlsiVmlhMSIsIlZpYTIiXX0%3D&respStatus=204
|
| -// the server sends back a response with
|
| -// Status code: 204
|
| -// Additional response headers: "Via: Via1" and "Via: Via2"
|
| -// Response body: "new body"
|
| -// where the overriding headers and body are base64 encoded in the request query.
|
| -
|
| -package server
|
| -
|
| -import (
|
| - "bytes"
|
| - "encoding/base64"
|
| - "encoding/json"
|
| - "errors"
|
| - "fmt"
|
| - "io"
|
| - "net/http"
|
| - "os"
|
| - "strconv"
|
| -)
|
| -
|
| -func init() {
|
| - http.HandleFunc("/requestHeader", requestHeader)
|
| - http.HandleFunc("/resource", resource)
|
| - http.HandleFunc("/default", defaultResponse)
|
| -}
|
| -
|
| -// requestHander returns request headers in response body as text.
|
| -func requestHeader(w http.ResponseWriter, r *http.Request) {
|
| - r.Header.Write(w)
|
| -}
|
| -
|
| -// resource returns the content of a data file specified by "r=" query as the response body.
|
| -// The response could be overridden by request queries.
|
| -// See parseOverrideQuery.
|
| -func resource(w http.ResponseWriter, r *http.Request) {
|
| - wroteBody, err := applyOverride(w, r)
|
| - if err != nil || wroteBody {
|
| - return
|
| - }
|
| - path, ok := r.URL.Query()["r"]
|
| - if !ok || len(path) != 1 {
|
| - w.WriteHeader(http.StatusBadRequest)
|
| - w.Write([]byte("no resource in query"))
|
| - return
|
| - }
|
| - if _, err := writeFromFile(w, path[0]); err != nil {
|
| - w.WriteHeader(http.StatusBadRequest)
|
| - w.Write([]byte(fmt.Sprintf("Failed to get %s: %v", path[0], err)))
|
| - return
|
| - }
|
| -}
|
| -
|
| -// defaultResponse returns "ok" as response body, if the body is not overridden.
|
| -// The response could be overridden by request queries.
|
| -// See parseOverrideQuery.
|
| -func defaultResponse(w http.ResponseWriter, r *http.Request) {
|
| - wroteBody, err := applyOverride(w, r)
|
| - if err != nil {
|
| - return
|
| - }
|
| - if !wroteBody {
|
| - w.Write([]byte("ok"))
|
| - }
|
| -}
|
| -
|
| -type override struct {
|
| - status int
|
| - header http.Header
|
| - body io.Reader
|
| -}
|
| -
|
| -// parseOverrideQuery parses the queries in r and returns an override.
|
| -// It supports the following queries:
|
| -// "respStatus": an integer to override response status code;
|
| -// "respHeader": base64 encoded JSON data to override the response headers;
|
| -// "respBody": base64 encoded JSON data to override the response body.
|
| -func parseOverrideQuery(r *http.Request) (*override, error) {
|
| - q := r.URL.Query()
|
| - resp := &override{0, nil, nil}
|
| - if v, ok := q["respStatus"]; ok && len(v) == 1 && len(v[0]) > 0 {
|
| - status, err := strconv.ParseInt(v[0], 10, 0)
|
| - if err != nil {
|
| - return nil, errors.New(fmt.Sprintf("respStatus: %v", err))
|
| - }
|
| - resp.status = int(status)
|
| - }
|
| - if v, ok := q["respHeader"]; ok && len(v) == 1 && len(v[0]) > 0 {
|
| - // Example header after base64 decoding:
|
| - // {"Via": ["Telemetry Test", "Test2"], "Name": ["XYZ"], "Cache-Control": ["public"]}
|
| - headerValue, err := base64.URLEncoding.DecodeString(v[0])
|
| - if err != nil {
|
| - return nil, errors.New(fmt.Sprintf("Decoding respHeader: %v", err))
|
| - }
|
| - var header http.Header
|
| - err = json.Unmarshal(headerValue, &header)
|
| - if err != nil {
|
| - return nil, errors.New(
|
| - fmt.Sprintf("Unmarlshal (%s) error: %v", string(headerValue), err))
|
| - }
|
| - resp.header = header
|
| - }
|
| - if v, ok := q["respBody"]; ok && len(v) == 1 && len(v[0]) > 0 {
|
| - body, err := base64.URLEncoding.DecodeString(v[0])
|
| - if err != nil {
|
| - return nil, errors.New(
|
| - fmt.Sprintf("Decoding respBody error: %v", err))
|
| - }
|
| - resp.body = bytes.NewBuffer(body)
|
| - }
|
| - return resp, nil
|
| -}
|
| -
|
| -// applyOverride applies the override queries in r to w and returns whether the response
|
| -// body is overridden.
|
| -func applyOverride(w http.ResponseWriter, r *http.Request) (wroteBody bool, err error) {
|
| - resp, err := parseOverrideQuery(r)
|
| - if err != nil {
|
| - w.WriteHeader(http.StatusBadRequest)
|
| - w.Write([]byte(err.Error()))
|
| - return false, err
|
| - }
|
| - headers := w.Header()
|
| - if resp.header != nil {
|
| - for k, v := range resp.header {
|
| - headers[k] = v
|
| - }
|
| - }
|
| - if resp.status > 0 {
|
| - w.WriteHeader(resp.status)
|
| - }
|
| - if resp.body != nil {
|
| - _, err := io.Copy(w, resp.body)
|
| - return true, err
|
| - }
|
| - return false, nil
|
| -}
|
| -
|
| -func writeFromFile(w io.Writer, filename string) (int64, error) {
|
| - f, err := os.Open(filename)
|
| - if err != nil {
|
| - return 0, err
|
| - }
|
| - return io.Copy(w, f)
|
| -}
|
|
|