コード例 #1
0
ファイル: action_controller.go プロジェクト: robertocs/cepiot
func AddRoutes(router *httprouter.Router) {
	mylog.Debugf("enter notice.AddRoutes(%+v)", router)
	defer func() { mylog.Debugf("exit action.Handler(%+v)", router) }()

	controller := &controller{&actionList}
	router.POST("/action", controller.Post)
}
コード例 #2
0
ファイル: profile.go プロジェクト: rezacute/bullettime
func (e profileEndpoint) Register(mux *httprouter.Router) {
	mux.GET("/profile/:userId/displayname", jsonHandler(e.getDisplayName))
	mux.PUT("/profile/:userId/displayname", jsonHandler(e.setDisplayName))
	mux.GET("/profile/:userId/avatar_url", jsonHandler(e.getAvatarUrl))
	mux.PUT("/profile/:userId/avatar_url", jsonHandler(e.setAvatarUrl))
	mux.GET("/profile/:userId", jsonHandler(e.getProfile))
}
コード例 #3
0
func myRouterConfig(router *httprouter.Router) {
	router.GET("/pepe", func(w http.ResponseWriter, req *http.Request, p httprouter.Params) {
		fmt.Fprintln(w, "pepe")
	})

	router.GET("/", homeHandler)

}
コード例 #4
0
ファイル: chat_service.go プロジェクト: CHH-Darick/raspchat
func (c *ChatService) httpRoutes(prefix string, router *httprouter.Router) http.Handler {
	router.POST(prefix+"/push", c.onPushPost)
	router.POST(prefix+"/register", c.onPushSubscribe)

	router.GET(prefix+"/channel/:id/message", c.onGetChatHistory)
	router.GET(prefix+"/channel/:id/message/:msg_id", c.onGetChatMessage)
	router.GET(prefix+"/channel", c.onGetChannels)
	return router
}
コード例 #5
0
ファイル: api.go プロジェクト: drborges/macaroons-spike
func Register(router *httprouter.Router) {
	router.GET("/storage/files", func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
		encodedToken := req.Header.Get("X-Auth-Token")
		//		authMacaroon, err := macaroon.New(auth.Key, auth.ServiceID, auth.Location)
		//		if err != nil {
		//			log.Print(err)
		//			w.WriteHeader(500)
		//			w.Write([]byte("Oops, something went wrong..."))
		//			return
		//		}

		token, err := base64.URLEncoding.DecodeString(encodedToken)
		if err != nil {
			log.Print(err)
			w.WriteHeader(500)
			w.Write([]byte("Oops, something went wrong..."))
			return
		}

		userMacaroon := &macaroon.Macaroon{}
		if err := userMacaroon.UnmarshalBinary(token); err != nil {
			log.Print(err)
			w.WriteHeader(500)
			w.Write([]byte("Oops, something went wrong..."))
			return
		}

		log.Printf("#### Macaroon caveats: %+v\n", userMacaroon.Caveats())
		log.Printf("#### Macaroon signature: %+v\n", userMacaroon.Signature())
		log.Printf("#### Macaroon id: %+v\n", userMacaroon.Id())
		log.Printf("#### Macaroon location: %+v\n", userMacaroon.Location())

		if err := userMacaroon.Verify(auth.Key, noCaveatsChecker, nil); err != nil {
			log.Print(err)
			w.WriteHeader(401)
			w.Write([]byte(err.Error()))
			return
		}

		response := struct {
			Files []string `json:"files"`
		}{
			Files: []string{
				"http://localhost:6061/storage/files/1",
				"http://localhost:6061/storage/files/2",
				"http://localhost:6061/storage/files/3",
			},
		}

		if err := json.NewEncoder(w).Encode(response); err != nil {
			log.Print(err)
			w.WriteHeader(500)
			w.Write([]byte(err.Error()))
		}
	})
}
コード例 #6
0
ファイル: static.go プロジェクト: manjeshpv/qgotify
func Init(router *httprouter.Router) {

	router.NotFound = http.FileServer(http.Dir(devsatic)).ServeHTTP

	env := os.Getenv("production")

	if env != "" {
		router.NotFound = http.FileServer(http.Dir(diststatic)).ServeHTTP
	}
}
コード例 #7
0
ファイル: route.go プロジェクト: patosullivan/mf-proto
func source(r *htr.Router) error {
	r.GET("/source",
		func(w http.ResponseWriter, r *http.Request, ps htr.Params) {
			if _, err := io.WriteString(w, sourceDoc); err != nil {
				log.Printf("failed to write response: %s", err.Error())
			}
		},
	)

	return nil
}
コード例 #8
0
ファイル: api.go プロジェクト: sguzwf/vertex
// configure registers the API's routes on a router. If the passed router is nil, we create a new one and return it.
// The nil mode is used when an API is run in stand-alone mode.
func (a *API) configure(router *httprouter.Router) *httprouter.Router {

	if router == nil {
		router = httprouter.New()
	}

	for i, route := range a.Routes {

		if err := route.parseInfo(route.Path); err != nil {
			logging.Error("Error parsing info for %s: %s", route.Path, err)
		}
		a.Routes[i] = route
		h := a.handler(route)

		pth := a.FullPath(route.Path)

		if route.Methods&GET == GET {
			logging.Info("Registering GET handler %v to path %s", h, pth)
			router.Handle("GET", pth, h)
		}
		if route.Methods&POST == POST {
			logging.Info("Registering POST handler %v to path %s", h, pth)
			router.Handle("POST", pth, h)

		}

	}

	chain := buildChain(a.SwaggerMiddleware...)
	if chain == nil {
		chain = buildChain(a.swaggerHandler())
	} else {
		chain.append(a.swaggerHandler())
	}

	// Server the API documentation swagger
	router.GET(a.FullPath("/swagger"), a.middlewareHandler(chain, nil, nil))

	chain = buildChain(a.TestMiddleware...)
	if chain == nil {
		chain = buildChain(a.testHandler())
	} else {
		chain.append(a.testHandler())
	}

	router.GET(path.Join("/test", a.root(), ":category"), a.middlewareHandler(chain, nil, nil))

	// Redirect /$api/$version/console => /console?url=/$api/$version/swagger
	uiPath := fmt.Sprintf("/console?url=%s", url.QueryEscape(a.FullPath("/swagger")))
	router.Handler("GET", a.FullPath("/console"), http.RedirectHandler(uiPath, 301))

	return router

}
コード例 #9
0
ファイル: test.go プロジェクト: itsabot/abot
func request(r *httprouter.Router, method, path string, data []byte) (int,
	string) {

	req, err := http.NewRequest(method, path, bytes.NewBuffer(data))
	if err != nil {
		return 0, "err completing request: " + err.Error()
	}
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)
	return w.Code, string(w.Body.Bytes())
}
コード例 #10
0
ファイル: routes.go プロジェクト: zaquestion/ambition
// Add routes to http router
// TODO: Add route description parameters and useage
func AddRoutes(router *httprouter.Router) {
	router.GET("/actions", Actions)
	router.GET("/actions/:ActionId", ActionById)
	router.POST("/set/:SetId", PostAction)
	router.GET("/actions/:ActionId/occrurrences", Occurrences)
	router.GET("/occurrences/:OccurrenceId", OccurrenceById)

	// TODO:
	// router.POST("/actions/:ActionId", postOccurrence)
	// router.GET("/sets", sets)
	// router.GET("/sets/:SetId/actions", actionsFromSet)
}
コード例 #11
0
ファイル: mysql.go プロジェクト: falmar/ego
func setMySQLHandlers(r *httprouter.Router) {
	r.GET("/MySQL", MySQL) // Read

	// GET Handlers
	r.GET("/Create", Create)
	r.GET("/Update/:ID", Update)
	r.GET("/Delete/:ID", Delete)

	//Post Handlers
	r.POST("/Create", CreateP)
	r.POST("/Update/:ID", UpdateP)
}
コード例 #12
0
ファイル: stream_controller.go プロジェクト: ello/streams
func (c *streamController) Register(router *httprouter.Router) {
	router.PUT("/streams", basicAuth(timeRequest(c.handle(c.addToStream), addToStreamTimer), c.authConfig))
	router.DELETE("/streams", basicAuth(timeRequest(c.handle(c.removeFromStream), removeFromStreamTimer), c.authConfig))
	router.POST("/streams/coalesce", basicAuth(timeRequest(c.handle(c.coalesceStreams), coalesceTimer), c.authConfig))
	router.GET("/stream/:id", basicAuth(timeRequest(c.handle(c.getStream), getStreamTimer), c.authConfig))

	log.Debug("Routes Registered")
}
コード例 #13
0
ファイル: pubsub.go プロジェクト: pengux/pub-sub
// SetupRoutes maps routes to the PubSub's handlers
func (ps *PubSub) SetupRoutes(router *httprouter.Router) *httprouter.Router {
	router.POST("/:topic_name", ps.PublishMessage)
	router.POST("/:topic_name/:subscriber_name", ps.Subscribe)
	router.DELETE("/:topic_name/:subscriber_name", ps.Unsubscribe)
	router.GET("/:topic_name/:subscriber_name", ps.GetMessages)

	return router
}
コード例 #14
0
ファイル: http.go プロジェクト: SunSparc/cayley
func (api *API) APIv1(r *httprouter.Router) {
	r.POST("/api/v1/query/:query_lang", LogRequest(api.ServeV1Query))
	r.POST("/api/v1/shape/:query_lang", LogRequest(api.ServeV1Shape))
	r.POST("/api/v1/write", LogRequest(api.ServeV1Write))
	r.POST("/api/v1/write/file/nquad", LogRequest(api.ServeV1WriteNQuad))
	//TODO(barakmich): /write/text/nquad, which reads from request.body instead of HTML5 file form?
	r.POST("/api/v1/delete", LogRequest(api.ServeV1Delete))
}
コード例 #15
0
ファイル: handlers_users.go プロジェクト: teefax/tmail
// addUsersHandlers add Users handler to router
func addUsersHandlers(router *httprouter.Router) {
	// add user
	router.POST("/users/:user", wrapHandler(usersAdd))

	// get all users
	router.GET("/users", wrapHandler(usersGetAll))

	// get one user
	router.GET("/users/:user", wrapHandler(usersGetOne))

	// del an user
	router.DELETE("/users/:user", wrapHandler(usersDel))

	// change user password
	router.PUT("/users/:user", wrapHandler(usersUpdate))
}
コード例 #16
0
func Register(router *httprouter.Router) {
	r := render.New()

	router.POST("/deployments", func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
		deployment := DeploymentFrom(req)
		macaroon := CreateDeploymentMacaroon(deployment)
		RequestApproval(appengine.NewContext(req), deployment, macaroon)

		db := appx.NewDatastore(appengine.NewContext(req))
		if err := db.Save(deployment); err != nil {
			log.Panic(err)
		}

		b, _ := macaroon.MarshalBinary()
		token := base64.URLEncoding.EncodeToString(b)

		r.JSON(w, 200, JSON{
			"token": token,
		})
	})

	router.POST("/validate", func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
		form := &MacaroonForm{}
		json.NewDecoder(req.Body).Decode(form)
		bytes, err := base64.URLEncoding.DecodeString(form.Token)
		if err != nil {
			r.JSON(w, 400, JSON{
				"message": "Error deserializing macaroon.",
				"error":   err.Error(),
			})
			return
		}

		err = VerifyMacaroon(bytes)
		if err != nil {
			r.JSON(w, 400, JSON{
				"message": "Macaroon invalid.",
				"error":   err.Error(),
			})
			return
		}

		r.JSON(w, 200, JSON{
			"message": "Macaroon valid.",
		})
	})
}
コード例 #17
0
ファイル: rule_controller.go プロジェクト: robertocs/cepiot
func AddRoutes(router *httprouter.Router) {
	mylog.Debugf("enter rule.AddRoutes(%+v)", router)
	defer func() { mylog.Debugf("exit rule.AddRoutes(%+v)", router) }()

	controller := &controller{}
	router.GET("/rules", controller.GetAll)
	router.GET("/rules/:name", controller.Get)
	router.POST("/rules", controller.Post)
	router.DELETE("/rules/:name", controller.Del)
}
コード例 #18
0
ファイル: handlers_queue.go プロジェクト: teefax/tmail
// addQueueHandlers add Queue handlers to router
func addQueueHandlers(router *httprouter.Router) {
	// get all message in queue
	router.GET("/queue", wrapHandler(queueGetMessages))
	// get a message by id
	router.GET("/queue/:id", wrapHandler(queueGetMessage))
	// discard a message
	router.DELETE("/queue/discard/:id", wrapHandler(queueDiscardMessage))
	// bounce a message
	router.DELETE("/queue/bounce/:id", wrapHandler(queueBounceMessage))
}
コード例 #19
0
ファイル: auth.go プロジェクト: rezacute/bullettime
func (e authEndpoint) Register(mux *httprouter.Router) {
	mux.GET("/register", jsonHandler(func() interface{} {
		return &defaultRegisterFlows
	}))
	mux.GET("/login", jsonHandler(func() interface{} {
		return &defaultLoginFlows
	}))
	mux.POST("/register", jsonHandler(e.postRegister))
	mux.POST("/login", jsonHandler(e.postLogin))
}
コード例 #20
0
ファイル: handlers.go プロジェクト: itsabot/abot
// initCMDGroup establishes routes for automatically reloading the page on any
// assets/ change when a watcher is running (see cmd/*watcher.sh).
func initCMDGroup(router *httprouter.Router) {
	cmdch := make(chan string, 10)
	addconnch := make(chan *cmdConn, 10)
	delconnch := make(chan *cmdConn, 10)

	go cmder(cmdch, addconnch, delconnch)

	router.GET("/_/cmd/ws/*cmd", func(w http.ResponseWriter,
		r *http.Request, ps httprouter.Params) {
		cmdch <- ps.ByName("cmd")[1:]
		w.WriteHeader(http.StatusOK)
	})
	router.Handler("GET", "/_/cmd/ws", w.Handler(func(wsc *w.Conn) {
		respch := make(chan bool)
		conn := &cmdConn{ws: wsc, respch: respch}
		addconnch <- conn
		<-respch
		delconnch <- conn
	}))
}
コード例 #21
0
ファイル: debugcharts.go プロジェクト: andboson/debugcharts
func InitHttpRouter(R *httprouter.Router) {
	R.HandlerFunc("GET", "/debug/charts/data-feed", s.dataFeedHandler)
	R.HandlerFunc("GET", "/debug/charts/data", dataHandler)
	R.HandlerFunc("GET", "/debug/charts/", handleAsset("static/index.html"))
	R.HandlerFunc("GET", "/debug/charts/main.js", handleAsset("static/main.js"))

	// preallocate arrays in data, helps save on reallocations caused by append()
	// when maxCount is large
	data.BytesAllocated = make([][]uint64, 0, maxCount)
	data.GcPauses = make([][]uint64, 0, maxCount)

	go s.gatherData()
}
コード例 #22
0
func (self *CommandModule) LoadRoutes(router *httprouter.Router) error {
	router.GET(`/api/commands/list`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
		util.Respond(w, http.StatusOK, self.Commands, nil)
	})

	router.PUT(`/api/commands/run/:name`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
		name := params.ByName(`name`)

		if command, ok := self.Commands[name]; ok {
			if results, err := command.Execute(); err == nil {
				util.Respond(w, http.StatusOK, results, nil)
			} else {
				util.Respond(w, http.StatusOK, results, nil)
			}
		} else {
			util.Respond(w, http.StatusNotFound, nil, fmt.Errorf("Cannot find a command called '%s'", name))
		}
	})

	return nil
}
コード例 #23
0
ファイル: stream_controller.go プロジェクト: rtyer/streams
func (c *streamController) Register(router *httprouter.Router) {
	router.PUT("/streams", basicAuth(c.handle(c.addToStream), c.authConfig))
	router.POST("/streams/coalesce", basicAuth(c.handle(c.coalesceStreams), c.authConfig))
	router.GET("/stream/:id", basicAuth(c.handle(c.getStream), c.authConfig))

	log.Debug("Routes Registered")
}
コード例 #24
0
ファイル: health_controller.go プロジェクト: ello/streams
func (c *healthController) Register(router *httprouter.Router) {
	router.GET("/health/metrics", c.handle(c.printMetrics))
	router.GET("/health/check", c.handle(c.healthCheck))
	router.GET("/health/heartbeat", c.handle(c.heartbeat))

	log.Debug("Health Routes Registered")
}
コード例 #25
0
ファイル: handlers.go プロジェクト: babelrpc/babel
func addHandlers(router *httprouter.Router, midl *idl.Idl) error {
	count := 0
	re := regexp.MustCompile(`\{(\w+)\}`)
	for _, svc := range allServices(midl) {
		for _, mth := range svc.Methods {
			count++
			op, err := rest.ReadOp(mth)
			if err != nil {
				log.Fatal("Cannot process %s.%s: %s", svc.Name, mth.Name, err)
			}
			if !op.Hide {
				routePath := re.ReplaceAllString(path.Join(conf.RestPath, op.Path), ":$1")
				handle, err := makeHandler(midl, svc, mth)
				if err != nil {
					return err
				}
				router.Handle(op.Method.String(), routePath, handle)
				log.Printf("%s %s -> %s", op.Method.String(), path.Join(conf.RestPath, op.Path), path.Join(conf.BabelPath, svc.Name, mth.Name))
			}
			babelPath := path.Join(conf.BabelPath, svc.Name, mth.Name)
			if !strings.HasPrefix(babelPath, "/") {
				babelPath = "/" + babelPath
			}
			handle, err := makeBabelHandler(midl, svc, mth)
			if err != nil {
				return err
			}
			router.Handle("POST", babelPath, handle)
			log.Printf("%s %s -> %s", op.Method.String(), babelPath, babelPath)
		}
	}
	if count == 0 {
		log.Fatal("No services to process")
	}

	return nil
}
コード例 #26
0
ファイル: http.go プロジェクト: skycoin/skycoin-exchange
// LaunchWebInterface begins listening on http://$host, for enabling remote web access
// Does NOT use HTTPS
func LaunchWebInterface(host, staticDir string, rt *httprouter.Router) error {
	logger.Info("Starting web interface on http://%s", host)
	logger.Warning("HTTPS not in use!")
	// logger.Info("Web resources directory: %s", staticDir)

	appLoc, err := determineResourcePath(staticDir)
	if err != nil {
		return err
	}
	logger.Debug("static dir:%s", appLoc)

	rt.NotFound = http.FileServer(http.Dir(appLoc))
	go func() {
		log.Panic(http.ListenAndServe(host, rt))
	}()
	return nil
}
コード例 #27
0
func (h *Handler) SetRoutes(r *httprouter.Router) {
	r.GET("/connections", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		if r.URL.Query().Get("local_subject") != "" {
			h.FindLocal(w, r, ps)
			return
		}

		if r.URL.Query().Get("remote_subject") != "" && r.URL.Query().Get("provider") != "" {
			h.FindRemote(w, r, ps)
			return
		}

		var ctx = context.Background()
		h.H.WriteErrorCode(ctx, w, r, http.StatusBadRequest, errors.New("Pass either [local_subject] or [remote_subject, provider] as query to this request"))
	})

	r.POST("/connections", h.Create)
	r.GET("/connections/:id", h.Get)
	r.DELETE("/connections/:id", h.Delete)
}
コード例 #28
0
ファイル: http.go プロジェクト: imjorge/flynn
func (h *jobAPI) RegisterRoutes(r *httprouter.Router) error {
	r.GET("/host/jobs", h.ListJobs)
	r.GET("/host/jobs/:id", h.GetJob)
	r.PUT("/host/jobs/:id", h.AddJob)
	r.DELETE("/host/jobs/:id", h.StopJob)
	r.PUT("/host/jobs/:id/discoverd-deregister", h.DiscoverdDeregisterJob)
	r.PUT("/host/jobs/:id/signal/:signal", h.SignalJob)
	r.POST("/host/pull/images", h.PullImages)
	r.POST("/host/pull/binaries", h.PullBinariesAndConfig)
	r.POST("/host/discoverd", h.ConfigureDiscoverd)
	r.POST("/host/network", h.ConfigureNetworking)
	r.GET("/host/status", h.GetStatus)
	r.POST("/host/resource-check", h.ResourceCheck)
	r.POST("/host/update", h.Update)
	r.POST("/host/tags", h.UpdateTags)
	return nil
}
コード例 #29
0
ファイル: services.go プロジェクト: drdreyworld/container
func (ctrl *ServicesController) BindActions(router *httprouter.Router) {
	router.GET("/admin/container/services", webapp.MakeAction(webapp.Action{
		RenderTemplate: true,
		TemplatePath:   ctrl.config.Paths.Templates,
		TemplateName:   "view/admin/services/index",
		ActionFunc: func(action *webapp.Action) interface{} {
			return ctrl.model.GetServices()
		},
	}))

	router.GET("/admin/container/services/create", webapp.MakeAction(webapp.Action{
		RenderTemplate: true,
		TemplatePath:   ctrl.config.Paths.Forms,
		TemplateName:   "edit",
		ActionFunc: func(action *webapp.Action) interface{} {
			form := new(forms.Form)
			form.CreateFromMeta(model.Service{}.GetForm())
			form.SetTemplatesPath(ctrl.config.Paths.Forms + "edit")

			return map[string]interface{}{
				"form": form,
			}
		},
	}))

	router.POST("/admin/container/services/create", webapp.MakeAction(webapp.Action{
		RenderTemplate: true,
		TemplatePath:   ctrl.config.Paths.Forms,
		TemplateName:   "edit",
		ActionFunc: func(action *webapp.Action) interface{} {
			item := model.Service{}
			form := new(forms.Form)
			form.CreateFromMeta(item.GetForm())
			form.SetTemplatesPath(ctrl.config.Paths.Forms + "edit")

			if form.IsValid(action.Request) {
				item.SetValues(form.GetValues())
				ctrl.model.Create(item)
			}

			action.Redirect("/admin/container/services")
			return nil
		},
	}))

	router.GET("/admin/container/services/update/:id", webapp.MakeAction(webapp.Action{
		RenderTemplate: true,
		TemplatePath:   ctrl.config.Paths.Forms,
		TemplateName:   "edit",
		ActionFunc: func(action *webapp.Action) interface{} {
			item := ctrl.model.GetItemById(action.Params.ByName("id"))
			form := new(forms.Form)
			form.CreateFromMeta(item.GetForm())
			form.SetTemplatesPath(ctrl.config.Paths.Forms + "edit/")

			return map[string]interface{}{
				"form": form,
			}
		},
	}))

	router.POST("/admin/container/services/update/:id", webapp.MakeAction(webapp.Action{
		RenderTemplate: true,
		TemplatePath:   ctrl.config.Paths.Forms,
		TemplateName:   "edit",
		ActionFunc: func(action *webapp.Action) interface{} {
			item := ctrl.model.GetItemById(action.Params.ByName("id"))
			form := new(forms.Form)
			form.CreateFromMeta(item.GetForm())
			form.SetTemplatesPath(ctrl.config.Paths.Forms + "edit/")

			if form.IsValid(action.Request) {
				item.SetValues(form.GetValues())
				ctrl.model.Update(*item)
			}

			action.Redirect("/admin/container/services")
			return nil
		},
	}))

	router.GET("/admin/container/services/delete/:id", webapp.MakeAction(webapp.Action{
		RenderTemplate: true,
		TemplatePath:   ctrl.config.Paths.Forms,
		TemplateName:   "edit",
		ActionFunc: func(action *webapp.Action) interface{} {
			ctrl.model.Delete(action.Params.ByName("id"))
			action.Redirect("/admin/container/services")
			return nil
		},
	}))
}
コード例 #30
0
ファイル: http.go プロジェクト: imjorge/flynn
func (api *HTTPAPI) RegisterRoutes(r *httprouter.Router) {
	r.POST("/storage/providers", api.CreateProvider)
	r.POST("/storage/providers/:provider_id/volumes", api.Create)
	r.GET("/storage/volumes", api.List)
	r.GET("/storage/volumes/:volume_id", api.Inspect)
	r.DELETE("/storage/volumes/:volume_id", api.Destroy)
	r.PUT("/storage/volumes/:volume_id/snapshot", api.Snapshot)
	// takes host and volID parameters, triggers a send on the remote host and give it a list of snaps already here, and pipes it into recv
	r.POST("/storage/volumes/:volume_id/pull_snapshot", api.Pull)
	// responds with a snapshot stream binary.  only works on snapshots, takes 'haves' parameters, usually called by a node that's servicing a 'pull_snapshot' request
	r.GET("/storage/volumes/:volume_id/send", api.Send)
}