123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- package rest
- import (
- "bytes"
- "encoding/json"
- "io"
- "log"
- "mime/multipart"
- "net/http"
- "net/textproto"
- mjson "git.ali33.ru/fcg-xvii/go-tools/json"
- )
- func NewResponse() *Response {
- return &Response{
- data: make(mjson.Map),
- files: make(map[string]io.ReadCloser),
- }
- }
- type Response struct {
- data mjson.Map
- files map[string]io.ReadCloser
- err error
- errArgs mjson.Map
- code int
- }
- func (s *Response) KeySet(key string, val any) {
- s.data[key] = val
- }
- func (s *Response) FileSet(name string, file io.ReadCloser) {
- s.files[name] = file
- }
- func (s *Response) SetError(code int, err error) {
- s.code = code
- s.err = err
- }
- func (s *Response) Close() {
- for _, file := range s.files {
- file.Close()
- }
- }
- func (s *Response) Send(w http.ResponseWriter) error {
- log.Println("SEND...")
- defer s.Close()
- if s.err != nil {
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(s.code)
- body := mjson.Map{
- "error": s.err.Error(),
- "args": s.errArgs,
- }
- w.Write(body.JSON())
- return nil
- }
- // Если есть файлы, то используем multipart
- if len(s.files) > 0 {
- var b bytes.Buffer
- writer := multipart.NewWriter(&b)
- // Добавляем JSON-данные как часть
- partHeader := make(textproto.MIMEHeader)
- partHeader.Set("Content-Type", "application/json")
- partHeader.Set("Content-Disposition", `form-data; name="data"`)
- dataPart, err := writer.CreatePart(partHeader)
- if err != nil {
- return err
- }
- if err := json.NewEncoder(dataPart).Encode(s.data); err != nil {
- return err
- }
- // Добавляем файлы
- for filename, file := range s.files {
- part, err := writer.CreateFormFile("file", filename)
- if err != nil {
- return err
- }
- if _, err := io.Copy(part, file); err != nil {
- return err
- }
- }
- // Закрываем multipart writer
- if err := writer.Close(); err != nil {
- return err
- }
- // Отправляем multipart response
- w.Header().Set("Content-Type", writer.FormDataContentType())
- w.Write(b.Bytes())
- } else {
- // Если нет файлов, просто отправляем JSON
- w.Header().Set("Content-Type", "application/json")
- return json.NewEncoder(w).Encode(s.data)
- }
- return nil
- }
- ///////////////////////////////////////////
- func ResponseError(err error, args mjson.Map, code int) *Response {
- return &Response{
- code: code,
- err: err,
- errArgs: args,
- }
- }
- ///////////////////////////////////////////
- func ResponseErrKeyNotExists(key string) *Response {
- return ResponseError(
- ErrKeyNotExists,
- mjson.Map{
- "key": key,
- },
- 500,
- )
- }
- func ResponseErrKeyInvalidType(key, kType string) *Response {
- return ResponseError(
- ErrKeyInvalidType,
- mjson.Map{
- "key": key,
- "type": kType,
- },
- 500,
- )
- }
- func ResponseNotFound(data mjson.Map) *Response {
- return &Response{
- code: 404,
- err: ErrNotFound,
- errArgs: data,
- }
- }
|