diff --git a/ginext/response.go b/ginext/response.go index c80a322..52f0fc8 100644 --- a/ginext/response.go +++ b/ginext/response.go @@ -9,6 +9,16 @@ import ( "os" ) +type cookieval struct { + name string + value string + maxAge int + path string + domain string + secure bool + httpOnly bool +} + type headerval struct { Key string Val string @@ -17,6 +27,7 @@ type headerval struct { type HTTPResponse interface { Write(g *gin.Context) WithHeader(k string, v string) HTTPResponse + WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse IsSuccess() bool } @@ -33,6 +44,7 @@ type jsonHTTPResponse struct { statusCode int data any headers []headerval + cookies []cookieval } func (j jsonHTTPResponse) jsonRenderer(g *gin.Context) json.GoJsonRender { @@ -47,6 +59,9 @@ func (j jsonHTTPResponse) Write(g *gin.Context) { for _, v := range j.headers { g.Header(v.Key, v.Val) } + for _, v := range j.cookies { + g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly) + } g.Render(j.statusCode, j.jsonRenderer(g)) } @@ -55,6 +70,11 @@ func (j jsonHTTPResponse) WithHeader(k string, v string) HTTPResponse { return j } +func (j jsonHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse { + j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly}) + return j +} + func (j jsonHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } @@ -82,12 +102,16 @@ func (j jsonHTTPResponse) Headers() []string { type emptyHTTPResponse struct { statusCode int headers []headerval + cookies []cookieval } func (j emptyHTTPResponse) Write(g *gin.Context) { for _, v := range j.headers { g.Header(v.Key, v.Val) } + for _, v := range j.cookies { + g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly) + } g.Status(j.statusCode) } @@ -96,6 +120,11 @@ func (j emptyHTTPResponse) WithHeader(k string, v string) HTTPResponse { return j } +func (j emptyHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse { + j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly}) + return j +} + func (j emptyHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } @@ -120,12 +149,16 @@ type textHTTPResponse struct { statusCode int data string headers []headerval + cookies []cookieval } func (j textHTTPResponse) Write(g *gin.Context) { for _, v := range j.headers { g.Header(v.Key, v.Val) } + for _, v := range j.cookies { + g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly) + } g.String(j.statusCode, "%s", j.data) } @@ -134,6 +167,11 @@ func (j textHTTPResponse) WithHeader(k string, v string) HTTPResponse { return j } +func (j textHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse { + j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly}) + return j +} + func (j textHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } @@ -159,12 +197,16 @@ type dataHTTPResponse struct { data []byte contentType string headers []headerval + cookies []cookieval } func (j dataHTTPResponse) Write(g *gin.Context) { for _, v := range j.headers { g.Header(v.Key, v.Val) } + for _, v := range j.cookies { + g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly) + } g.Data(j.statusCode, j.contentType, j.data) } @@ -173,6 +215,11 @@ func (j dataHTTPResponse) WithHeader(k string, v string) HTTPResponse { return j } +func (j dataHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse { + j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly}) + return j +} + func (j dataHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } @@ -198,6 +245,7 @@ type fileHTTPResponse struct { filepath string filename *string headers []headerval + cookies []cookieval } func (j fileHTTPResponse) Write(g *gin.Context) { @@ -209,6 +257,9 @@ func (j fileHTTPResponse) Write(g *gin.Context) { for _, v := range j.headers { g.Header(v.Key, v.Val) } + for _, v := range j.cookies { + g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly) + } g.File(j.filepath) } @@ -217,6 +268,11 @@ func (j fileHTTPResponse) WithHeader(k string, v string) HTTPResponse { return j } +func (j fileHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse { + j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly}) + return j +} + func (j fileHTTPResponse) IsSuccess() bool { return true } @@ -247,17 +303,20 @@ type downloadDataHTTPResponse struct { data []byte filename *string headers []headerval + cookies []cookieval } func (j downloadDataHTTPResponse) Write(g *gin.Context) { g.Header("Content-Type", j.mimetype) // if we don't set it here gin does weird file-sniffing later... if j.filename != nil { g.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", *j.filename)) - } for _, v := range j.headers { g.Header(v.Key, v.Val) } + for _, v := range j.cookies { + g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly) + } g.Data(j.statusCode, j.mimetype, j.data) } @@ -266,6 +325,11 @@ func (j downloadDataHTTPResponse) WithHeader(k string, v string) HTTPResponse { return j } +func (j downloadDataHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse { + j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly}) + return j +} + func (j downloadDataHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } @@ -290,9 +354,16 @@ type redirectHTTPResponse struct { statusCode int url string headers []headerval + cookies []cookieval } func (j redirectHTTPResponse) Write(g *gin.Context) { + for _, v := range j.headers { + g.Header(v.Key, v.Val) + } + for _, v := range j.cookies { + g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly) + } g.Redirect(j.statusCode, j.url) } @@ -301,6 +372,11 @@ func (j redirectHTTPResponse) WithHeader(k string, v string) HTTPResponse { return j } +func (j redirectHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse { + j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly}) + return j +} + func (j redirectHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } @@ -324,9 +400,16 @@ func (j redirectHTTPResponse) Headers() []string { type jsonAPIErrResponse struct { err *exerr.ExErr headers []headerval + cookies []cookieval } func (j jsonAPIErrResponse) Write(g *gin.Context) { + for _, v := range j.headers { + g.Header(v.Key, v.Val) + } + for _, v := range j.cookies { + g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly) + } j.err.Output(g) j.err.CallListener(exerr.MethodOutput) @@ -337,6 +420,11 @@ func (j jsonAPIErrResponse) WithHeader(k string, v string) HTTPResponse { return j } +func (j jsonAPIErrResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse { + j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly}) + return j +} + func (j jsonAPIErrResponse) IsSuccess() bool { return false } diff --git a/goextVersion.go b/goextVersion.go index 6454259..bfcc20b 100644 --- a/goextVersion.go +++ b/goextVersion.go @@ -1,5 +1,5 @@ package goext -const GoextVersion = "0.0.365" +const GoextVersion = "0.0.366" -const GoextVersionTimestamp = "2024-01-09T18:23:46+0100" +const GoextVersionTimestamp = "2024-01-12T15:10:48+0100"