123 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package http
 | |
| 
 | |
| import (
 | |
| 	"io/ioutil"
 | |
| 	"net/http"
 | |
| 	"strconv"
 | |
| 
 | |
| 	"git.defalsify.org/vise.git/logging"
 | |
| 
 | |
| 	"git.grassecon.net/urdt/ussd/internal/handlers"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	logg = logging.NewVanilla().WithDomain("httpserver")
 | |
| )
 | |
| 
 | |
| type DefaultRequestParser struct {
 | |
| }
 | |
| 
 | |
| 
 | |
| func(rp *DefaultRequestParser) GetSessionId(rq any) (string, error) {
 | |
| 	rqv, ok := rq.(*http.Request)
 | |
| 	if !ok {
 | |
| 		return "", handlers.ErrInvalidRequest
 | |
| 	}
 | |
| 	v := rqv.Header.Get("X-Vise-Session")
 | |
| 	if v == "" {
 | |
| 		return "", handlers.ErrSessionMissing
 | |
| 	}
 | |
| 	return v, nil
 | |
| }
 | |
| 
 | |
| func(rp *DefaultRequestParser) GetInput(rq any) ([]byte, error) {
 | |
| 	rqv, ok := rq.(*http.Request)
 | |
| 	if !ok {
 | |
| 		return nil, handlers.ErrInvalidRequest
 | |
| 	}
 | |
| 	defer rqv.Body.Close()
 | |
| 	v, err := ioutil.ReadAll(rqv.Body)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return v, nil
 | |
| }
 | |
| 
 | |
| type SessionHandler struct {
 | |
| 	handlers.RequestHandler
 | |
| }
 | |
| 
 | |
| func ToSessionHandler(h handlers.RequestHandler) *SessionHandler {
 | |
| 	return &SessionHandler{
 | |
| 		RequestHandler: h,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func(f *SessionHandler) writeError(w http.ResponseWriter, code int, err error) {
 | |
| 	s := err.Error()
 | |
| 	w.Header().Set("Content-Length", strconv.Itoa(len(s)))
 | |
| 	w.WriteHeader(code)
 | |
| 	_, err = w.Write([]byte{})
 | |
| 	if err != nil {
 | |
| 		logg.Errorf("error writing error!!", "err", err, "olderr", s)
 | |
| 		w.WriteHeader(500)
 | |
| 	}
 | |
| 	return 
 | |
| }
 | |
| 
 | |
| func(f *SessionHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
 | |
| 	var code int
 | |
| 	var err error
 | |
| 	var perr error
 | |
| 
 | |
| 	rqs := handlers.RequestSession{
 | |
| 		Ctx: req.Context(),
 | |
| 		Writer: w,
 | |
| 	}
 | |
| 
 | |
| 	rp := f.GetRequestParser()
 | |
| 	cfg := f.GetConfig()
 | |
| 	cfg.SessionId, err = rp.GetSessionId(req)
 | |
| 	if err != nil {
 | |
| 		logg.ErrorCtxf(rqs.Ctx, "", "header processing error", err)
 | |
| 		f.writeError(w, 400, err)
 | |
| 	}
 | |
| 	rqs.Config = cfg
 | |
| 	rqs.Input, err = rp.GetInput(req)
 | |
| 	if err != nil {
 | |
| 		logg.ErrorCtxf(rqs.Ctx, "", "header processing error", err)
 | |
| 		f.writeError(w, 400, err)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	rqs, err = f.Process(rqs)
 | |
| 	switch err {
 | |
| 	case handlers.ErrStorage:
 | |
| 		code = 500
 | |
| 	case handlers.ErrEngineInit:
 | |
| 		code = 500
 | |
| 	case handlers.ErrEngineExec:
 | |
| 		code = 500
 | |
| 	default:
 | |
| 		code = 200
 | |
| 	}
 | |
| 
 | |
| 	if code != 200 {
 | |
| 		f.writeError(w, 500, err)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	w.WriteHeader(200)
 | |
| 	w.Header().Set("Content-Type", "text/plain")
 | |
| 	rqs, err = f.Output(rqs)
 | |
| 	rqs, perr = f.Reset(rqs)
 | |
| 	if err != nil {
 | |
| 		f.writeError(w, 500, err)
 | |
| 		return
 | |
| 	}
 | |
| 	if perr != nil {
 | |
| 		f.writeError(w, 500, perr)
 | |
| 		return
 | |
| 	}
 | |
| }
 |