func (e roomsEndpoint) handlePutState(rw http.ResponseWriter, req *http.Request, params httprouter.Params) { room, user, err := e.getRoomAndUser(req, params) if err != nil { WriteJsonResponseWithStatus(rw, err) return } eventType := params[1].Value stateKey := "" if len(params) > 2 { stateKey = params[2].Value } var content ct.TypedContent switch eventType { case types.EventTypeMembership: content = &types.MembershipEventContent{} case types.EventTypeName: content = &types.NameEventContent{} case types.EventTypeTopic: content = &types.TopicEventContent{} case types.EventTypePowerLevels: content = &types.PowerLevelsEventContent{} case types.EventTypeJoinRules: content = &types.JoinRulesEventContent{} } var jsonErr error if content != nil { jsonErr = json.NewDecoder(req.Body).Decode(content) } else { genericContent := types.NewGenericContent(map[string]interface{}{}, eventType) content = genericContent jsonErr = json.NewDecoder(req.Body).Decode(&genericContent.Content) } if jsonErr != nil { switch err := jsonErr.(type) { case *json.SyntaxError: msg := fmt.Sprintf("error at [%d]: %s", err.Offset, err.Error()) WriteJsonResponseWithStatus(rw, types.NotJsonError(msg)) case *json.UnmarshalTypeError: msg := fmt.Sprintf("error at [%d]: expected type %s but got %s", err.Offset, err.Type, err.Value) WriteJsonResponseWithStatus(rw, types.BadJsonError(msg)) default: WriteJsonResponseWithStatus(rw, types.BadJsonError(err.Error())) } return } state, err := e.roomService.SetState(room, user, content, stateKey) if err != nil { WriteJsonResponseWithStatus(rw, err) return } res := eventIdResponse{state.EventId} WriteJsonResponse(rw, 200, res) }
func jsonHandler(i interface{}) httprouter.Handle { t := reflect.TypeOf(i) if reflect.Func != t.Kind() { panic("jsonHandler: must be a function") } if t.NumOut() != 1 { panic("jsonHandler: must return a single value") } argCount := t.NumIn() var jsonType reflect.Type firstParamIsParams := false if argCount > 0 { firstParamIsParams = t.In(0).String() == "httprouter.Params" lastParamIsParams := t.In(argCount-1).String() == "httprouter.Params" lastParamIsRequest := t.In(argCount-1).String() == "*http.Request" if !lastParamIsParams && !lastParamIsRequest { typ := t.In(argCount - 1) if typ.Kind() != reflect.Ptr { panic("jsonHandler: body argument must be a pointer type, was " + typ.String()) } jsonType = typ.Elem() } } if jsonType == nil { if t.NumIn() > 2 { panic("jsonHandler: arity must be at most 2 if no body argument is preset") } } else { if t.NumIn() > 3 { panic("jsonHandler: arity must be at most 3 if body argument is preset") } } handlerFunc := reflect.ValueOf(i) return func(rw http.ResponseWriter, req *http.Request, params httprouter.Params) { var returnValue reflect.Value var args []reflect.Value if jsonType == nil { switch argCount { case 0: args = []reflect.Value{} case 1: if firstParamIsParams { args = []reflect.Value{reflect.ValueOf(params)} } else { args = []reflect.Value{reflect.ValueOf(req)} } case 2: if firstParamIsParams { args = []reflect.Value{reflect.ValueOf(params), reflect.ValueOf(req)} } else { args = []reflect.Value{reflect.ValueOf(req), reflect.ValueOf(params)} } } } else { body := reflect.New(jsonType) if err := json.NewDecoder(req.Body).Decode(body.Interface()); err != nil { switch err := err.(type) { case *json.SyntaxError: msg := fmt.Sprintf("error at [%d]: %s", err.Offset, err.Error()) WriteJsonResponseWithStatus(rw, types.NotJsonError(msg)) case *json.UnmarshalTypeError: msg := fmt.Sprintf("error at [%d]: expected type %s but got %s", err.Offset, err.Type, err.Value) WriteJsonResponseWithStatus(rw, types.BadJsonError(msg)) default: WriteJsonResponseWithStatus(rw, types.BadJsonError(err.Error())) } return } switch argCount { case 1: args = []reflect.Value{body} case 2: if firstParamIsParams { args = []reflect.Value{reflect.ValueOf(params), body} } else { args = []reflect.Value{reflect.ValueOf(req), body} } case 3: if firstParamIsParams { args = []reflect.Value{reflect.ValueOf(params), reflect.ValueOf(req), body} } else { args = []reflect.Value{reflect.ValueOf(req), reflect.ValueOf(params), body} } } } returnValue = handlerFunc.Call(args)[0] res := returnValue.Interface() withStatus, ok := res.(WithStatus) if ok { WriteJsonResponseWithStatus(rw, withStatus) } else { WriteJsonResponse(rw, 200, res) } } }