// start accepting connections and consume each of them as they come in func (h *HTTPProvider) Start(p event.Passer) { defer func() { if r := recover(); r != nil { fmt.Println("Recovered in f", r) } }() std_http.HandleFunc(ENDPOINT, func(w std_http.ResponseWriter, r *std_http.Request) { // handle the case where a provider is restarting and needs to check if a listener is a bangarang provider or not if r.URL.Query().Get("init_check") == "true" { w.Write([]byte(START_HANDSHAKE)) } buff, err := ioutil.ReadAll(r.Body) if err != nil { logrus.Error(err) std_http.Error(w, err.Error(), std_http.StatusInternalServerError) return } e := &event.Event{} err = h.pool.Decode(buff, e) if err != nil { logrus.Error(err) std_http.Error(w, err.Error(), std_http.StatusInternalServerError) return } p.Pass(e) logrus.Debug("Done processing http event") }) logrus.Infof("Serving http listener on %s", h.listen) logrus.Fatal(std_http.ListenAndServe(h.listen, nil)) }
func (t *TCPProvider) consume(conn *net.TCPConn, p event.Passer) { buff := make([]byte, 1024*200) var size_buff = make([]byte, 8) var nextEventSize uint64 var n int var err error // write the start of the handshake so the client can verify this is a bangarang client conn.Write([]byte(START_HANDSHAKE)) for { // read the size of the next event n, err = conn.Read(size_buff) if err != nil { if err == io.EOF { time.Sleep(50 * time.Millisecond) } else { logrus.Error(err) return } } else { if n != 8 { logrus.Errorf("tcp-provider: Expecting 8byte 64bit unsigned int. Only got %d bytes", n) conn.Close() return } nextEventSize, _ = binary.Uvarint(size_buff) // read the next event err = readFull(conn, buff[:nextEventSize]) if err != nil { logrus.Error(err) conn.Close() return } e := &event.Event{} err = t.pool.Decode(buff[:nextEventSize], e) if err != nil { logrus.Error(err, string(buff[:nextEventSize])) } else { p.Pass(e) } } } }
// consume a tcp connection's events and pass them on to the next step in the pipeline func (t *TCPProvider) consume(conn *net.TCPConn, p event.Passer) { buff := make([]byte, 1024*200) var size_buff = make([]byte, 8) var nextEventSize uint64 var err error logContext := func() { // log out context logrus.Errorf("Panic Context... size_buff: %x nextEventSize: %d buff: %x", size_buff, nextEventSize, buff) } // recover from a panaic while dealing with the tcp connection defer func() { if r := recover(); r != nil { err := conn.Close() if err != nil { logrus.Error(err) } logrus.Error("Recoverd from panic while reading tcp connection: ", r) logContext() } }() // write the start of the handshake so the client can verify this is a bangarang client conn.Write([]byte(START_HANDSHAKE)) for { // read the size of the next event err = readFull(conn, size_buff) if err != nil { if err == io.EOF { time.Sleep(50 * time.Millisecond) } else { logrus.Error(err) return } } else { nextEventSize = binary.LittleEndian.Uint64(size_buff) // make sure the nextEventSize is not larger than the buffer we are going to read into if int(nextEventSize) > len(buff) { logrus.Errorf("Incorrect size parsed for next event %d", nextEventSize) logContext() conn.Close() return } // read the next event err = readFull(conn, buff[:nextEventSize]) if err != nil { logrus.Error(err) conn.Close() return } e := &event.Event{} err = t.pool.Decode(buff[:nextEventSize], e) if err != nil { logrus.Errorf("Unable to parse event %s", err.Error()) conn.Close() } else { p.Pass(e) } } } }