func (self *JsonMessageBodyReader) Read(t reflect.Type, req *http.Request, mediaType *MediaType) (interface{}, error) { body := req.Body defer body.Close() decoder := json.NewDecoder(req.Body) valueT := t pointerDepth := 0 for valueT.Kind() == reflect.Ptr { valueT = valueT.Elem() pointerDepth++ } msg := reflect.New(valueT) err := decoder.Decode(msg.Interface()) if err != nil { // && err != io.EOF { return nil, err } //log.Debug("PointerDepth: %v, type %v", pointerDepth, t) // reflect.New returns a pointer, so we start at 1 for i := 1; i < pointerDepth; i++ { assert.That(msg.CanAddr()) msg = msg.Addr() } assert.Equal(msg.Type(), t) return msg.Interface(), nil }
func (self *RestEndpointHandler) buildArg(req *http.Request, t reflect.Type) (interface{}, error) { v, err := self.server.injector.Get(t) if err == nil && v != nil { return v, nil } // TODO: Fail if two args... // TODO: Only if has content? mediaType, err := getMediaType(req) if err != nil { return nil, err } if mediaType == nil { // Go does have a function to guess the media type, but that seems risky // Instead, use a fixed default mediaType = self.server.defaultMediaType } v, err = self.server.readMessageBody(t, req, mediaType) if err != nil { if err == io.EOF { log.Debug("Error reading message body (EOF)") } else { log.Debug("Error reading message body", err) } err = HttpError(http.StatusBadRequest) return nil, err } if v == nil && err == nil { err = HttpError(http.StatusUnsupportedMediaType) return nil, err } if v != nil { assert.Equal(reflect.TypeOf(v), t) return v, nil } log.Warn("Unable to bind parameter: %v", t) return nil, fmt.Errorf("Unable to bind parameter: %v", t) }