Ejemplo n.º 1
0
// Returns a top-level HTTP handler for a Router. This adds behavior for URLs that don't
// match anything -- it handles the OPTIONS method as well as returning either a 404 or 405
// for URLs that don't match a route.
func wrapRouter(sc *ServerContext, privs handlerPrivs, router *mux.Router) http.Handler {
	return http.HandlerFunc(func(response http.ResponseWriter, rq *http.Request) {
		fixQuotedSlashes(rq)
		var match mux.RouteMatch
		if router.Match(rq, &match) {
			router.ServeHTTP(response, rq)
		} else {
			// Log the request
			h := newHandler(sc, privs, response, rq)
			h.logRequestLine()

			// What methods would have matched?
			var options []string
			for _, method := range []string{"GET", "HEAD", "POST", "PUT", "DELETE"} {
				if wouldMatch(router, rq, method) {
					options = append(options, method)
				}
			}
			if len(options) == 0 {
				h.writeStatus(http.StatusNotFound, "unknown URL")
			} else {
				response.Header().Add("Allow", strings.Join(options, ", "))
				if rq.Method != "OPTIONS" {
					h.writeStatus(http.StatusMethodNotAllowed, "")
				}
			}
		}
	})
}
Ejemplo n.º 2
0
// TestErrorExpectedResponse is the generic test code for testing for a bad response
func TestErrorExpectedResponse(t *testing.T, router *mux.Router, method, url, route string, data io.Reader, accessToken, msg string, code int, assertExpectations func()) {
	// Prepare a request
	r, err := http.NewRequest(
		method,
		url,
		data,
	)
	assert.NoError(t, err)

	// Optionally add a bearer token to headers
	if accessToken != "" {
		r.Header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken))
	}

	// Check the routing
	match := new(mux.RouteMatch)
	router.Match(r, match)
	if assert.NotNil(t, match.Route) {
		assert.Equal(t, route, match.Route.GetName())
	}

	// And serve the request
	w := httptest.NewRecorder()
	router.ServeHTTP(w, r)

	TestResponseForError(t, w, msg, code)

	assertExpectations()
}
Ejemplo n.º 3
0
// IssueTestRequest executes an HTTP request described by rt, to a
// specified REST router.  It returns the HTTP response to the request.
func IssueRequest(router *mux.Router, rt *RequestTester) *httptest.ResponseRecorder {
	response := httptest.NewRecorder()
	body := bytes.NewReader(rt.request_body)
	req, _ := http.NewRequest(rt.method, rt.uri, body)
	if rt.api_token != "" {
		req.Header.Set("Authorization", "OAuth2 "+rt.api_token)
	}
	router.ServeHTTP(response, req)
	return response
}
Ejemplo n.º 4
0
func getRoles(router *mux.Router, recorder *httptest.ResponseRecorder, request *http.Request) []string {
	var roles []string
	router.ServeHTTP(recorder, request)
	Expect(recorder.Code).To(Equal(200))

	body, err := ioutil.ReadAll(io.LimitReader(recorder.Body, bufferLength))
	Expect(err).To(BeNil())

	err = json.Unmarshal(body, &roles)
	Expect(err).To(BeNil())

	return roles
}
Ejemplo n.º 5
0
func MakeRequest(method, urlStr string, body io.Reader, router *mux.Router) *httptest.ResponseRecorder {
	req, err := http.NewRequest(method, urlStr, body)

	if err != nil {
		fmt.Println(err)
	}

	w := httptest.NewRecorder()

	router.ServeHTTP(w, req)

	return w
}
Ejemplo n.º 6
0
func sampleRequest(router *mux.Router,
	method string, urlPath string, body []byte) []byte {
	req := &http.Request{
		Method: method,
		URL:    &url.URL{Path: urlPath},
		Form:   url.Values(nil),
		Body:   ioutil.NopCloser(bytes.NewBuffer(body)),
	}
	record := httptest.NewRecorder()
	router.ServeHTTP(record, req)
	if record.Code != 200 {
		return nil
	}
	return record.Body.Bytes()
}
Ejemplo n.º 7
0
// TestErrorExpectedResponse is the generic test code for testing for a bad response
func TestErrorExpectedResponse(t *testing.T, router *mux.Router, operation, url, msg string, code int, data io.Reader) {
	// Prepare a request
	r, err := http.NewRequest(
		operation,
		url,
		data,
	)
	assert.NoError(t, err)

	// Mock authentication
	r.Header.Set("Authorization", "Bearer test_token")

	// And serve the request
	w := httptest.NewRecorder()
	router.ServeHTTP(w, r)
	TestResponseForError(t, w, msg, code)
}
Ejemplo n.º 8
0
// Returns a top-level HTTP handler for a Router. This adds behavior for URLs that don't
// match anything -- it handles the OPTIONS method as well as returning either a 404 or 405
// for URLs that don't match a route.
func wrapRouter(sc *ServerContext, privs handlerPrivs, router *mux.Router) http.Handler {
	return http.HandlerFunc(func(response http.ResponseWriter, rq *http.Request) {
		fixQuotedSlashes(rq)
		var match mux.RouteMatch

		// Inject CORS if enabled and requested and not admin port
		originHeader := rq.Header["Origin"]
		if privs != adminPrivs && sc.config.CORS != nil && len(originHeader) > 0 {
			origin := matchedOrigin(sc.config.CORS.Origin, originHeader)
			response.Header().Add("Access-Control-Allow-Origin", origin)
			response.Header().Add("Access-Control-Allow-Credentials", "true")
			response.Header().Add("Access-Control-Allow-Headers", strings.Join(sc.config.CORS.Headers, ", "))
		}

		if router.Match(rq, &match) {
			router.ServeHTTP(response, rq)
		} else {
			// Log the request
			h := newHandler(sc, privs, response, rq, false)
			h.logRequestLine()

			// What methods would have matched?
			var options []string
			for _, method := range []string{"GET", "HEAD", "POST", "PUT", "DELETE"} {
				if wouldMatch(router, rq, method) {
					options = append(options, method)
				}
			}
			if len(options) == 0 {
				h.writeStatus(http.StatusNotFound, "unknown URL")
			} else {
				response.Header().Add("Allow", strings.Join(options, ", "))
				if privs != adminPrivs && sc.config.CORS != nil && len(originHeader) > 0 {
					response.Header().Add("Access-Control-Max-Age", strconv.Itoa(sc.config.CORS.MaxAge))
					response.Header().Add("Access-Control-Allow-Methods", strings.Join(options, ", "))
				}
				if rq.Method != "OPTIONS" {
					h.writeStatus(http.StatusMethodNotAllowed, "")
				} else {
					h.writeStatus(http.StatusNoContent, "")
				}
			}
			h.logDuration(true)
		}
	})
}
Ejemplo n.º 9
0
func getFox(uuid string, router *mux.Router) Fox {
	var r *http.Request
	var f *Fox

	recorder := httptest.NewRecorder()
	r, _ = http.NewRequest("GET", "/fox/foxes/"+uuid, nil)
	router.ServeHTTP(recorder, r)
	Expect(recorder.Code).To(Equal(200))

	body, err := ioutil.ReadAll(io.LimitReader(recorder.Body, bufferLength))
	Expect(err).To(BeNil())

	f = new(Fox)

	err = json.Unmarshal(body, f)
	Expect(err).To(BeNil())

	return *f
}
Ejemplo n.º 10
0
// Returns a top-level HTTP handler for a Router. This adds behavior for URLs that don't
// match anything -- it handles the OPTIONS method as well as returning either a 404 or 405
// for URLs that don't match a route.
func wrapRouter(sc *ServerContext, privs handlerPrivs, router *mux.Router) http.Handler {
	return http.HandlerFunc(func(response http.ResponseWriter, rq *http.Request) {
		fixQuotedSlashes(rq)
		var match mux.RouteMatch

		//if sc.config.CORS != nil {
		response.Header().Add("Access-Control-Allow-Origin", "*")
		response.Header().Add("Access-Control-Allow-Credentials", "true")
		response.Header().Add("Access-Control-Allow-Headers", "DNT, X-Mx-ReqToken, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type")
		// }

		if router.Match(rq, &match) {
			router.ServeHTTP(response, rq)
		} else {
			// Log the request
			h := newHandler(sc, privs, response, rq)
			h.logRequestLine()

			// What methods would have matched?
			var options []string
			for _, method := range []string{"GET", "HEAD", "POST", "PUT", "DELETE"} {
				if wouldMatch(router, rq, method) {
					options = append(options, method)
				}
			}
			if len(options) == 0 {
				h.writeStatus(http.StatusNotFound, "unknown URL")
			} else {
				response.Header().Add("Allow", strings.Join(options, ", "))
				//if sc.config.CORS != nil {
				response.Header().Add("Access-Control-Max-Age", "1728000")
				response.Header().Add("Access-Control-Allow-Methods", strings.Join(options, ", "))
				// }
				if rq.Method != "OPTIONS" {
					h.writeStatus(http.StatusMethodNotAllowed, "")
				}
			}
		}
	})
}
Ejemplo n.º 11
0
// TopologyHandler registers the various topology routes with a http mux.
//
// The returned http.Handler has to be passed directly to http.ListenAndServe,
// and cannot be nested inside another gorrilla.mux.
//
// Routes which should be matched before the topology routes should be added
// to a router and passed in preRoutes.  Routes to be matches after topology
// routes should be added to a router and passed to postRoutes.
func TopologyHandler(c Reporter, preRoutes *mux.Router, postRoutes http.Handler) http.Handler {
	get := preRoutes.Methods("GET").Subrouter()
	get.HandleFunc("/api", gzipHandler(apiHandler))
	get.HandleFunc("/api/topology", gzipHandler(topologyRegistry.makeTopologyList(c)))
	get.HandleFunc("/api/topology/{topology}",
		gzipHandler(topologyRegistry.captureRenderer(c, handleTopology)))
	get.HandleFunc("/api/topology/{topology}/ws",
		topologyRegistry.captureRenderer(c, handleWs)) // NB not gzip!
	get.HandleFunc("/api/report", gzipHandler(makeRawReportHandler(c)))

	// We pull in the http.DefaultServeMux to get the pprof routes
	preRoutes.PathPrefix("/debug/pprof").Handler(http.DefaultServeMux)

	if postRoutes != nil {
		preRoutes.PathPrefix("/").Handler(postRoutes)
	}

	// We have to handle the node details path manually due to
	// various bugs in gorilla.mux and Go URL parsing.  See #804.
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		vars, match := matchURL(r, "/api/topology/{topology}/{id}")
		if !match {
			preRoutes.ServeHTTP(w, r)
			return
		}

		topologyID := vars["topology"]
		nodeID := vars["id"]
		if nodeID == "ws" {
			preRoutes.ServeHTTP(w, r)
			return
		}

		handler := gzipHandler(topologyRegistry.captureRendererWithoutFilters(
			c, topologyID, handleNode(nodeID),
		))
		handler.ServeHTTP(w, r)
	})
}
Ejemplo n.º 12
0
func testRESTHandlers(t *testing.T,
	tests []*RESTHandlerTest, router *mux.Router) {
	for _, test := range tests {
		if test.Before != nil {
			test.Before()
		}
		if test.Method != "NOOP" {
			req := &http.Request{
				Method: test.Method,
				URL:    &url.URL{Path: test.Path},
				Form:   test.Params,
				Body:   ioutil.NopCloser(bytes.NewBuffer(test.Body)),
			}
			record := httptest.NewRecorder()
			router.ServeHTTP(record, req)
			test.check(t, record)
		}
		if test.After != nil {
			test.After()
		}
	}
}
Ejemplo n.º 13
0
func addFox(f Fox, router *mux.Router) string {
	var id *UUID
	var r *http.Request

	m, _ := json.Marshal(f)

	recorder := httptest.NewRecorder()
	r, _ = http.NewRequest("POST", "/fox/foxes", bytes.NewReader(m))

	router.ServeHTTP(recorder, r)
	Expect(recorder.Code).To(Equal(201))

	body, err := ioutil.ReadAll(io.LimitReader(recorder.Body, bufferLength))
	Expect(err).To(BeNil())

	id = new(UUID)

	err = json.Unmarshal(body, id)
	Expect(err).To(BeNil())

	return id.Uuid
}
Ejemplo n.º 14
0
func routerHandlerFunc(router *mux.Router) http.HandlerFunc {
	return func(res http.ResponseWriter, req *http.Request) {
		router.ServeHTTP(res, req)
	}
}
Ejemplo n.º 15
0
		chocStorage := storage.NewChocolateStorage()
		api.AddResource(model.User{}, resource.UserResource{ChocStorage: chocStorage, UserStorage: userStorage})
		api.AddResource(model.Chocolate{}, resource.ChocolateResource{ChocStorage: chocStorage, UserStorage: userStorage})
	})

	BeforeEach(func() {
		log.SetOutput(ioutil.Discard)
		rec = httptest.NewRecorder()
	})

	Context("CRUD Tests", func() {
		It("will create a new user", func() {
			reqBody := strings.NewReader(`{"data": [{"attributes": {"username": "******"}, "id": "1", "type": "users"}]}`)
			req, err := http.NewRequest("POST", "/api/users", reqBody)
			Expect(err).To(BeNil())
			r.ServeHTTP(rec, req)
			Expect(rec.Code).To(Equal(http.StatusCreated))
		})

		It("will find her", func() {
			expectedUser := `
			{
				"data":
				{
					"attributes":{
						"user-name":"Sansa Stark"
					},
					"id":"1",
					"relationships":{
						"sweets":{
							"data":[],"links":{"related":"/api/users/1/sweets","self":"/api/users/1/relationships/sweets"}
Ejemplo n.º 16
0
	var r *mux.Router
	var w *httptest.ResponseRecorder

	BeforeEach(func() {
		r = mux.NewRouter()
	})

	Describe("Get Users", func() {
		Context("Get all Users", func() {
			//providing mocked data of 3 users
			It("should get list of Users", func() {
				r.Handle("/users", GetUsers(userRepository)).Methods("GET")
				req, err := http.NewRequest("GET", "/users", nil)
				Expect(err).NotTo(HaveOccurred())
				w = httptest.NewRecorder()
				r.ServeHTTP(w, req)
				Expect(w.Code).To(Equal(200))
				var users []User
				json.Unmarshal(w.Body.Bytes(), &users)
				//Verifying mocked data of 3 users
				Expect(len(users)).To(Equal(3))
			})
		})
	})

	Describe("Post a new User", func() {
		Context("Provide a valid User data", func() {
			It("should create a new User and get HTTP Status: 201", func() {
				r.Handle("/users", CreateUser(userRepository)).Methods("POST")
				userJson := `{"firstname": "Alex", "lastname": "John", "email": "*****@*****.**"}`
Ejemplo n.º 17
0
		cb = v1.NewCentralBooking(
			instance.NewRegistrar(&mockVaultClient),
			&mockConsulCatalog,
			"https://vault.example.com/",
		)
		cb.InstallHandlers(router.PathPrefix("/v1").Subrouter())
	})

	Describe("instance registration", func() {
		endpoint := "http://example.com/v1/register/instance"

		It("should fail with invalid GET verb", func() {
			req, err := http.NewRequest("GET", endpoint, nil)
			Expect(err).To(BeNil())

			router.ServeHTTP(resp, req)
			Expect(resp.Code).To(Equal(404))
		})

		It("should fail if policies not provided", func() {
			req, err := http.NewRequest(
				"POST", endpoint,
				strings.NewReader(`{
                    "environment": "dev",
                    "provider":    "aws",
                    "account":     "gen",
                    "region":      "us-east-1",
                    "instance_id": "i-04c9c4c4",
                    "role":        "cluster-server"
                }`),
			)
Ejemplo n.º 18
0
		manager = mocks.NewMockResourceManager(ctrl)
		router = mux.NewRouter().PathPrefix("/api").Subrouter()
		rw = httptest.NewRecorder()
		manager.EXPECT().GetName().AnyTimes().Return("test")
		r = goresource.NewResource(manager, router)
	})

	AfterEach(func() {
		ctrl.Finish()
	})

	Context("given a valid id", func() {
		It("responds with the corresponding entity.", func() {
			req, _ := http.NewRequest("GET", "/api/test/fakeid", nil)
			manager.EXPECT().GetEntity("fakeid", req.URL.Query()).Return("fake-entity", nil)
			router.ServeHTTP(rw, req)
			Expect(rw.Code).To(Equal(http.StatusOK))
			Expect(rw.Header().Get("Content-Type")).To(Equal("application/json"))
			Expect(rw.Body.String()).To(Equal(`"fake-entity"`))
		})
		It("responds with an error, if one occurs.", func() {
			req, _ := http.NewRequest("GET", "/api/test/fakeid", nil)
			manager.EXPECT().GetEntity("fakeid", req.URL.Query()).Return(nil, fmt.Errorf("Test Error"))
			router.ServeHTTP(rw, req)
			Expect(rw.Code).To(Equal(http.StatusInternalServerError))
			Expect(rw.Header().Get("Content-Type")).To(Equal("text/plain; charset=utf-8"))
			Expect(rw.Body.String()).To(Equal("Test Error\n"))
		})
	})
	Context("not given an id", func() {
		It("responds with all entities.", func() {
Ejemplo n.º 19
0
// TestListValidResponseWithParams tests a list endpoint for a valid response with default settings
func TestListValidResponseWithParams(t *testing.T, router *mux.Router, entity string, items []interface{}, assertExpectations func(), params map[string]string) {
	u, err := url.Parse(fmt.Sprintf("http://1.2.3.4/v1/%s", entity))

	// add any params
	for k, v := range params {
		q := u.Query()
		q.Set(k, v)
		u.RawQuery = q.Encode()
	}

	// Prepare a request
	r, err := http.NewRequest(
		"GET",
		u.String(),
		nil,
	)
	assert.NoError(t, err)

	// Mock authentication
	r.Header.Set("Authorization", "Bearer test_token")

	// And serve the request
	w := httptest.NewRecorder()
	router.ServeHTTP(w, r)

	// Check that the mock object expectations were met
	assertExpectations()
	assert.Equal(t, http.StatusOK, w.Code)

	baseURI := u.RequestURI()

	q := u.Query()
	q.Set("page", "1")
	u.RawQuery = q.Encode()

	pagedURI := u.RequestURI()

	expected := &ListResponse{
		Hal: jsonhal.Hal{
			Links: map[string]*jsonhal.Link{
				"self": &jsonhal.Link{
					Href: baseURI,
				},
				"first": &jsonhal.Link{
					Href: pagedURI,
				},
				"last": &jsonhal.Link{
					Href: pagedURI,
				},
				"prev": new(jsonhal.Link),
				"next": new(jsonhal.Link),
			},
			Embedded: map[string]jsonhal.Embedded{
				entity: jsonhal.Embedded(items),
			},
		},
		Count: uint(len(items)),
		Page:  1,
	}
	expectedJSON, err := json.Marshal(expected)

	if assert.NoError(t, err, "JSON marshalling failed") {
		TestResponseBody(t, w, string(expectedJSON))
	}
}
Ejemplo n.º 20
0
				foxID := addFox(aFox, router)

				// See if we can find it
				_ = getFox(foxID, router)
			})
		})
	})

	Describe("Reading the fox list", func() {
		BeforeEach(func() {
			request, _ = http.NewRequest("GET", "/fox/foxes", nil)
		})

		Context("Foxes exist", func() {
			It("Should return http 200", func() {
				router.ServeHTTP(recorder, request)
				Expect(recorder.Code).To(Equal(200))
			})
		})

		Context("Random fox should return 404", func() {
			It("Should return 404", func() {
				request, _ = http.NewRequest("GET", "/fox/foxes/nosuchfoxforsure", nil)
				router.ServeHTTP(recorder, request)
				Expect(recorder.Code).To(Equal(404))
			})
		})
	})

	Describe("Updating a fox", func() {
		var m []byte
Ejemplo n.º 21
0
var _ = Describe("Debug", func() {
	BeforeEach(func() {
		recorder = httptest.NewRecorder()
		handler = handlers.NewInfoHandler()
		router = mux.NewRouter()
		handlers.CreateDebugEndpoints(router, "admin", "password")
	})

	Context("with proper authorization", func() {
		DescribeTable("debug endpoints should return 200 response code", func(endpoint string) {
			req, err = http.NewRequest("GET", fmt.Sprintf("/debug/pprof%s", endpoint), nil)
			Expect(err).ToNot(HaveOccurred())

			encodedCreds := base64.StdEncoding.EncodeToString([]byte("admin:password"))
			req.Header.Add("Authorization", fmt.Sprintf("Basic %s", encodedCreds))
			router.ServeHTTP(recorder, req)
			Expect(recorder.Code).To(Equal(200))
		},
			Entry("index", ""),
			Entry("cmdline", "/cmdline"),
			Entry("profile", "/profile?seconds=1"),
			Entry("symbol", "/symbol"),
			Entry("goroutine", "/goroutine"),
			Entry("heap", "/heap"),
			Entry("threadcreate", "/threadcreate"),
			Entry("block", "/block"),
		)
	})
	Context("with bad authentication", func() {
		Context("not BasicAuth", func() {
			It("returns a 401", func() {