...

Source file src/github.com/go-kivik/kivik/v4/x/server/bind.go

Documentation: github.com/go-kivik/kivik/v4/x/server

     1  // Licensed under the Apache License, Version 2.0 (the "License"); you may not
     2  // use this file except in compliance with the License. You may obtain a copy of
     3  // the License at
     4  //
     5  //  http://www.apache.org/licenses/LICENSE-2.0
     6  //
     7  // Unless required by applicable law or agreed to in writing, software
     8  // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     9  // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    10  // License for the specific language governing permissions and limitations under
    11  // the License.
    12  
    13  //go:build !js
    14  
    15  package server
    16  
    17  import (
    18  	"encoding/json"
    19  	"mime"
    20  	"net/http"
    21  
    22  	internal "github.com/go-kivik/kivik/v4/int/errors"
    23  )
    24  
    25  // bind binds the request to v if it is of type application/json or
    26  // application/x-www-form-urlencoded.
    27  func (s *Server) bind(r *http.Request, v interface{}) error {
    28  	defer r.Body.Close()
    29  	switch r.Method {
    30  	case http.MethodPatch, http.MethodPost, http.MethodPut:
    31  		// continue
    32  	default:
    33  		// simple query parsing
    34  		return s.bindForm(r, v)
    35  	}
    36  	ct, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
    37  	switch ct {
    38  	case "application/json":
    39  		if err := json.NewDecoder(r.Body).Decode(v); err != nil {
    40  			return &internal.Error{Status: http.StatusBadRequest, Err: err}
    41  		}
    42  		return nil
    43  	case "application/x-www-form-urlencoded":
    44  		return s.bindForm(r, v)
    45  	default:
    46  		return &couchError{status: http.StatusUnsupportedMediaType, Err: "bad_content_type", Reason: "Content-Type must be 'application/x-www-form-urlencoded' or 'application/json'"}
    47  	}
    48  }
    49  
    50  func (s *Server) bindForm(r *http.Request, v interface{}) error {
    51  	defer r.Body.Close()
    52  	if err := r.ParseForm(); err != nil {
    53  		return &internal.Error{Status: http.StatusBadRequest, Err: err}
    54  	}
    55  	if err := s.formDecoder.Decode(r.Form, v); err != nil {
    56  		return &internal.Error{Status: http.StatusBadRequest, Err: err}
    57  	}
    58  	return nil
    59  }
    60  
    61  // bindJSON works like bind, but for endpoints that require application/json.
    62  func (s *Server) bindJSON(r *http.Request, v interface{}) error {
    63  	defer r.Body.Close()
    64  	ct, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
    65  	switch ct {
    66  	case "application/json":
    67  		return json.NewDecoder(r.Body).Decode(v)
    68  	default:
    69  		return &couchError{status: http.StatusUnsupportedMediaType, Err: "bad_content_type", Reason: "Content-Type must be 'application/json'"}
    70  	}
    71  }
    72  

View as plain text