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  }