Пример #1
0
func main() {
	// Create a new Service rooted at "/"
	service := siesta.NewService("/")

	// Route accepts normal http.Handlers.
	service.Route("GET", "/", "Sends 'Hello, world!'", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Hello, world!")
	})

	// Let's create some simple "middleware."
	// This handler will accept a Context argument and will add the current
	// time to it.
	timestamper := func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		c.Set("start", time.Now())
	}

	// This is the handler that will actually send data back to the client.
	// It also takes a Context argument so it can get the timestamp from the
	// previous handler.
	timeHandler := func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		start := c.Get("start").(time.Time)
		delta := time.Now().Sub(start)
		fmt.Fprintf(w, "That took %v.\n", delta)
	}

	// We can compose these handlers together.
	timeHandlers := siesta.Compose(timestamper, timeHandler)

	// Finally, we'll add the new handler we created using composition to a new route.
	service.Route("GET", "/time", "Sends how long it took to send a message", timeHandlers)

	// service is an http.Handler, so we can pass it directly to ListenAndServe.
	log.Fatal(http.ListenAndServe(":8080", service))
}
Пример #2
0
func main() {
	// Create a new service rooted at /.
	service := siesta.NewService("/")

	// requestIdentifier assigns an ID to every request
	// and adds it to the context for that request.
	// This is useful for logging.
	service.AddPre(requestIdentifier)

	// Add access to the state via the context in every handler.
	service.AddPre(func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		c.Set("db", state)
	})

	// We'll add the authenticator middleware to the "pre" chain.
	// It will ensure that every request has a valid token.
	service.AddPre(authenticator)

	// Response generation
	service.AddPost(responseGenerator)
	service.AddPost(responseWriter)

	// Custom 404 handler
	service.SetNotFound(func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		c.Set("status-code", http.StatusNotFound)
		c.Set("error", "not found")
	})

	// Routes
	service.Route("GET", "/resources/:resourceID", "Retrieves a resource",
		getResource)

	log.Println("Listening on :8080")
	panic(http.ListenAndServe(":8080", service))
}
Пример #3
0
func main() {
	// Create a new Service rooted at "/"
	service := siesta.NewService("/")

	// Here's a handler that uses a URL parameter.
	// Example: GET /greet/Bob
	service.Route("GET", "/greet/:name", "Greets with a name.",
		func(w http.ResponseWriter, r *http.Request) {
			var params siesta.Params
			name := params.String("name", "", "Person's name")

			err := params.Parse(r.Form)
			if err != nil {
				log.Println("Error parsing parameters!", err)
				return
			}

			fmt.Fprintf(w, "Hello, %s!", *name)
		},
	)

	// Here's a handler that uses a query string parameter.
	// Example: GET /square?number=10
	service.Route("GET", "/square", "Prints the square of a number.",
		func(w http.ResponseWriter, r *http.Request) {
			var params siesta.Params
			number := params.Int("number", 0, "A number to square")

			err := params.Parse(r.Form)
			if err != nil {
				log.Println("Error parsing parameters!", err)
				return
			}

			fmt.Fprintf(w, "%d * %d = %d.", *number, *number, (*number)*(*number))
		},
	)

	// We can also use both URL and query string parameters.
	// Example: GET /exponentiate/10?power=10
	service.Route("GET", "/exponentiate/:number", "Exponentiates a number.",
		func(w http.ResponseWriter, r *http.Request) {
			var params siesta.Params
			number := params.Float64("number", 0, "A number to exponentiate")
			power := params.Float64("power", 1, "Power")

			err := params.Parse(r.Form)
			if err != nil {
				log.Println("Error parsing parameters!", err)
				return
			}

			fmt.Fprintf(w, "%g ^ %g = %g.", *number, *power, math.Pow(*number, *power))
		},
	)

	// service is an http.Handler, so we can pass it directly to ListenAndServe.
	log.Fatal(http.ListenAndServe(":8080", service))
}
Пример #4
0
func initSiesta() {
	h := siesta.NewService("/")
	h.Route("GET", "/", "",
		func(w http.ResponseWriter, r *http.Request) {
			w.Header().Set("Content-Type", "text/plain; charset=utf-8")
			fmt.Fprintf(w, "Hello, World")
		})
	h.Route("GET", "/:name", "",
		func(w http.ResponseWriter, r *http.Request) {
			var params siesta.Params
			name := params.String("name", "", "")
			params.Parse(r.Form)
			w.Header().Set("Content-Type", "text/plain; charset=utf-8")
			fmt.Fprintf(w, "Hello, %s", *name)
		})
	registerHandler("siesta", h)
}
Пример #5
0
func (s *APIServer) Run() {
	service := siesta.NewService("/")

	service.AddPre(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Headers", r.Header.Get("Access-Control-Request-Headers"))
	})

	service.AddPost(func(c siesta.Context, w http.ResponseWriter, r *http.Request, q func()) {
		resp := c.Get(responseKey)
		err, _ := c.Get(errorKey).(string)

		if resp == nil && err == "" {
			return
		}

		enc := json.NewEncoder(w)
		enc.Encode(APIResponse{
			Data:  resp,
			Error: err,
		})
	})

	service.Route("GET", "/", "Default page", func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		c.Set(responseKey, "Welcome to the Cistern API!")
	})

	service.Route("GET", "/devices", "Lists sources", func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		type ipHostname struct {
			IP       string `json:"ip"`
			Hostname string `json:"hostname,omitempty"`
		}

		devices := []ipHostname{}

		for _, dev := range s.deviceRegistry.Devices() {
			devices = append(devices, ipHostname{
				IP:       dev.IP().String(),
				Hostname: dev.Hostname(),
			})
		}

		c.Set(responseKey, devices)
	})

	service.Route("GET", "/devices/:device/metrics",
		"Lists metrics for a device",
		func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
			var params siesta.Params
			device := params.String("device", "", "Device name")
			err := params.Parse(r.Form)
			if err != nil {
				c.Set(errorKey, err.Error())
				return
			}

			address := net.ParseIP(*device)
			dev, present := s.deviceRegistry.Lookup(address)
			if !present {
				c.Set(errorKey, "device not found")
				return
			}

			c.Set(responseKey, dev.Metrics())
		})

	service.Route("GET", "/devices/:device/flows",
		"Lists top flows for a device",
		func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
			var params siesta.Params
			device := params.String("device", "", "Device name")
			err := params.Parse(r.Form)
			if err != nil {
				c.Set(errorKey, err.Error())
				return
			}

			address := net.ParseIP(*device)
			dev, present := s.deviceRegistry.Lookup(address)
			if !present {
				c.Set(errorKey, "device not found")
				return
			}

			type flowsResponse struct {
				ByBytes   []flows.Flow `json:"byBytes"`
				ByPackets []flows.Flow `json:"byPackets"`
			}

			topTalkers := dev.TopTalkers()
			if topTalkers == nil {
				c.Set(errorKey, "No active flows")
				return
			}

			resp := flowsResponse{
				ByBytes:   topTalkers.ByBytes(),
				ByPackets: topTalkers.ByPackets(),
			}

			c.Set(responseKey, resp)
		})

	service.Route("OPTIONS", "/series/query",
		"Accepts an OPTIONS request",
		func(w http.ResponseWriter, r *http.Request) {
			// Doesn't do anything
		})

	service.Route("POST", "/series/query",
		"Lists metrics for a device",
		s.querySeriesRoute())

	http.Handle("/", service)

	go http.ListenAndServe(s.addr, nil)
}