@@ -3,9 +3,8 @@ package server
33import (
44 "crypto/rand"
55 "encoding/base64"
6- "encoding/json"
76 "errors"
8- "strings "
7+ "strconv "
98
109 emmerFs "github.com/TimoKats/emmer/server/fs"
1110
@@ -16,67 +15,27 @@ import (
1615 "os"
1716)
1817
19- var config Config
18+ var session Session
2019
21- // get HTTP request and format it into Request object used by server
22- func parseRequest (r * http.Request ) (Request , error ) {
23- // parse URL path (parameters, path)
24- request := Request {Method : r .Method , Mode : r .FormValue ("mode" )}
25- urlPath := r .URL .Path [len ("/api/" ):]
26- urlItems := strings .Split (urlPath , "/" )
27- if len (urlItems ) > 0 {
28- request .Table = urlItems [0 ]
29- if len (urlItems ) > 1 {
30- request .Key = urlItems [1 :]
31- }
32- }
33- // parse request body
34- payload , err := io .ReadAll (r .Body )
35- defer r .Body .Close () //nolint:errcheck
36- if err != nil {
37- return request , err
38- }
39- if len (payload ) > 0 {
40- err = json .Unmarshal (payload , & request .Value )
41- }
42- return request , err
43- }
20+ // helper function that selects the interface based on the URL path
21+ func ApiHandler (w http.ResponseWriter , r * http.Request ) {
4422
45- // takes response object and writes the HTTP response object
46- func parseResponse (w http.ResponseWriter , response Response ) error {
47- if response .Error != nil {
48- w .Header ().Set ("Content-Type" , "text/plain" )
49- if strings .Contains (response .Error .Error (), "not found" ) {
50- w .WriteHeader (404 )
51- } else {
52- w .WriteHeader (500 )
23+ // returns the item to apply CRUD operations on
24+ toggle := func (request Request ) (Item , error ) {
25+ if len (request .Key ) > 0 {
26+ return EntryItem {}, nil
5327 }
54- return json .NewEncoder (w ).Encode (response .Error .Error ())
55- }
56- w .Header ().Set ("Content-Type" , "application/json" )
57- w .WriteHeader (200 )
58- return json .NewEncoder (w ).Encode (response .Data )
59- }
60-
61- // returns the item to apply CRUD operations on
62- func selectItem (request Request ) (Item , error ) {
63- if len (request .Key ) > 0 {
64- return EntryItem {}, nil
28+ return TableItem {}, nil
6529 }
66- return TableItem {}, nil
67- }
6830
69- // helper function that selects the interface based on the URL path
70- func ApiHandler (w http.ResponseWriter , r * http.Request ) {
71- // set up
31+ // apply CRUD to correct item and return response
7232 var response Response
7333 request , parseErr := parseRequest (r )
74- item , itemErr := selectItem (request )
34+ item , itemErr := toggle (request )
7535 if err := errors .Join (parseErr , itemErr ); err != nil {
7636 http .Error (w , err .Error (), http .StatusBadRequest ) // to response
7737 return
7838 }
79- // select function
8039 switch request .Method {
8140 case "PUT" :
8241 response = item .Add (request )
@@ -85,33 +44,44 @@ func ApiHandler(w http.ResponseWriter, r *http.Request) {
8544 case "GET" :
8645 response = item .Get (request )
8746 default :
88- http .Error (w , "please use put/del/get" , http .StatusMethodNotAllowed ) // to response
47+ http .Error (w , "please use put/del/get" , http .StatusMethodNotAllowed )
8948 return
9049 }
91- // check errors and return response
9250 if err := parseResponse (w , response ); err != nil {
9351 http .Error (w , err .Error (), http .StatusInternalServerError )
9452 return
9553 }
9654}
9755
98- // does nothing. Only used for health checks
56+ // does nothing, only used for health checks
9957func PingHandler (w http.ResponseWriter , r * http.Request ) {
10058 fmt .Fprintln (w , "pong" ) //nolint:errcheck
10159}
10260
10361// shows last n (20) logs from server
10462func LogsHandler (w http.ResponseWriter , r * http.Request ) {
105- for _ , entry := range config .logBuffer .GetLogs () {
63+ for _ , entry := range session .logBuffer .GetLogs () {
10664 fmt .Fprint (w , entry ) //nolint:errcheck
10765 }
10866}
10967
68+ // write all cache to filesystem
69+ func CommitHandler (w http.ResponseWriter , r * http.Request ) {
70+ for filename , data := range session .cache .data {
71+ err := session .fs .Put (filename , data )
72+ if err != nil {
73+ log .Printf ("error writing cache of %s" , filename )
74+ } else {
75+ fmt .Fprint (w , "cache written to filesystem" ) //nolint:errcheck
76+ }
77+ }
78+ }
79+
11080// basic auth that uses public username/password for check
11181func Auth (next http.HandlerFunc ) http.HandlerFunc {
11282 return func (w http.ResponseWriter , r * http.Request ) {
11383 user , pass , ok := r .BasicAuth ()
114- if ! ok || user != config .username || pass != config .password {
84+ if ! ok || user != session . config .username || pass != session . config .password {
11585 w .Header ().Set ("WWW-Authenticate" , `Basic realm="Restricted"` )
11686 http .Error (w , "Unauthorized" , http .StatusUnauthorized )
11787 return
@@ -135,15 +105,29 @@ func init() {
135105 password = base64 .URLEncoding .EncodeToString (b )
136106 log .Printf ("set password to: %s" , password )
137107 }
108+ // cache settings
109+ commit := 1
110+ commitEnv := os .Getenv ("EM_COMMIT" )
111+ if commitEnv != "" {
112+ commitInt , err := strconv .Atoi (commitEnv )
113+ if err != nil {
114+ fmt .Printf ("Error converting commit strategy to int: %v" , err )
115+ return
116+ }
117+ commit = commitInt
118+ }
138119 // logs settings
139120 buffer := NewLogBuffer (20 )
140121 log .SetOutput (io .MultiWriter (os .Stdout , buffer ))
141122 // create config object
142- config = Config {
143- logBuffer : buffer ,
144- autoTable : os .Getenv ("EM_AUTOTABLE" ) != "false" ,
145- username : username ,
146- password : password ,
147- fs : emmerFs .SetupLocal (),
123+ session .config = Config {
124+ username : username ,
125+ password : password ,
126+ commit : commit ,
148127 }
128+ session .logBuffer = buffer
129+ session .cache .data = make (map [string ]map [string ]any )
130+ session .cache .data = make (map [string ]map [string ]any )
131+ session .fs = emmerFs .SetupLocal ()
132+ session .commits = 1
149133}
0 commit comments