Beispiel #1
0
func main() {
	// Create our Gotcha application
	var app = gotcha.Create(Asset)

	// Set the logger output pattern
	log.Logger().Appender().SetLayout(layout.Pattern("[%d] [%p] %m"))
	log.Logger().SetLevel(log.Stol("TRACE"))

	// Get the router
	r := app.Router

	// Create some routes
	r.Get("/", example)
	r.Post("/", examplepost)
	r.Get("/foo", example2)
	r.Get("/bar", example3)
	r.Get("/stream", streamed)
	r.Get("/err", err)

	// Serve static content (but really use a CDN)
	r.Get("/images/(?P<file>.*)", r.Static("assets/images/{{file}}"))
	r.Get("/css/(?P<file>.*)", r.Static("assets/css/{{file}}"))

	// Listen to some events
	app.On(events.BeforeHandler, func(session *http.Session, next func()) {
		n := 0
		c, ok := session.Request.Cookies["test"]
		if ok {
			n, _ = strconv.Atoi(c.Value)
		}
		session.Stash["test"] = n
		log.Printf("Got BeforeHandler event! n = %d", n)
		next()
	})
	app.On(events.AfterHandler, func(session *http.Session, next func()) {
		n := session.Stash["test"].(int) + 1
		session.Response.Cookies.Set(&nethttp.Cookie{
			Name:  "test",
			Value: strconv.Itoa(n),
		})
		log.Println("Got AfterHandler event!")
		next()
	})
	app.On(events.AfterResponse, func(session *http.Session, next func()) {
		log.Println("Got AfterResponse event!")
		next()
	})

	// Start our application
	app.Start()

	<-make(chan int)
}
Beispiel #2
0
func (apiv2 *APIv2) search(w http.ResponseWriter, req *http.Request) {
	log.Println("[APIv2] GET /api/v2/search")

	apiv2.defaultOptions(w, req)

	start, limit := apiv2.getStartLimit(w, req)

	kind := req.URL.Query().Get("kind")
	if kind != "from" && kind != "to" && kind != "containing" {
		w.WriteHeader(400)
		return
	}

	query := req.URL.Query().Get("query")
	if len(query) == 0 {
		w.WriteHeader(400)
		return
	}

	var res messagesResult

	messages, total, _ := apiv2.config.Storage.Search(kind, query, start, limit)

	res.Count = len([]data.Message(*messages))
	res.Start = start
	res.Items = []data.Message(*messages)
	res.Total = total

	b, _ := json.Marshal(res)
	w.Header().Add("Content-Type", "application/json")
	w.Write(b)
}
Beispiel #3
0
func CreateAPIv1(conf *config.Config, r *pat.Router) *APIv1 {
	log.Println("Creating API v1")
	apiv1 := &APIv1{
		config: conf,
	}

	stream = goose.NewEventStream()

	r.Path("/api/v1/messages").Methods("GET").HandlerFunc(apiv1.messages)
	r.Path("/api/v1/messages").Methods("DELETE").HandlerFunc(apiv1.delete_all)
	r.Path("/api/v1/messages").Methods("OPTIONS").HandlerFunc(apiv1.defaultOptions)

	r.Path("/api/v1/messages/{id}").Methods("GET").HandlerFunc(apiv1.message)
	r.Path("/api/v1/messages/{id}").Methods("DELETE").HandlerFunc(apiv1.delete_one)
	r.Path("/api/v1/messages/{id}").Methods("OPTIONS").HandlerFunc(apiv1.defaultOptions)

	r.Path("/api/v1/messages/{id}/download").Methods("GET").HandlerFunc(apiv1.download)
	r.Path("/api/v1/messages/{id}/download").Methods("OPTIONS").HandlerFunc(apiv1.defaultOptions)

	r.Path("/api/v1/messages/{id}/mime/part/{part}/download").Methods("GET").HandlerFunc(apiv1.download_part)
	r.Path("/api/v1/messages/{id}/mime/part/{part}/download").Methods("OPTIONS").HandlerFunc(apiv1.defaultOptions)

	r.Path("/api/v1/messages/{id}/release").Methods("POST").HandlerFunc(apiv1.release_one)
	r.Path("/api/v1/messages/{id}/release").Methods("OPTIONS").HandlerFunc(apiv1.defaultOptions)

	r.Path("/api/v1/events").Methods("GET").HandlerFunc(apiv1.eventstream)
	r.Path("/api/v1/events").Methods("OPTIONS").HandlerFunc(apiv1.defaultOptions)

	go func() {
		keepaliveTicker := time.Tick(time.Minute)
		for {
			select {
			case msg := <-apiv1.config.MessageChan:
				log.Println("Got message in APIv1 event stream")
				bytes, _ := json.MarshalIndent(msg, "", "  ")
				json := string(bytes)
				log.Printf("Sending content: %s\n", json)
				apiv1.broadcast(json)
			case <-keepaliveTicker:
				apiv1.keepalive()
			}
		}
	}()

	return apiv1
}
Beispiel #4
0
func (apiv2 *APIv2) listOutgoingSMTP(w http.ResponseWriter, req *http.Request) {
	log.Println("[APIv2] GET /api/v2/outgoing-smtp")

	apiv2.defaultOptions(w, req)

	b, _ := json.Marshal(apiv2.config.OutgoingSMTP)
	w.Header().Add("Content-Type", "application/json")
	w.Write(b)
}
Beispiel #5
0
func (apiv1 *APIv1) eventstream(w http.ResponseWriter, req *http.Request) {
	log.Println("[APIv1] GET /api/v1/events")

	//apiv1.defaultOptions(session)
	if len(apiv1.config.CORSOrigin) > 0 {
		w.Header().Add("Access-Control-Allow-Origin", apiv1.config.CORSOrigin)
		w.Header().Add("Access-Control-Allow-Methods", "OPTIONS,GET,POST,DELETE")
	}

	stream.AddReceiver(w)
}
Beispiel #6
0
func (apiv2 *APIv2) deleteJim(w http.ResponseWriter, req *http.Request) {
	log.Println("[APIv2] DELETE /api/v2/jim")

	apiv2.defaultOptions(w, req)

	if apiv2.config.Monkey == nil {
		w.WriteHeader(404)
		return
	}

	apiv2.config.Monkey = nil
}
Beispiel #7
0
func (apiv2 *APIv2) jim(w http.ResponseWriter, req *http.Request) {
	log.Println("[APIv2] GET /api/v2/jim")

	apiv2.defaultOptions(w, req)

	if apiv2.config.Monkey == nil {
		w.WriteHeader(404)
		return
	}

	b, _ := json.Marshal(apiv2.config.Monkey)
	w.Header().Add("Content-Type", "application/json")
	w.Write(b)
}
Beispiel #8
0
func (apiv2 *APIv2) updateJim(w http.ResponseWriter, req *http.Request) {
	log.Println("[APIv2] PUT /api/v2/jim")

	apiv2.defaultOptions(w, req)

	if apiv2.config.Monkey == nil {
		w.WriteHeader(404)
		return
	}

	err := apiv2.newJimFromBody(w, req)
	if err != nil {
		w.WriteHeader(400)
	}
}
Beispiel #9
0
func (apiv1 *APIv1) delete_all(w http.ResponseWriter, req *http.Request) {
	log.Println("[APIv1] POST /api/v1/messages")

	apiv1.defaultOptions(w, req)

	w.Header().Add("Content-Type", "text/json")
	switch apiv1.config.Storage.(type) {
	case *storage.MongoDB:
		apiv1.config.Storage.(*storage.MongoDB).DeleteAll()
	case *storage.InMemory:
		apiv1.config.Storage.(*storage.InMemory).DeleteAll()
	default:
		w.WriteHeader(500)
		return
	}
}
Beispiel #10
0
func (apiv2 *APIv2) createJim(w http.ResponseWriter, req *http.Request) {
	log.Println("[APIv2] POST /api/v2/jim")

	apiv2.defaultOptions(w, req)

	if apiv2.config.Monkey != nil {
		w.WriteHeader(400)
		return
	}

	apiv2.config.Monkey = config.Jim

	// Try, but ignore errors
	// Could be better (e.g., ok if no json, error if badly formed json)
	// but this works for now
	apiv2.newJimFromBody(w, req)

	w.WriteHeader(201)
}
Beispiel #11
0
func (apiv2 *APIv2) messages(w http.ResponseWriter, req *http.Request) {
	log.Println("[APIv2] GET /api/v2/messages")

	apiv2.defaultOptions(w, req)

	start, limit := apiv2.getStartLimit(w, req)

	var res messagesResult

	messages, _ := apiv2.config.Storage.List(start, limit)

	res.Count = len([]data.Message(*messages))
	res.Start = start
	res.Items = []data.Message(*messages)
	res.Total = apiv2.config.Storage.Count()

	bytes, _ := json.Marshal(res)
	w.Header().Add("Content-Type", "text/json")
	w.Write(bytes)
}
Beispiel #12
0
func (apiv1 *APIv1) messages(w http.ResponseWriter, req *http.Request) {
	log.Println("[APIv1] GET /api/v1/messages")

	apiv1.defaultOptions(w, req)

	// TODO start, limit
	switch apiv1.config.Storage.(type) {
	case *storage.MongoDB:
		messages, _ := apiv1.config.Storage.(*storage.MongoDB).List(0, 1000)
		bytes, _ := json.Marshal(messages)
		w.Header().Add("Content-Type", "text/json")
		w.Write(bytes)
	case *storage.InMemory:
		messages, _ := apiv1.config.Storage.(*storage.InMemory).List(0, 1000)
		bytes, _ := json.Marshal(messages)
		w.Header().Add("Content-Type", "text/json")
		w.Write(bytes)
	default:
		w.WriteHeader(500)
	}
}
Beispiel #13
0
func CreateAPIv2(conf *config.Config, r *pat.Router) *APIv2 {
	log.Println("Creating API v2")
	apiv2 := &APIv2{
		config: conf,
	}

	r.Path("/api/v2/messages").Methods("GET").HandlerFunc(apiv2.messages)
	r.Path("/api/v2/messages").Methods("OPTIONS").HandlerFunc(apiv2.defaultOptions)

	r.Path("/api/v2/search").Methods("GET").HandlerFunc(apiv2.search)
	r.Path("/api/v2/search").Methods("OPTIONS").HandlerFunc(apiv2.defaultOptions)

	r.Path("/api/v2/jim").Methods("GET").HandlerFunc(apiv2.jim)
	r.Path("/api/v2/jim").Methods("POST").HandlerFunc(apiv2.createJim)
	r.Path("/api/v2/jim").Methods("PUT").HandlerFunc(apiv2.updateJim)
	r.Path("/api/v2/jim").Methods("DELETE").HandlerFunc(apiv2.deleteJim)
	r.Path("/api/v2/jim").Methods("OPTIONS").HandlerFunc(apiv2.defaultOptions)

	r.Path("/api/v2/outgoing-smtp").Methods("GET").HandlerFunc(apiv2.listOutgoingSMTP)
	r.Path("/api/v2/outgoing-smtp").Methods("OPTIONS").HandlerFunc(apiv2.defaultOptions)

	return apiv2
}
Beispiel #14
0
func (apiv1 *APIv1) broadcast(json string) {
	log.Println("[APIv1] BROADCAST /api/v1/events")
	b := []byte(json)
	stream.Notify("data", b)
}
Beispiel #15
0
// keepalive sends an empty keep alive message.
//
// This not only can keep connections alive, but also will detect broken
// connections. Without this it is possible for the server to become
// unresponsive due to too many open files.
func (apiv1 *APIv1) keepalive() {
	log.Println("[APIv1] KEEPALIVE /api/v1/events")
	stream.Notify("keepalive", []byte{})
}