package rest_http import ( "bytes" "encoding/json" "fmt" "io" "mime/multipart" "net/http" "net/textproto" "git.ali33.ru/fcg-xvii/rest" ) func NewRequestOut(req rest.IRequest) *RequestOut { return &RequestOut{ IRequest: req, } } // Response реализует объект ответа type RequestOut struct { Err rest.IErrorArgs rest.IRequest } func (s *RequestOut) RClose() { if s.IRequest != nil { s.IRequest.RClose() } } // Send отправляет запрос серверу func (s *RequestOut) Write(writer io.Writer) rest.IErrorArgs { w := writer.(http.ResponseWriter) //log.Println("SEND...") defer s.RClose() if s.Err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(500) w.Write([]byte(s.Err.Map().JSON())) return nil } // Если есть файлы, то используем multipart files := s.RFiles() if len(files) > 0 { var b bytes.Buffer writer := multipart.NewWriter(&b) w.Header().Set("Content-Type", writer.FormDataContentType()) // Добавляем 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 rest.ErrorMessage("ErrResponsePartDataCreate", err.Error()) } if err := json.NewEncoder(dataPart).Encode(s.RData()); err != nil { return rest.ErrorMessage("ErrResponseDataJsonEncode", err.Error()) } // Добавляем файлы for filename, file := range files { var part io.Writer if mimeFile, check := file.(*rest.MimeFile); check { h := make(textproto.MIMEHeader) h.Set("Content-Type", mimeFile.MimeType) h.Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, mimeFile.Name)) if part, err = writer.CreatePart(h); err != nil { return rest.ErrorMessage("ErrResponsePartFileCreate", err.Error()) } } else { if part, err = writer.CreateFormFile("file", filename); err != nil { return rest.ErrorMessage("ErrResponsePartFileCreate", err.Error()) } } if _, err := io.Copy(part, file); err != nil { return rest.ErrorMessage("ErrResponsePartFileCopy", err.Error()) } } // Закрываем multipart writer if err := writer.Close(); err != nil { return rest.ErrorMessage("ErrResponsePartFileClose", err.Error()) } // Отправляем multipart response w.Header().Set("Content-Type", writer.FormDataContentType()) w.Write(b.Bytes()) } else { // Если нет файлов, просто отправляем JSON w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(s.RData()); err != nil { return rest.ErrorMessage("ErrResponseDataJsonEncode", err.Error()) } } return nil } // Успрешный ответ func ResponseSuccess(req rest.IRequest) rest.IRequestOut { return &RequestOut{ IRequest: req, } } func ResponseError(err rest.IErrorArgs) rest.IRequestOut { return &RequestOut{ Err: err, } }