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  }