15357fd3c0
yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarbacreate and moove into new directories for BegushiyBashkir and yalarba
76 lines
2.2 KiB
Go
76 lines
2.2 KiB
Go
package utils
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
func RespondWithJSON(w http.ResponseWriter, statusCode int, data interface{}) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(statusCode)
|
|
json.NewEncoder(w).Encode(data)
|
|
}
|
|
|
|
func RespondWithError(w http.ResponseWriter, statusCode int, message string) {
|
|
RespondWithJSON(w, statusCode, map[string]string{"error": message})
|
|
}
|
|
|
|
// DecodeJSONBody декодирует JSON тело запроса
|
|
func DecodeJSONBody(w http.ResponseWriter, r *http.Request, dst interface{}) error {
|
|
if r.Header.Get("Content-Type") != "application/json" {
|
|
return errors.New("Content-Type header is not application/json")
|
|
}
|
|
|
|
r.Body = http.MaxBytesReader(w, r.Body, 1048576) // 1MB limit
|
|
|
|
dec := json.NewDecoder(r.Body)
|
|
dec.DisallowUnknownFields()
|
|
|
|
err := dec.Decode(dst)
|
|
if err != nil {
|
|
var syntaxError *json.SyntaxError
|
|
var unmarshalTypeError *json.UnmarshalTypeError
|
|
|
|
switch {
|
|
case errors.As(err, &syntaxError):
|
|
return fmt.Errorf("request body contains badly-formed JSON (at position %d)", syntaxError.Offset)
|
|
|
|
case errors.Is(err, io.ErrUnexpectedEOF):
|
|
return errors.New("request body contains badly-formed JSON")
|
|
|
|
case errors.As(err, &unmarshalTypeError):
|
|
return fmt.Errorf("request body contains an invalid value for the %q field (at position %d)", unmarshalTypeError.Field, unmarshalTypeError.Offset)
|
|
|
|
case strings.HasPrefix(err.Error(), "json: unknown field "):
|
|
fieldName := strings.TrimPrefix(err.Error(), "json: unknown field ")
|
|
return fmt.Errorf("request body contains unknown field %s", fieldName)
|
|
|
|
case errors.Is(err, io.EOF):
|
|
return errors.New("request body must not be empty")
|
|
|
|
case err.Error() == "http: request body too large":
|
|
return errors.New("request body must not be larger than 1MB")
|
|
|
|
default:
|
|
return err
|
|
}
|
|
}
|
|
|
|
err = dec.Decode(&struct{}{})
|
|
if err != io.EOF {
|
|
return errors.New("request body must only contain a single JSON object")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetUserIDFromContext извлекает userID из контекста
|
|
func GetUserIDFromContext(r *http.Request) (uint, bool) {
|
|
userID, ok := r.Context().Value("userID").(uint)
|
|
return userID, ok
|
|
}
|