http, websocket api handler 추가

This commit is contained in:
2023-09-19 18:50:17 +09:00
parent 1af5d72819
commit 49a3722a7e
5 changed files with 221 additions and 64 deletions

View File

@ -1,6 +1,7 @@
package gocommon
import (
"bytes"
"context"
"encoding/gob"
"encoding/json"
@ -699,22 +700,68 @@ func MakeHttpApiHandler[T any](receiver *T, receiverName string) HttpApiHandler
}
}
type HttpApiHandlerContainer struct {
methods map[string]apiFuncType
type HttpApiBroker struct {
methods map[string]apiFuncType
methods_dup map[string][]apiFuncType
}
func (hc *HttpApiHandlerContainer) RegisterApiHandler(receiver HttpApiHandler) {
type bufferReadCloser struct {
*bytes.Reader
}
func (buff *bufferReadCloser) Close() error { return nil }
type readOnlyResponseWriter struct {
inner http.ResponseWriter
statusCode int
}
func (w *readOnlyResponseWriter) Header() http.Header {
return w.inner.Header()
}
func (w *readOnlyResponseWriter) Write(in []byte) (int, error) {
logger.Println("readOnlyResponseWriter cannot write")
return len(in), nil
}
func (w *readOnlyResponseWriter) WriteHeader(statusCode int) {
w.statusCode = statusCode
}
func (hc *HttpApiBroker) AddHandler(receiver HttpApiHandler) {
if hc.methods == nil {
hc.methods = make(map[string]apiFuncType)
hc.methods_dup = make(map[string][]apiFuncType)
}
for k, v := range receiver.methods {
logger.Println("http api registered :", k)
hc.methods[k] = v
hc.methods_dup[k] = append(hc.methods_dup[k], v)
if len(hc.methods_dup[k]) > 1 {
chain := hc.methods_dup[k]
hc.methods[k] = func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
defer r.Body.Close()
wrap := &readOnlyResponseWriter{inner: w, statusCode: 200}
for _, f := range chain {
r.Body = &bufferReadCloser{bytes.NewReader(body)}
f(wrap, r)
}
if wrap.statusCode != 200 {
w.WriteHeader(wrap.statusCode)
}
}
} else {
hc.methods[k] = v
}
}
}
func (hc *HttpApiHandlerContainer) Call(funcname string, w http.ResponseWriter, r *http.Request) {
func (hc *HttpApiBroker) Call(funcname string, w http.ResponseWriter, r *http.Request) {
if found := hc.methods[funcname]; found != nil {
found(w, r)
} else {