code: func parseBody(w http.ResponseWriter, r *http.Request, resp *bodyResponse) error {
  	if r.Body == nil {
  		return nil
  	}
  
  	// Always set resp.Data to the incoming request body, in case we don't know
  	// how to handle the content type
  	body, err := ioutil.ReadAll(r.Body)
  	if err != nil {
  		r.Body.Close()
  		return err
  	}
  	resp.Data = string(body)
  
  	// After reading the body to populate resp.Data, we need to re-wrap it in
  	// an io.Reader for further processing below
  	r.Body.Close()
  	r.Body = ioutil.NopCloser(bytes.NewBuffer(body))
  
  	ct := r.Header.Get("Content-Type")
  	switch {
  	case strings.HasPrefix(ct, "application/x-www-form-urlencoded"):
  		if err := r.ParseForm(); err != nil {
  			return err
  		}
  		resp.Form = r.PostForm
  	case strings.HasPrefix(ct, "multipart/form-data"):
  		// The memory limit here only restricts how many parts will be kept in
  		// memory before overflowing to disk:
  		// http://localhost:8080/pkg/net/http/#Request.ParseMultipartForm
  		if err := r.ParseMultipartForm(1024); err != nil {
  			return err
  		}
  		resp.Form = r.PostForm
  	case strings.HasPrefix(ct, "application/json"):
  		err := json.NewDecoder(r.Body).Decode(&resp.JSON)
  		if err != nil && err != io.EOF {
  			return err
  		}
  	}
  
  	return nil
  }
docs: // parseBody handles parsing a request body into our standard API response,
  // taking care to only consume the request body once based on the Content-Type
  // of the request. The given bodyResponse will be modified.
  //
  // Note: this function expects callers to limit the the maximum size of the
  // request body. See, e.g., the limitRequestSize middleware.