Example #1
0
// An HTTP handler for matching incoming requests with existing watches.
func (self *matchHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// The standard library does not support keep-alive timeouts,
	// so we'll just have to close the connection after every request
	// (or we could hope that clients remember to close their
	// connections (but if they don't, then we can't shutdown)).
	w.Header().Set("Connection", "close")

	defer func() {
		if e := recover(); e != nil {
			var str string

			switch u := e.(type) {
			case error:
				str = u.Error()
			default:
				str = fmt.Sprintf("%+v", e)
			}

			log.Printf("panic: (%d) %s", GOOSE_ERROR, str)
			http.Error(w, str, GOOSE_ERROR)
		}
	}()

	// Build a match expression from the request
	expr := watchdb.NewMatchExpr(self.DataSourceName, req.URL.Path, req.Method)

	// Lookup the associated watch, if any
	m, err := self.ws.Match(expr)
	if err != nil {
		http.Error(w, err.Error(), GOOSE_ERROR)
		return
	}

	// TODO: m.MatchType == watchdb.PASSTHRU

	tag := ""
	if m.IsMatch() {
		tag = m.Tag()
	}

	// Record the event.
	self.ep.Trace(eventdb.NewMessage(tag, req, map[string]string{
		"dataSourceName": self.DataSourceName,
	}))

	// Return an error code if we don't find any matching watches.
	if !m.IsMatch() {
		http.Error(w, "This request did not match any watches.", GOOSE_CONF_ERROR)
		return
	}

	// Otherwise, return an echo.
	m.Echo().ServeHTTP(w, req)
}
Example #2
0
func TestMatchWithService(t *testing.T) {
	ws, err := Start()
	if err != nil {
		t.Error(err)
		return
	}

	defer ws.Stop()

	w := fakeWatch()
	ws.Add(w)

	expr := watchdb.NewMatchExpr("dummy-service", w.Path, w.Method)
	m, err := ws.Match(expr)
	if err != nil {
		t.Error(err)
		return
	}

	if m.Tag() != w.Tag {
		t.Error("expected: %s, got: %s", w.Tag, m.Tag())
		return
	}
}
Example #3
0
func TestMatchHandler(t *testing.T) {
	const (
		LISTEN_ADDR = ":9002"
		WATCHED_URL = "http://127.0.0.1:9002/foo"
		WATCH_BODY  = "hello, world"
		DSN         = "dummy-service"
	)

	ws, err := worker.Start()
	if err != nil {
		t.Error(err)
		return
	}

	defer ws.Stop()

	echo := &fakeResponse{body: WATCH_BODY}
	w := watchdb.NewWatch(DSN,
		"/foo", "GET", "redis:watch:1234", echo)

	_, _, err = ws.Add(w)
	if err != nil {
		t.Error(err)
		return
	}

	mx := watchdb.NewMatchExpr(DSN, "/foo", "GET")
	m, _ := ws.Match(mx)
	if !m.IsMatch() {
		t.Errorf("watchdb doesn't recognize the watch")
		return
	}

	ep := eventdb.NopEventProvider()

	mux := NewMatchHandler(DSN, ws, ep)

	s, err := StartHttpServer(LISTEN_ADDR, mux)
	if err != nil {
		t.Error(err)
		return
	}

	defer s.Stop()

	resp, err := http.Get(WATCHED_URL)
	if err != nil {
		t.Error(err)
		return
	}

	if resp.StatusCode != 200 {
		t.Errorf("expected: %d, got: %d", 200, resp.StatusCode)
		return
	}

	bufr := bufio.NewReader(resp.Body)
	yy, err := ioutil.ReadAll(bufr)
	resp.Body.Close()
	if err != nil {
		t.Error(err)
		return
	}

	str := string(yy)
	if str != WATCH_BODY {
		t.Errorf("unexpected: %s", str)
		t.Errorf("expected: \"%s\", got: \"%s\"", WATCH_BODY, str)

		// Fprintln adds a '\n', oops.
		spew.Dump(yy)
		spew.Dump(str)
		return
	}
}