Example #1
0
func (self Blog) ServeHTTP(w http.ResponseWriter, r *http.Request) {

	tpl, err := template.ParseFiles(self.TplPath)
	if err != nil {
		log.Fatal(err)
	}

	// data is the template data for the Blog.
	data := struct {
		// Posts is the slice of posts for this blog page.
		Posts []post
	}{}

	// Pull out {…} variables from muxer.
	vars := mux.Vars(r)

	switch mux.CurrentRoute(r).GetName() {
	case "post":
		data.Posts = make([]post, 1)
		newPost, err := self.getPost(vars["year"], vars["month"],
			vars["day"], vars["name"])
		if err != nil {
			log.Fatal(err)
		}
		data.Posts[0] = *newPost
	default:
		data.Posts, err = self.getPage(0)
	}

	tpl.Execute(w, data)
}
Example #2
0
func getPasteRawHandler(o Model, w http.ResponseWriter, r *http.Request) {
	p := o.(*Paste)
	mime := "text/plain"
	ext := "txt"
	if mux.CurrentRoute(r).GetName() == "download" {
		lang := p.Language
		if lang != nil {
			if len(lang.MIMETypes) > 0 {
				mime = lang.MIMETypes[0]
			}

			if len(lang.Extensions) > 0 {
				ext = lang.Extensions[0]
			}
		}

		filename := p.ID.String()
		if p.Title != "" {
			filename = p.Title
		}
		w.Header().Set("Content-Disposition", "attachment; filename=\""+filename+"."+ext+"\"")
		w.Header().Set("Content-Transfer-Encoding", "binary")
	}
	w.Header().Set("Content-Security-Policy", "default-src 'none'")
	w.Header().Set("Content-Type", mime+"; charset=utf-8")

	reader, _ := p.Reader()
	defer reader.Close()
	io.Copy(w, reader)
}
Example #3
0
func (sc *ServerConfig) metadata(w http.ResponseWriter, req *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	vars := mux.Vars(req)
	clientIp := sc.requestIp(req)

	version := vars["version"]
	wait := mux.CurrentRoute(req).GetName() == "Wait"
	oldValue := vars["oldValue"]
	maxWait, _ := strconv.Atoi(req.URL.Query().Get("maxWait"))

	answers := sc.answers()
	_, ok := answers[version]
	if !ok {
		// If a `latest` key is not provided, pick the ASCII-betically highest version and call it that.
		if version == "latest" {
			version = ""
			for _, k := range answers.Versions() {
				if k > version {
					version = k
				}
			}

			logrus.Debugf("Picked %s for latest version because none provided", version)
		} else {
			respondError(w, req, "Invalid version", http.StatusNotFound)
			return
		}
	}

	path := strings.TrimRight(req.URL.EscapedPath()[1:], "/")
	pathSegments := strings.Split(path, "/")[1:]
	displayKey := ""
	var err error
	for i := 0; err == nil && i < len(pathSegments); i++ {
		displayKey += "/" + pathSegments[i]
		pathSegments[i], err = url.QueryUnescape(pathSegments[i])
	}

	if err != nil {
		respondError(w, req, err.Error(), http.StatusBadRequest)
		return
	}

	logrus.WithFields(logrus.Fields{
		"version":  version,
		"client":   clientIp,
		"wait":     wait,
		"oldValue": oldValue,
		"maxWait":  maxWait}).Debugf("Searching for: %s", displayKey)
	val, ok := sc.lookupAnswer(wait, oldValue, version, clientIp, pathSegments, time.Duration(maxWait)*time.Second)

	if ok {
		logrus.WithFields(logrus.Fields{"version": version, "client": clientIp}).Debugf("OK: %s", displayKey)
		respondSuccess(w, req, val)
	} else {
		logrus.WithFields(logrus.Fields{"version": version, "client": clientIp}).Infof("Error: %s", displayKey)
		respondError(w, req, "Not found", http.StatusNotFound)
	}
}
Example #4
0
func BeforeAPICall(app string, r *http.Request) {
	c := &Call{
		App:         app,
		Host:        hostname,
		RemoteAddr:  r.RemoteAddr,
		UserAgent:   r.UserAgent(),
		URL:         r.URL.String(),
		HTTPMethod:  r.Method,
		Route:       mux.CurrentRoute(r).GetName(),
		RouteParams: mapStringStringAsParams(mux.Vars(r)),
		QueryParams: mapStringSliceOfStringAsParams(r.URL.Query()),
		Start:       time.Now().In(time.UTC),
	}
	if parentCallID, ok := GetParentCallID(r); ok {
		c.ParentCallID = nnz.Int64(parentCallID)
	}
	if CurrentUser != nil {
		c.UID = nnz.Int(CurrentUser(r))
	}

	err := insertCall(c)
	if err != nil {
		log.Printf("insertCall failed: %s", err)
	}
	setCallID(r, c.ID)
}
Example #5
0
func (nd *NegroniDog) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	start := time.Now()
	next(rw, r)

	statPrefix := "http"
	if mux.CurrentRoute(r) != nil && mux.CurrentRoute(r).GetName() != "" {
		statPrefix += "." + mux.CurrentRoute(r).GetName()
	}

	//resp time
	responseTime := time.Since(start)
	statName := strings.Join([]string{statPrefix, "resp_time"}, ".")
	nd.Cli.Histogram(statName, responseTime.Seconds(), nil, 1)
	//resp code
	statName = strings.Join([]string{statPrefix, "status_code", strconv.Itoa(rw.(negroni.ResponseWriter).Status())}, ".")
	nd.Cli.Count(statName, 1, nil, 1)

}
Example #6
0
// TrackAPICall wraps an API endpoint handler and records incoming API calls.
func TrackAPICall(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		c := &Call{
			URL:         r.URL.String(),
			Route:       mux.CurrentRoute(r).GetName(),
			RouteParams: mapStringStringAsParams(mux.Vars(r)),
			QueryParams: mapStringSliceOfStringAsParams(r.URL.Query()),
			Date:        time.Now(),
		}

		// Try to get the current view info from the X-Track-View header.
		viewID, err := GetViewID(r)
		if err != nil {
			log.Printf("GetViewID failed: %s", err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		if viewID != nil {
			c.Instance = viewID.Instance
			c.ViewSeq = nnz.Int(viewID.Seq)
		}

		// Otherwise, try to get the instance from the request context.
		if c.Instance == 0 {
			if i := GetInstance(r); i != 0 {
				c.Instance = i
			}
		}

		err = InsertCall(c)
		if err != nil {
			log.Printf("InsertCall failed: %s", err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}

		status := CallStatus{
			CallID:   c.ID,
			Panicked: true, // assume the worst, set false if no panic
		}
		start := time.Now()
		rw := newRecorder(w)
		defer func() {
			status.Duration = time.Since(start).Nanoseconds()
			status.BodyLength = rw.BodyLength
			status.HTTPStatusCode = rw.Code
			err := InsertCallStatus(&status)
			if err != nil {
				log.Printf("warn: UpdateCallStatus failed (ID=%d): %s", c.ID, err)
			}
		}()

		h.ServeHTTP(rw, r)

		status.Panicked = false
	})
}
Example #7
0
func logError(req *http.Request, err error, rv interface{}) {
	if err != nil {
		var buf bytes.Buffer
		fmt.Fprintf(&buf, "Error serving %s (route %s): %s\n", req.URL, mux.CurrentRoute(req).GetName(), err)
		if rv != nil {
			fmt.Fprintln(&buf, rv)
			buf.Write(debug.Stack())
		}
		log.Print(buf.String())
	}
}
Example #8
0
/*
This is the handler where all the requests to providers will land in.
Here the parameters are extracted and passed to the providers along with
the requestbody if any using RPC. Result will be parsed to see if a specific
status code needs to be set for http response.
Arguments to Provider function -
1. type RpcRequest struct {
	RpcRequestVars map[string]string
	RpcRequestData []byte
}
Each provider should expect this structure as the first argument. RpcRequestVars
is a map of parameters passed in request URL. RpcRequestData is the payload(body)
of the http request.

2.Result - *[]byte
Pointer to a byte array. In response, the byte array should contain
{
    "status": {"statuscode": <Code>, "statusmessage": "<msg>"},
    "data": {"requestid": "<id>", "result": []byte}
}
where result is response payload from the provider, RequestId is populated if the
request is asynchronously executed and statuscode and statusmessage to be set in the
status field. The statuscode field should be valid http status code
*/
func (a *App) ProviderHandler(w http.ResponseWriter, r *http.Request) {
	ctxt, err := GetContext(r)
	if err != nil {
		logger.Get().Error("Error Getting the context. error: %v", err)
	}

	//Parse the Request and get the parameters and route information
	route := mux.CurrentRoute(r)
	vars := mux.Vars(r)

	var result []byte

	//Get the route details from the map
	routeCfg := a.routes[route.GetName()]
	//Get the request details from requestbody
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		logger.Get().Error("%s-Error parsing http request body: %v", ctxt, err)
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("Error parsing the http request body"))
	}

	//Find out the provider to process this request and send the request
	//After getting the response, pass it on to the client
	provider := a.getProviderFromRoute(ctxt, routeCfg)
	if provider != nil {
		logger.Get().Info("%s-Sending the request to provider: %s", ctxt, provider.Name)
		provider.Client.Call(provider.Name+"."+routeCfg.PluginFunc, models.RpcRequest{RpcRequestVars: vars, RpcRequestData: body}, &result)
		//Parse the result to see if a different status needs to set
		//By default it sets http.StatusOK(200)
		logger.Get().Info("Got response from provider: %s", provider.Name)
		var m models.RpcResponse
		if err = json.Unmarshal(result, &m); err != nil {
			logger.Get().Error("%s-Unable to Unmarshall the result from provider: %s. error: %v", ctxt, provider.Name, err)
			w.WriteHeader(http.StatusInternalServerError)
			w.Write([]byte("Unable to unmarshall the result from provider"))
		}
		status := m.Status.StatusCode
		if status != http.StatusOK {
			w.WriteHeader(int(status))
		}
		w.Write(result)
		return
	} else {
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("Matching Provider Not Found"))
	}
}
Example #9
0
// Add the access record for the catalog if it's our current route
func appendCatalogAccessRecord(accessRecords []auth.Access, r *http.Request) []auth.Access {
	route := mux.CurrentRoute(r)
	routeName := route.GetName()

	if routeName == v2.RouteNameCatalog {
		resource := auth.Resource{
			Type: "registry",
			Name: "catalog",
		}

		accessRecords = append(accessRecords,
			auth.Access{
				Resource: resource,
				Action:   "*",
			})
	}
	return accessRecords
}
Example #10
0
func MeterRequests(reg metrics.Registry) func(http.Handler) http.Handler {
	return func(back http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
			start := time.Now()

			writer := statusResponseWriter{w, 200}
			back.ServeHTTP(writer, req)

			route := mux.CurrentRoute(req)
			if name := route.GetName(); name != "" {
				timer := metrics.GetOrRegisterTimer(name, reg)
				timer.UpdateSince(start)

				meter := metrics.GetOrRegisterMeter(fmt.Sprintf("%s.%d", name, writer.status), reg)
				meter.Mark(1)
			}
		})
	}
}
Example #11
0
func (a *App) renderTemplate(w http.ResponseWriter, r *http.Request, name string, status int, data interface{}) error {
	a.tmplLock.Lock()
	defer a.tmplLock.Unlock()

	if a.tmpls == nil || ReloadTemplates {
		if err := a.parseHTMLTemplates(templates); err != nil {
			return err
		}
	}

	w.WriteHeader(status)
	if ct := w.Header().Get("content-type"); ct == "" {
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
	}
	t := a.tmpls[name]
	if t == nil {
		return fmt.Errorf("Template %s not found", name)
	}

	if data != nil {
		// Set TemplateCommon values.
		baseURL, err := a.URLTo(RootRoute)
		if err != nil {
			return err
		}
		reflect.ValueOf(data).Elem().FieldByName("TemplateCommon").Set(reflect.ValueOf(TemplateCommon{
			CurrentRoute: mux.CurrentRoute(r).GetName(),
			CurrentURI:   r.URL,
			BaseURL:      baseURL,
		}))
	}

	// Write to a buffer to properly catch errors and avoid partial output written to the http.ResponseWriter
	var buf bytes.Buffer
	err := t.Execute(&buf, data)
	if err != nil {
		return err
	}
	_, err = buf.WriteTo(w)
	return err
}
Example #12
0
// nameRequired returns true if the route requires a name.
func (app *App) nameRequired(r *http.Request) bool {
	route := mux.CurrentRoute(r)
	routeName := route.GetName()
	return route == nil || (routeName != v2.RouteNameBase && routeName != v2.RouteNameCatalog)
}
Example #13
0
func checkTestRouter(t *testing.T, testCases []routeTestCase, prefix string, deeplyEqual bool) {
	router := RouterWithPrefix(prefix)

	testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		testCase := routeTestCase{
			RequestURI: r.RequestURI,
			Vars:       mux.Vars(r),
			RouteName:  mux.CurrentRoute(r).GetName(),
		}

		enc := json.NewEncoder(w)

		if err := enc.Encode(testCase); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	})

	// Startup test server
	server := httptest.NewServer(router)

	for _, testcase := range testCases {
		testcase.RequestURI = strings.TrimSuffix(prefix, "/") + testcase.RequestURI
		// Register the endpoint
		route := router.GetRoute(testcase.RouteName)
		if route == nil {
			t.Fatalf("route for name %q not found", testcase.RouteName)
		}

		route.Handler(testHandler)

		u := server.URL + testcase.RequestURI

		resp, err := http.Get(u)

		if err != nil {
			t.Fatalf("error issuing get request: %v", err)
		}

		if testcase.StatusCode == 0 {
			// Override default, zero-value
			testcase.StatusCode = http.StatusOK
		}
		if testcase.ExpectedURI == "" {
			// Override default, zero-value
			testcase.ExpectedURI = testcase.RequestURI
		}

		if resp.StatusCode != testcase.StatusCode {
			t.Fatalf("unexpected status for %s: %v %v", u, resp.Status, resp.StatusCode)
		}

		if testcase.StatusCode != http.StatusOK {
			// We don't care about json response.
			continue
		}

		dec := json.NewDecoder(resp.Body)

		var actualRouteInfo routeTestCase
		if err := dec.Decode(&actualRouteInfo); err != nil {
			t.Fatalf("error reading json response: %v", err)
		}
		// Needs to be set out of band
		actualRouteInfo.StatusCode = resp.StatusCode

		if actualRouteInfo.RequestURI != testcase.ExpectedURI {
			t.Fatalf("URI %v incorrectly parsed, expected %v", actualRouteInfo.RequestURI, testcase.ExpectedURI)
		}

		if actualRouteInfo.RouteName != testcase.RouteName {
			t.Fatalf("incorrect route %q matched, expected %q", actualRouteInfo.RouteName, testcase.RouteName)
		}

		// when testing deep equality, the actualRouteInfo has an empty ExpectedURI, we don't want
		// that to make the comparison fail. We're otherwise done with the testcase so empty the
		// testcase.ExpectedURI
		testcase.ExpectedURI = ""
		if deeplyEqual && !reflect.DeepEqual(actualRouteInfo, testcase) {
			t.Fatalf("actual does not equal expected: %#v != %#v", actualRouteInfo, testcase)
		}
	}

}
Example #14
0
// TestRouter registers a test handler with all the routes and ensures that
// each route returns the expected path variables. Not method verification is
// present. This not meant to be exhaustive but as check to ensure that the
// expected variables are extracted.
//
// This may go away as the application structure comes together.
func TestRouter(t *testing.T) {

	router := Router()

	testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		testCase := routeTestCase{
			RequestURI: r.RequestURI,
			Vars:       mux.Vars(r),
			RouteName:  mux.CurrentRoute(r).GetName(),
		}

		enc := json.NewEncoder(w)

		if err := enc.Encode(testCase); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	})

	// Startup test server
	server := httptest.NewServer(router)

	for _, testcase := range []routeTestCase{
		{
			RouteName:  RouteNameBase,
			RequestURI: "/v2/",
			Vars:       map[string]string{},
		},
		{
			RouteName:  RouteNameManifest,
			RequestURI: "/v2/foo/manifests/bar",
			Vars: map[string]string{
				"name":      "foo",
				"reference": "bar",
			},
		},
		{
			RouteName:  RouteNameManifest,
			RequestURI: "/v2/foo/bar/manifests/tag",
			Vars: map[string]string{
				"name":      "foo/bar",
				"reference": "tag",
			},
		},
		{
			RouteName:  RouteNameTags,
			RequestURI: "/v2/foo/bar/tags/list",
			Vars: map[string]string{
				"name": "foo/bar",
			},
		},
		{
			RouteName:  RouteNameBlob,
			RequestURI: "/v2/foo/bar/blobs/tarsum.dev+foo:abcdef0919234",
			Vars: map[string]string{
				"name":   "foo/bar",
				"digest": "tarsum.dev+foo:abcdef0919234",
			},
		},
		{
			RouteName:  RouteNameBlob,
			RequestURI: "/v2/foo/bar/blobs/sha256:abcdef0919234",
			Vars: map[string]string{
				"name":   "foo/bar",
				"digest": "sha256:abcdef0919234",
			},
		},
		{
			RouteName:  RouteNameBlobUpload,
			RequestURI: "/v2/foo/bar/blobs/uploads/",
			Vars: map[string]string{
				"name": "foo/bar",
			},
		},
		{
			RouteName:  RouteNameBlobUploadChunk,
			RequestURI: "/v2/foo/bar/blobs/uploads/uuid",
			Vars: map[string]string{
				"name": "foo/bar",
				"uuid": "uuid",
			},
		},
		{
			RouteName:  RouteNameBlobUploadChunk,
			RequestURI: "/v2/foo/bar/blobs/uploads/D95306FA-FAD3-4E36-8D41-CF1C93EF8286",
			Vars: map[string]string{
				"name": "foo/bar",
				"uuid": "D95306FA-FAD3-4E36-8D41-CF1C93EF8286",
			},
		},
		{
			RouteName:  RouteNameBlobUploadChunk,
			RequestURI: "/v2/foo/bar/blobs/uploads/RDk1MzA2RkEtRkFEMy00RTM2LThENDEtQ0YxQzkzRUY4Mjg2IA==",
			Vars: map[string]string{
				"name": "foo/bar",
				"uuid": "RDk1MzA2RkEtRkFEMy00RTM2LThENDEtQ0YxQzkzRUY4Mjg2IA==",
			},
		},
		{
			// Check ambiguity: ensure we can distinguish between tags for
			// "foo/bar/image/image" and image for "foo/bar/image" with tag
			// "tags"
			RouteName:  RouteNameManifest,
			RequestURI: "/v2/foo/bar/manifests/manifests/tags",
			Vars: map[string]string{
				"name":      "foo/bar/manifests",
				"reference": "tags",
			},
		},
		{
			// This case presents an ambiguity between foo/bar with tag="tags"
			// and list tags for "foo/bar/manifest"
			RouteName:  RouteNameTags,
			RequestURI: "/v2/foo/bar/manifests/tags/list",
			Vars: map[string]string{
				"name": "foo/bar/manifests",
			},
		},
		{
			RouteName:  RouteNameBlobUploadChunk,
			RequestURI: "/v2/foo/../../blob/uploads/D95306FA-FAD3-4E36-8D41-CF1C93EF8286",
			StatusCode: http.StatusNotFound,
		},
	} {
		// Register the endpoint
		router.GetRoute(testcase.RouteName).Handler(testHandler)
		u := server.URL + testcase.RequestURI

		resp, err := http.Get(u)

		if err != nil {
			t.Fatalf("error issuing get request: %v", err)
		}

		if testcase.StatusCode == 0 {
			// Override default, zero-value
			testcase.StatusCode = http.StatusOK
		}

		if resp.StatusCode != testcase.StatusCode {
			t.Fatalf("unexpected status for %s: %v %v", u, resp.Status, resp.StatusCode)
		}

		if testcase.StatusCode != http.StatusOK {
			// We don't care about json response.
			continue
		}

		dec := json.NewDecoder(resp.Body)

		var actualRouteInfo routeTestCase
		if err := dec.Decode(&actualRouteInfo); err != nil {
			t.Fatalf("error reading json response: %v", err)
		}
		// Needs to be set out of band
		actualRouteInfo.StatusCode = resp.StatusCode

		if actualRouteInfo.RouteName != testcase.RouteName {
			t.Fatalf("incorrect route %q matched, expected %q", actualRouteInfo.RouteName, testcase.RouteName)
		}

		if !reflect.DeepEqual(actualRouteInfo, testcase) {
			t.Fatalf("actual does not equal expected: %#v != %#v", actualRouteInfo, testcase)
		}
	}

}
Example #15
0
// nameRequired returns true if the route requires a name.
func (app *App) nameRequired(r *http.Request) bool {
	route := mux.CurrentRoute(r)
	return route == nil || route.GetName() != v2.RouteNameBase
}