...

Source file src/github.com/99designs/gqlgen/graphql/handler/transport/http_form_urlencoded.go

Documentation: github.com/99designs/gqlgen/graphql/handler/transport

     1  package transport
     2  
     3  import (
     4  	"io"
     5  	"mime"
     6  	"net/http"
     7  	"net/url"
     8  	"strings"
     9  
    10  	"github.com/vektah/gqlparser/v2/gqlerror"
    11  
    12  	"github.com/99designs/gqlgen/graphql"
    13  )
    14  
    15  // FORM implements the application/x-www-form-urlencoded side of the default HTTP transport
    16  type UrlEncodedForm struct {
    17  	// Map of all headers that are added to graphql response. If not
    18  	// set, only one header: Content-Type: application/json will be set.
    19  	ResponseHeaders map[string][]string
    20  }
    21  
    22  var _ graphql.Transport = UrlEncodedForm{}
    23  
    24  func (h UrlEncodedForm) Supports(r *http.Request) bool {
    25  	if r.Header.Get("Upgrade") != "" {
    26  		return false
    27  	}
    28  
    29  	mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
    30  	if err != nil {
    31  		return false
    32  	}
    33  
    34  	return r.Method == "POST" && mediaType == "application/x-www-form-urlencoded"
    35  }
    36  
    37  func (h UrlEncodedForm) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
    38  	ctx := r.Context()
    39  	writeHeaders(w, h.ResponseHeaders)
    40  	params := &graphql.RawParams{}
    41  	start := graphql.Now()
    42  	params.Headers = r.Header
    43  	params.ReadTime = graphql.TraceTiming{
    44  		Start: start,
    45  		End:   graphql.Now(),
    46  	}
    47  
    48  	bodyString, err := getRequestBody(r)
    49  	if err != nil {
    50  		w.WriteHeader(http.StatusBadRequest)
    51  		gqlErr := gqlerror.Errorf("could not get form body: %+v", err)
    52  		resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
    53  		writeJson(w, resp)
    54  		return
    55  	}
    56  
    57  	params, err = h.parseBody(bodyString)
    58  	if err != nil {
    59  		w.WriteHeader(http.StatusUnprocessableEntity)
    60  		gqlErr := gqlerror.Errorf("could not cleanup body: %+v", err)
    61  		resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
    62  		writeJson(w, resp)
    63  		return
    64  	}
    65  
    66  	rc, OpErr := exec.CreateOperationContext(ctx, params)
    67  	if OpErr != nil {
    68  		w.WriteHeader(statusFor(OpErr))
    69  		resp := exec.DispatchError(graphql.WithOperationContext(ctx, rc), OpErr)
    70  		writeJson(w, resp)
    71  		return
    72  	}
    73  
    74  	var responses graphql.ResponseHandler
    75  	responses, ctx = exec.DispatchOperation(ctx, rc)
    76  	writeJson(w, responses(ctx))
    77  }
    78  
    79  func (h UrlEncodedForm) parseBody(bodyString string) (*graphql.RawParams, error) {
    80  	switch {
    81  	case strings.Contains(bodyString, "\"query\":"):
    82  		// body is json
    83  		return h.parseJson(bodyString)
    84  	case strings.HasPrefix(bodyString, "query=%7B"):
    85  		// body is urlencoded
    86  		return h.parseEncoded(bodyString)
    87  	default:
    88  		// body is plain text
    89  		params := &graphql.RawParams{}
    90  		params.Query = strings.TrimPrefix(bodyString, "query=")
    91  
    92  		return params, nil
    93  	}
    94  }
    95  
    96  func (h UrlEncodedForm) parseEncoded(bodyString string) (*graphql.RawParams, error) {
    97  	params := &graphql.RawParams{}
    98  
    99  	query, err := url.QueryUnescape(bodyString)
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  
   104  	params.Query = strings.TrimPrefix(query, "query=")
   105  
   106  	return params, nil
   107  }
   108  
   109  func (h UrlEncodedForm) parseJson(bodyString string) (*graphql.RawParams, error) {
   110  	params := &graphql.RawParams{}
   111  	bodyReader := io.NopCloser(strings.NewReader(bodyString))
   112  
   113  	err := jsonDecode(bodyReader, &params)
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  
   118  	return params, nil
   119  }
   120  

View as plain text