diff options
| author | Shulhan <ms@kilabit.info> | 2023-11-22 03:23:21 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-11-26 21:32:46 +0700 |
| commit | c170365f09a38b0d9b09b74716dacd7a0114cd7d (patch) | |
| tree | 5fe386cfb764a53560a50e814ee670a9ab88dfa8 /lib/http/server.go | |
| parent | c64476c10a8a6d331278fdc96f896559d3939f17 (diff) | |
| download | pakakeh.go-c170365f09a38b0d9b09b74716dacd7a0114cd7d.tar.xz | |
lib/http: implement Server-Sent Events (SSE)
For server SSE, we add new type SSEEndpoint, for registering endpoint
that can handle SSE.
For client SSE, we add it in new sub package "sseclient".
Implements: https://todo.sr.ht/~shulhan/share/1
Implements: https://todo.sr.ht/~shulhan/share/2
Signed-off-by: Shulhan <ms@kilabit.info>
Diffstat (limited to 'lib/http/server.go')
| -rw-r--r-- | lib/http/server.go | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/lib/http/server.go b/lib/http/server.go index 96a2a902..f0f6f409 100644 --- a/lib/http/server.go +++ b/lib/http/server.go @@ -127,6 +127,34 @@ func (srv *Server) RegisterEndpoint(ep *Endpoint) (err error) { return err } +// RegisterSSE register Server-Sent Events endpoint. +// It will return an error if the Call field is not set or +// [ErrEndpointAmbiguous], if the same path is already registered. +func (srv *Server) RegisterSSE(ep *SSEEndpoint) (err error) { + var logp = `RegisterSSE` + + if ep.Call == nil { + return fmt.Errorf(`%s: Call field not set`, logp) + } + + // Check if the same GET path already registered. + var ( + rute *route + exist bool + ) + for _, rute = range srv.routeGets { + _, exist = rute.parse(ep.Path) + if exist { + return fmt.Errorf(`%s: %w`, logp, ErrEndpointAmbiguous) + } + } + + rute = newRouteSSE(ep) + srv.routeGets = append(srv.routeGets, rute) + + return nil +} + // registerDelete register HTTP method DELETE with specific endpoint to handle // it. func (srv *Server) registerDelete(ep *Endpoint) (err error) { @@ -561,12 +589,25 @@ func (srv *Server) HandleFS(res http.ResponseWriter, req *http.Request) { // handleGet handle the GET request by searching the registered route and // calling the endpoint. func (srv *Server) handleGet(res http.ResponseWriter, req *http.Request) { - for _, rute := range srv.routeGets { - vals, ok := rute.parse(req.URL.Path) - if ok { + var ( + rute *route + vals map[string]string + ok bool + ) + for _, rute = range srv.routeGets { + vals, ok = rute.parse(req.URL.Path) + if !ok { + continue + } + if rute.kind == routeKindHttp { rute.endpoint.call(res, req, srv.evals, vals) return } + if rute.kind == routeKindSSE { + rute.endpointSSE.call(res, req, srv.evals, vals) + return + } + // Unknown kind will be handled by HandleFS. } srv.HandleFS(res, req) |
