github.com/profzone/eden-framework@v1.0.10/pkg/courier/transport_http/encode.go (about) 1 package transport_http 2 3 import ( 4 "context" 5 "io" 6 "io/ioutil" 7 "net/http" 8 "reflect" 9 10 "github.com/profzone/eden-framework/pkg/courier" 11 "github.com/profzone/eden-framework/pkg/courier/httpx" 12 "github.com/profzone/eden-framework/pkg/courier/status_error" 13 "github.com/profzone/eden-framework/pkg/courier/transport_http/transform" 14 ) 15 16 func setContextType(w http.ResponseWriter, s string) { 17 w.Header().Set(httpx.HeaderContentType, s+";charset=utf-8") 18 } 19 20 func encodeHttpResponse(_ context.Context, w http.ResponseWriter, r *http.Request, response interface{}) error { 21 if redirect, ok := response.(httpx.IRedirect); ok { 22 http.Redirect(w, r, redirect.Redirect(r.Host), redirect.Status()) 23 return nil 24 } 25 26 if hasMeta, ok := response.(courier.IMeta); ok { 27 meta := hasMeta.Meta() 28 for k := range meta { 29 w.Header().Set(k, meta.Get(k)) 30 } 31 } 32 33 code := http.StatusOK 34 if r.Method == http.MethodPost { 35 code = http.StatusCreated 36 } 37 38 if sc, ok := response.(IStatus); ok { 39 code = sc.Status() 40 } 41 42 if response == nil { 43 code = http.StatusNoContent 44 } 45 46 if code == http.StatusNoContent { 47 w.WriteHeader(code) 48 return nil 49 } 50 51 tpe := reflect.TypeOf(response) 52 for tpe.Kind() == reflect.Ptr { 53 tpe = tpe.Elem() 54 } 55 56 contentType := "" 57 58 if withContentType, ok := response.(IContentType); ok { 59 contentType = withContentType.ContentType() 60 setContextType(w, contentType) 61 } 62 63 if reader, ok := response.(io.Reader); ok { 64 b, errForRead := ioutil.ReadAll(reader) 65 if errForRead != nil { 66 return errForRead 67 } 68 w.WriteHeader(code) 69 w.Write(b) 70 return nil 71 } 72 73 if contentType == "" { 74 contentType = httpx.MIME_JSON 75 setContextType(w, contentType) 76 } 77 78 dataList, err := transform.ContentMarshal(reflect.ValueOf(response), "body", contentType) 79 if err != nil { 80 return err 81 } 82 w.WriteHeader(code) 83 w.Write(dataList[0]) 84 return nil 85 } 86 87 func encodeHttpError(c context.Context, w http.ResponseWriter, r *http.Request, err error) (finalErr error) { 88 if redirect, ok := err.(httpx.IRedirect); ok { 89 http.Redirect(w, r, redirect.Redirect(r.Host), redirect.Status()) 90 return nil 91 } 92 93 finalStatusErr := status_error.FromError(err).WithSource(c.Value(ContextKeyServerName).(string)) 94 encodeHttpResponse(c, w, r, finalStatusErr) 95 return finalStatusErr 96 }