mirror of
				https://github.com/datarhei/core.git
				synced 2025-11-01 03:42:51 +08:00 
			
		
		
		
	Add logging HTTP requests as single session
This commit is contained in:
		| @@ -94,6 +94,8 @@ func NewHLSWithConfig(config HLSConfig) echo.MiddlewareFunc { | ||||
| func (h *hls) handleIngress(c echo.Context, next echo.HandlerFunc) error { | ||||
| 	req := c.Request() | ||||
|  | ||||
| 	ctxuser := util.DefaultContext(c, "user", "") | ||||
|  | ||||
| 	path := req.URL.Path | ||||
|  | ||||
| 	if strings.HasSuffix(path, ".m3u8") { | ||||
| @@ -113,10 +115,15 @@ func (h *hls) handleIngress(c echo.Context, next echo.HandlerFunc) error { | ||||
| 			} | ||||
|  | ||||
| 			if !h.ingressCollector.IsKnownSession(path) { | ||||
| 				ip, _ := net.AnonymizeIPString(c.RealIP()) | ||||
|  | ||||
| 				// Register a new session | ||||
| 				reference := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path)) | ||||
| 				h.ingressCollector.RegisterAndActivate(path, reference, path, "") | ||||
| 				h.ingressCollector.RegisterAndActivate(path, reference, path, ip) | ||||
|  | ||||
| 				h.ingressCollector.Extra(path, map[string]interface{}{ | ||||
| 					"name":       ctxuser, | ||||
| 					"ip":         ip, | ||||
| 					"user_agent": req.Header.Get("User-Agent"), | ||||
| 				}) | ||||
| 			} | ||||
|   | ||||
| @@ -4,8 +4,13 @@ import ( | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
|  | ||||
| 	"github.com/datarhei/core/v16/glob" | ||||
| 	"github.com/datarhei/core/v16/http/api" | ||||
| 	"github.com/datarhei/core/v16/http/handler/util" | ||||
| 	"github.com/datarhei/core/v16/session" | ||||
| 	"github.com/lithammer/shortuuid/v4" | ||||
|  | ||||
| 	"github.com/labstack/echo/v4" | ||||
| 	"github.com/labstack/echo/v4/middleware" | ||||
| @@ -43,6 +48,8 @@ func NewHTTPWithConfig(config HTTPConfig) echo.MiddlewareFunc { | ||||
| 				return next(c) | ||||
| 			} | ||||
|  | ||||
| 			ctxuser := util.DefaultContext(c, "user", "") | ||||
|  | ||||
| 			req := c.Request() | ||||
| 			res := c.Response() | ||||
|  | ||||
| @@ -51,32 +58,91 @@ func NewHTTPWithConfig(config HTTPConfig) echo.MiddlewareFunc { | ||||
| 				host = "" | ||||
| 			} | ||||
|  | ||||
| 			path := req.URL.Path | ||||
|  | ||||
| 			location := path + req.URL.RawQuery | ||||
| 			remote := req.RemoteAddr | ||||
|  | ||||
| 			id := shortuuid.New() | ||||
|  | ||||
| 			data := map[string]interface{}{} | ||||
|  | ||||
| 			e := util.DefaultContext[interface{}](c, "session", nil) | ||||
| 			if e != nil { | ||||
| 				var ok bool | ||||
| 				data, ok = e.(map[string]interface{}) | ||||
| 				if !ok { | ||||
| 					return api.Err(http.StatusForbidden, "", "invalid session data, cast") | ||||
| 				} | ||||
|  | ||||
| 				if match, ok := data["match"].(string); ok { | ||||
| 					if ok, err := glob.Match(match, path, '/'); !ok { | ||||
| 						if err != nil { | ||||
| 							return api.Err(http.StatusForbidden, "", "no match for '%s' in %s: %s", match, path, err.Error()) | ||||
| 						} | ||||
|  | ||||
| 						return api.Err(http.StatusForbidden, "", "no match for '%s' in %s", match, path) | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				referrer := req.Header.Get("Referer") | ||||
| 				if u, err := url.Parse(referrer); err == nil { | ||||
| 					referrer = u.Host | ||||
| 				} | ||||
|  | ||||
| 				if remote, ok := data["remote"].([]string); ok && len(remote) != 0 { | ||||
| 					match := false | ||||
| 					for _, r := range remote { | ||||
| 						if referrer == r { | ||||
| 							match = true | ||||
| 							break | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
| 					if !match { | ||||
| 						return api.Err(http.StatusForbidden, "", "remote not allowed") | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			data["name"] = ctxuser | ||||
| 			data["method"] = req.Method | ||||
| 			data["code"] = 0 | ||||
|  | ||||
| 			reader := req.Body | ||||
| 			r := &fakeReader{ | ||||
| 				reader: req.Body, | ||||
| 			} | ||||
| 			req.Body = r | ||||
|  | ||||
| 			defer func() { | ||||
| 				req.Body = reader | ||||
|  | ||||
| 				if config.Collector.IsCollectableIP(host) { | ||||
| 					config.Collector.RegisterAndActivate("HTTP", "", "any", "any") | ||||
| 					config.Collector.Ingress("HTTP", r.size+headerSize(req.Header)) | ||||
| 				} | ||||
| 			}() | ||||
|  | ||||
| 			writer := res.Writer | ||||
| 			w := &fakeWriter{ | ||||
| 				ResponseWriter: res.Writer, | ||||
| 			} | ||||
| 			res.Writer = w | ||||
|  | ||||
| 			if config.Collector.IsCollectableIP(host) { | ||||
| 				config.Collector.RegisterAndActivate(id, "", location, remote) | ||||
| 				config.Collector.Extra(id, data) | ||||
| 			} | ||||
|  | ||||
| 			defer config.Collector.Close(id) | ||||
|  | ||||
| 			defer func() { | ||||
| 				req.Body = reader | ||||
|  | ||||
| 				if config.Collector.IsCollectableIP(host) { | ||||
| 					config.Collector.Ingress(id, r.size+headerSize(req.Header)) | ||||
| 				} | ||||
| 			}() | ||||
|  | ||||
| 			defer func() { | ||||
| 				res.Writer = writer | ||||
|  | ||||
| 				if config.Collector.IsCollectableIP(host) { | ||||
| 					config.Collector.Egress("HTTP", w.size+headerSize(res.Header())) | ||||
| 					config.Collector.Egress(id, w.size+headerSize(res.Header())) | ||||
| 					data["code"] = res.Status | ||||
| 					config.Collector.Extra(id, data) | ||||
| 				} | ||||
| 			}() | ||||
|  | ||||
| @@ -104,6 +170,13 @@ func (r *fakeReader) Close() error { | ||||
| type fakeWriter struct { | ||||
| 	http.ResponseWriter | ||||
| 	size int64 | ||||
| 	code int | ||||
| } | ||||
|  | ||||
| func (w *fakeWriter) WriteHeader(statusCode int) { | ||||
| 	w.ResponseWriter.WriteHeader(statusCode) | ||||
|  | ||||
| 	w.code = statusCode | ||||
| } | ||||
|  | ||||
| func (w *fakeWriter) Write(body []byte) (int, error) { | ||||
|   | ||||
| @@ -371,9 +371,6 @@ func NewServer(config Config) (Server, error) { | ||||
| 			return nil | ||||
| 		}, | ||||
| 	})) | ||||
| 	s.router.Use(mwsession.NewHTTPWithConfig(mwsession.HTTPConfig{ | ||||
| 		Collector: config.Sessions.Collector("http"), | ||||
| 	})) | ||||
|  | ||||
| 	s.router.HideBanner = true | ||||
| 	s.router.HidePort = true | ||||
| @@ -386,6 +383,10 @@ func NewServer(config Config) (Server, error) { | ||||
|  | ||||
| 	s.router.Use(s.middleware.iam) | ||||
|  | ||||
| 	s.router.Use(mwsession.NewHTTPWithConfig(mwsession.HTTPConfig{ | ||||
| 		Collector: config.Sessions.Collector("http"), | ||||
| 	})) | ||||
|  | ||||
| 	// Add static routes | ||||
| 	if path, target := config.Router.StaticRoute(); len(target) != 0 { | ||||
| 		group := s.router.Group(path) | ||||
|   | ||||
| @@ -314,7 +314,7 @@ func (r *registry) Register(id string, conf CollectorConfig) (Collector, error) | ||||
| 		return nil, fmt.Errorf("a collector with the ID '%s' already exists", id) | ||||
| 	} | ||||
|  | ||||
| 	m, err := newCollector(id, r.persist.sessionsCh, r.logger.WithComponent(id), conf) | ||||
| 	m, err := newCollector(id, r.persist.sessionsCh, r.logger, conf) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Ingo Oppermann
					Ingo Oppermann