diff --git a/context.go b/context.go index 9015159..31743ca 100644 --- a/context.go +++ b/context.go @@ -56,8 +56,8 @@ func (c *Context) Next() { func (c *Context) prepare(ctx *Context) { // Only parse multipart form if it hasn't been parsed already // This prevents race conditions when multiple goroutines might access the same request - if ctx.Request.httpRequest.MultipartForm == nil { - ctx.Request.httpRequest.ParseMultipartForm(int64(app.Config.Request.MaxUploadFileSize)) + if ctx.Request.HttpRequest.MultipartForm == nil { + ctx.Request.HttpRequest.ParseMultipartForm(int64(app.Config.Request.MaxUploadFileSize)) } } @@ -66,32 +66,50 @@ func (c *Context) GetPathParam(key string) interface{} { } func (c *Context) GetRequestParam(key string) interface{} { - return c.Request.httpRequest.FormValue(key) + return c.Request.HttpRequest.FormValue(key) } func (c *Context) RequestParamExists(key string) bool { - return c.Request.httpRequest.Form.Has(key) + return c.Request.HttpRequest.Form.Has(key) } func (c *Context) GetRequesForm(key string) interface{} { - c.Request.httpRequest.ParseForm() - return c.Request.httpRequest.Form[key] + c.Request.HttpRequest.ParseForm() + return c.Request.HttpRequest.Form[key] } func (c *Context) GetRequesBodyMap() map[string]interface{} { var dat map[string]any - body := c.Request.httpRequest.Body + body := c.Request.HttpRequest.Body + if body != nil { if content, err := io.ReadAll(body); err == nil { json.Unmarshal(content, &dat) } } + defer body.Close() return dat } +// get raw data for file binary +func (c *Context) GetRawBody() ([]byte, error) { + if c.Request.HttpRequest.Body == nil { + return nil, errors.New("empty body") + } + + defer c.Request.HttpRequest.Body.Close() + + data, err := io.ReadAll(c.Request.HttpRequest.Body) + if err != nil { + return nil, err + } + + return data, nil +} + // get json body and bind to dest interface func (c *Context) GetRequesBodyStruct(dest interface{}) error { - body := c.Request.httpRequest.Body + body := c.Request.HttpRequest.Body if body != nil { value := reflect.ValueOf(dest) if value.Kind() != reflect.Ptr { @@ -105,12 +123,12 @@ func (c *Context) GetRequesBodyStruct(dest interface{}) error { } func (c *Context) GetHeader(key string) string { - return c.Request.httpRequest.Header.Get(key) + return c.Request.HttpRequest.Header.Get(key) } func (c *Context) GetCookie() (UserCookie, error) { - user, err := GetCookie(c.Request.httpRequest) + user, err := GetCookie(c.Request.HttpRequest) if err != nil { return user, err } @@ -126,7 +144,7 @@ func (c *Context) GetQueueClient() *asynq.Client { } func (c *Context) GetUploadedFile(name string) (*UploadedFileInfo, error) { - file, fileHeader, err := c.Request.httpRequest.FormFile(name) + file, fileHeader, err := c.Request.HttpRequest.FormFile(name) if err != nil { return nil, fmt.Errorf("error retrieving file: %v", err) } @@ -290,7 +308,7 @@ func (c *Context) CastToString(value interface{}) string { } func (c Context) GetUserAgent() string { - return c.Request.httpRequest.UserAgent() + return c.Request.HttpRequest.UserAgent() } func (c *Context) CastToInt(value interface{}) int { diff --git a/context_test.go b/context_test.go index 9cc4287..d812454 100644 --- a/context_test.go +++ b/context_test.go @@ -25,7 +25,7 @@ func TestDebugAny(t *testing.T) { w := httptest.NewRecorder() c := &Context{ Request: &Request{ - httpRequest: r, + HttpRequest: r, httpPathParams: nil, }, Response: &Response{ @@ -538,7 +538,7 @@ func makeCTXLogTestCTX(t *testing.T, w http.ResponseWriter, r *http.Request, tmp t.Helper() return &Context{ Request: &Request{ - httpRequest: r, + HttpRequest: r, httpPathParams: nil, }, Response: &Response{ diff --git a/core.go b/core.go index 9afef81..8e7e4f1 100644 --- a/core.go +++ b/core.go @@ -242,7 +242,7 @@ func (app *App) makeHTTPRouterHandlerFunc(h Controller, ms []Hook) httprouter.Ha reqCtx := &requestContext{ chainIndex: 0, } - + // Prepare the chain nodes for this request mw := app.hooks.GetHooks() for _, v := range mw { @@ -252,11 +252,11 @@ func (app *App) makeHTTPRouterHandlerFunc(h Controller, ms []Hook) httprouter.Ha for _, v := range rhs { reqCtx.chainNodes = append(reqCtx.chainNodes, v) } - + // Store chain state in request context ctx := &Context{ Request: &Request{ - httpRequest: r.WithContext(context.WithValue(r.Context(), "goffeeChain", reqCtx)), + HttpRequest: r.WithContext(context.WithValue(r.Context(), "goffeeChain", reqCtx)), httpPathParams: ps, }, Response: &Response{ @@ -279,7 +279,7 @@ func (app *App) makeHTTPRouterHandlerFunc(h Controller, ms []Hook) httprouter.Ha } ctx.prepare(ctx) - + // Execute the first handler in the chain if len(reqCtx.chainNodes) > 0 { n := reqCtx.chainNodes[0] @@ -392,7 +392,7 @@ func UseHook(mw Hook) { // Next advances to the next middleware or controller in the chain and invokes it with the given context if available. func (app *App) Next(c *Context) { // Get request-specific chain state from context - if reqCtx, ok := c.Request.httpRequest.Context().Value("goffeeChain").(*requestContext); ok { + if reqCtx, ok := c.Request.HttpRequest.Context().Value("goffeeChain").(*requestContext); ok { reqCtx.chainIndex++ if reqCtx.chainIndex < len(reqCtx.chainNodes) { n := reqCtx.chainNodes[reqCtx.chainIndex] diff --git a/core_test.go b/core_test.go index fc146af..b76faaf 100644 --- a/core_test.go +++ b/core_test.go @@ -226,7 +226,7 @@ func makeCTX(t *testing.T) *Context { t.Helper() return &Context{ Request: &Request{ - httpRequest: httptest.NewRequest(GET, LOCALHOST, nil), + HttpRequest: httptest.NewRequest(GET, LOCALHOST, nil), httpPathParams: nil, }, Response: &Response{ diff --git a/request.go b/request.go index a93ac62..008b3e5 100644 --- a/request.go +++ b/request.go @@ -12,6 +12,6 @@ import ( ) type Request struct { - httpRequest *http.Request + HttpRequest *http.Request httpPathParams httprouter.Params } diff --git a/response.go b/response.go index d6202c7..6beb36e 100644 --- a/response.go +++ b/response.go @@ -9,10 +9,13 @@ import ( "bytes" "fmt" "net/http" + "strings" ) // Response represents an HTTP response to be sent to the client, including headers, body, status code, and metadata. type Response struct { + FlashMessage string + MsgType string headers []header body []byte statusCode int @@ -144,6 +147,23 @@ func (rs *Response) Redirect(url string) *Response { }, map[string]interface{}{ "url": "url", }) + + if rs.FlashMessage != "" || rs.MsgType != "" { + if !strings.Contains(url, "?") { + url += "?" + } else { + url += "&" + } + if rs.FlashMessage != "" { + url += "flash_message=" + rs.FlashMessage + } + if rs.MsgType != "" { + if rs.FlashMessage != "" { + url += "&" + } + url += "msg_type=" + rs.MsgType + } + } if v.Failed() { if url[0:1] != "/" { rs.redirectTo = "/" + url diff --git a/template/components/form_color_opacity.go b/template/components/form_color_opacity.go new file mode 100644 index 0000000..1998386 --- /dev/null +++ b/template/components/form_color_opacity.go @@ -0,0 +1,14 @@ +package components + +type FormColorOpacity struct { + ColorID string + OpacityID string + Label string + ColorHexValue string + OpacityValue string + Hint string + Error string + IsDisabled bool + IsRequired bool + HasOpacity bool +} diff --git a/template/components/form_color_opacity.html b/template/components/form_color_opacity.html new file mode 100644 index 0000000..b429d55 --- /dev/null +++ b/template/components/form_color_opacity.html @@ -0,0 +1,28 @@ +{{ define "form_color_opacity"}} +
+ +
+ + {{if eq .HasOpacity true}} + opacity: + {{if ne .Hint ""}}{{.Hint}}{{end}} + {{if ne .Error ""}}
{{.Error}}
{{end}} + {{end}} +
+ +{{end}} + \ No newline at end of file