github.com/gramework/gramework@v1.8.1-0.20231027140105-82555c9057f5/context_writers.go (about) 1 package gramework 2 3 import ( 4 "fmt" 5 "strings" 6 7 acceptParser "github.com/kirillDanshin/go-accept-headers" 8 "github.com/valyala/fasthttp" 9 ) 10 11 func (ctx *Context) Write(p []byte) (int, error) { 12 return ctx.writer(p) 13 } 14 15 // Encode automatically determines accepted formats 16 // and choose preferred one 17 func (ctx *Context) Encode(v interface{}) (string, error) { 18 accept := ctx.Request.Header.Peek(acceptHeader) 19 accepted := acceptParser.Parse(BytesToString(accept)) 20 21 sentType, err := accepted.Negotiate(ctypes...) 22 if err != nil { 23 return emptyString, err 24 } 25 26 switch sentType { 27 case jsonCT: 28 err = ctx.JSON(v) 29 case xmlCT: 30 err = ctx.XML(v) 31 case csvCT: 32 err = ctx.CSV(v) 33 } 34 35 return sentType, err 36 } 37 38 // Writef is a fmt.Fprintf(context, format, a...) shortcut 39 func (ctx *Context) Writef(format string, a ...interface{}) (int, error) { 40 return fmt.Fprintf(ctx, format, a...) 41 } 42 43 // CSV sends text/csv content type (see rfc4180, sec 3) and csv-encoded value to client 44 func (ctx *Context) CSV(v interface{}) error { 45 ctx.SetContentType(csvCT) 46 47 b, err := ctx.ToCSV(v) 48 if err != nil { 49 return err 50 } 51 _, err = ctx.Write(b) 52 return err 53 } 54 55 // Writeln is a fmt.Fprintln(context, format, a...) shortcut 56 func (ctx *Context) Writeln(a ...interface{}) (int, error) { 57 return fmt.Fprintln(ctx, a...) 58 } 59 60 // XML sends text/xml content type (see rfc3023, sec 3) and xml-encoded value to client 61 func (ctx *Context) XML(v interface{}) error { 62 ctx.SetContentType(xmlCT) 63 b, err := ctx.ToXML(v) 64 if err != nil { 65 return err 66 } 67 68 _, err = ctx.Write(b) 69 return err 70 } 71 72 // HTML sets HTML content type 73 func (ctx *Context) HTML(src ...string) *Context { 74 ctx.SetContentType(htmlCT) 75 if len(src) > 0 { 76 _, e := ctx.WriteString(src[0]) 77 _ = e 78 } 79 return ctx 80 } 81 82 // CORS enables CORS in the current context 83 func (ctx *Context) CORS(domains ...string) *Context { 84 var origins []string 85 if len(domains) > 0 { 86 origins = domains 87 } else if headerOrigin := ctx.Request.Header.Peek(hOrigin); len(headerOrigin) > 0 { 88 origins = append(origins, string(headerOrigin)) 89 } else { 90 origins = append(origins, string(ctx.Request.URI().Host())) 91 } 92 93 ctx.Response.Header.Set(corsAccessControlAllowOrigin, strings.Join(origins, " ")) 94 ctx.Response.Header.Set(corsAccessControlAllowMethods, methods) 95 ctx.Response.Header.Set(corsAccessControlAllowHeaders, corsCType) 96 ctx.Response.Header.Set(corsAccessControlAllowCredentials, trueStr) 97 98 return ctx 99 } 100 101 // JSON serializes and writes a json-formatted response to user 102 func (ctx *Context) JSON(v interface{}) error { 103 ctx.SetContentType(jsonCT) 104 b, err := ctx.ToJSON(v) 105 if err != nil { 106 return err 107 } 108 109 _, err = ctx.Write(b) 110 return err 111 } 112 113 // BadRequest sends HTTP/1.1 400 Bad Request 114 func (ctx *Context) BadRequest(err ...error) { 115 e := badRequest 116 if len(err) > 0 { 117 e = err[0].Error() 118 } 119 120 ctx.Error(e, fasthttp.StatusBadRequest) 121 } 122 123 // Err500 sets Internal Server Error status 124 func (ctx *Context) Err500(message ...interface{}) *Context { 125 ctx.SetStatusCode(fasthttp.StatusInternalServerError) 126 for k := range message { 127 switch v := message[k].(type) { 128 case string: 129 _, err := ctx.WriteString(v) 130 if err != nil { 131 ctx.Logger.WithError(err).Error("Err500 serving error") 132 } 133 case error: 134 _, e := ctx.Writef(fmtS, v) 135 _ = e // it's already 500 136 default: 137 _, e := ctx.Writef(fmtV, v) 138 _ = e 139 } 140 } 141 return ctx 142 } 143 144 // JSONError sets Internal Server Error status, 145 // serializes and writes a json-formatted response to user 146 func (ctx *Context) JSONError(v interface{}) error { 147 ctx.Err500() 148 return ctx.JSON(v) 149 }