-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfgweb.go
236 lines (195 loc) · 6.13 KB
/
fgweb.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
package fgweb
import (
"fmt"
"net/http"
"path/filepath"
"runtime"
"time"
"github.com/agungdhewe/dwlog"
"github.com/agungdhewe/dwtpl"
"github.com/alexedwards/scs/v2"
"github.com/fgtago/fgweb/appsmodel"
"github.com/fgtago/fgweb/config"
"github.com/fgtago/fgweb/defaulthandlers"
"github.com/fgtago/fgweb/midware"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
type RouteHandlerFunc func(mux *chi.Mux) error
var ws *appsmodel.Webservice
var cfgcontent *[]byte
// New initializes a new instance of the Webservice struct.
//
// Parameters:
// - rootDir: the root directory of the webservice.
// - cfgpath: the path to the configuration file.
//
// Returns:
// - *appsmodel.Webservice: a pointer to the initialized Webservice struct.
// - error: an error if there was a problem reading the configuration file or preparing the template.
func New(rootDir string, cfgpath string) (*appsmodel.Webservice, error) {
// siapkan core webservice
ws = &appsmodel.Webservice{}
ws.RootDir = rootDir
// current direktori relative ke fgweb.go
_, filename, _, _ := runtime.Caller(0)
ws.CurrentWsDir = filepath.Dir(filename)
// baca configurasi file
cfgcontent = &[]byte{}
cfg, err := config.ReadFromYml(cfgpath, cfgcontent)
if err != nil {
dwlog.Error(err.Error())
return nil, fmt.Errorf("cannot read config file: %s", cfgpath)
}
ws.Configuration = cfg
// set show server error
ws.ShowServerError = ws.Configuration.ShowServerError
// siapkan session manager
session := scs.New()
session.Lifetime = time.Duration(ws.Configuration.Cookie.LifeTime) * time.Hour
session.Cookie.Persist = ws.Configuration.Cookie.Persist
session.Cookie.Secure = ws.Configuration.Cookie.Secure
session.Cookie.Path = ws.Configuration.Cookie.Path
if ws.Configuration.Cookie.SameSite == "lax" {
session.Cookie.SameSite = http.SameSiteLaxMode
} else if ws.Configuration.Cookie.SameSite == "strict" {
session.Cookie.SameSite = http.SameSiteStrictMode
} else if ws.Configuration.Cookie.SameSite == "none" {
session.Cookie.SameSite = http.SameSiteNoneMode
} else {
session.Cookie.SameSite = http.SameSiteDefaultMode
}
//session.Cookie.SameSite = http.SameSiteLaxMode
//fmt.Println(session.Cookie.SameSite, ws.Configuration.Cookie.SameSite)
ws.Session = session
// siapkan keperluan lain
defaulthandlers.New(ws)
err = PrepareTemplate(ws)
if err != nil {
dwlog.Error(err.Error())
return nil, fmt.Errorf("error while preparing template")
}
appsmodel.NewWebservice(ws)
return ws, nil
}
func GetCfgContent() *[]byte {
return cfgcontent
}
func CreateServer(port int, hnd RouteHandlerFunc) *http.Server {
// buat router
ws.Mux = httpRequestHandler(hnd)
// siapkan server
srv := &http.Server{
Addr: fmt.Sprintf(":%d", port),
Handler: ws.Mux,
}
return srv
}
// StartService starts the web service on the specified port and handles incoming requests using the provided RouteHandlerFunc.
//
// Parameters:
// - port: the port number on which the service should be started.
// - hnd: the RouteHandlerFunc that will handle incoming requests.
//
// Returns:
// - err: an error if there was a problem starting the service.
func StartService(port int, hnd RouteHandlerFunc) (err error) {
// buat router
ws.Mux = httpRequestHandler(hnd)
// siapkan server
srv := http.Server{
Addr: fmt.Sprintf(":%d", port),
Handler: ws.Mux,
}
// jalankan server
err = srv.ListenAndServe()
if err != nil {
dwlog.Error(err.Error())
return fmt.Errorf("cannot start service on port %d", port)
}
return nil
}
func CreateRequestHandler(hnd RouteHandlerFunc) *chi.Mux {
return httpRequestHandler(hnd)
}
// httpRequestHandler creates a new router and sets up middleware before invoking the provided RouteHandlerFunc.
//
// Parameters:
// - hnd: The RouteHandlerFunc that will handle incoming requests.
//
// Returns:
// - *chi.Mux: The configured router.
func httpRequestHandler(hnd RouteHandlerFunc) *chi.Mux {
// ws := appsmodel.GetWebservice()
mux := chi.NewRouter()
// external middleware
mux.Use(middleware.Recoverer)
// testing if page is hit
if ws.Configuration.HitTest {
mux.Use(midware.HitTest)
}
// internal middleware
mux.Use(midware.Csrf)
mux.Use(midware.SessionLoader)
mux.Use(midware.MobileDetect)
mux.Use(midware.DefaultPageVariable)
mux.Use(midware.User)
// handle dari main program
hnd(mux)
// kalau halaman tidak ditemukan
mux.NotFound(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
pv := ctx.Value(appsmodel.PageVariableKeyName).(*appsmodel.PageVariable)
defaulthandlers.ErrorPageHandler(404, "page not found", pv, w, r)
})
return mux
}
// Get registers a route handler function for the given pattern in the chi.Mux router.
//
// Parameters:
// - mux: The chi.Mux router to register the route handler on.
// - pattern: The URL pattern for the route.
// - fn: The route handler function that will handle incoming requests.
//
// Returns: None.
func Get(mux *chi.Mux, pattern string, fn http.HandlerFunc) {
mux.Get(pattern, func(w http.ResponseWriter, r *http.Request) {
fn(w, r)
})
}
// Post registers a route handler function for the given pattern in the chi.Mux router.
//
// Parameters:
// - mux: The chi.Mux router to register the route handler on.
// - pattern: The URL pattern for the route.
// - fn: The route handler function that will handle incoming requests.
func Post(mux *chi.Mux, pattern string, fn http.HandlerFunc) {
mux.Post(pattern, func(w http.ResponseWriter, r *http.Request) {
fn(w, r)
})
}
// PrepareTemplate prepares the template for the given webservice.
//
// Parameters:
// - ws: The webservice for which the template needs to be prepared.
//
// Returns:
// - error: An error if the template preparation fails.
func PrepareTemplate(ws *appsmodel.Webservice) error {
// prepare template
cfgtpl := &dwtpl.Configuration{
Dir: filepath.Join(ws.RootDir, ws.Configuration.Template.Dir),
Cached: ws.Configuration.Template.Cached,
}
mgr, err := dwtpl.New(cfgtpl, ws.Configuration.Template.Options...)
if err != nil {
return err
}
pagedir := filepath.Join(ws.RootDir, ws.Configuration.Application.PageDir)
err = mgr.CachePages(pagedir)
if err != nil {
return err
}
ws.TplMgr = mgr
return nil
}