request_out.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package rest_http
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "io"
  6. "mime/multipart"
  7. "net/http"
  8. "net/textproto"
  9. "git.ali33.ru/fcg-xvii/rest"
  10. )
  11. func NewRequestOut(req rest.IRequest) *RequestOut {
  12. return &RequestOut{
  13. IRequest: req,
  14. }
  15. }
  16. // Response реализует объект ответа
  17. type RequestOut struct {
  18. Err rest.IErrorArgs
  19. rest.IRequest
  20. }
  21. // Send отправляет запрос серверу
  22. func (s *RequestOut) Write(writer io.Writer) rest.IErrorArgs {
  23. w := writer.(http.ResponseWriter)
  24. //log.Println("SEND...")
  25. defer s.RClose()
  26. if s.Err != nil {
  27. w.Header().Set("Content-Type", "application/json")
  28. w.WriteHeader(500)
  29. w.Write([]byte(s.Err.Map().JSON()))
  30. return nil
  31. }
  32. // Если есть файлы, то используем multipart
  33. files := s.RFiles()
  34. if len(files) > 0 {
  35. var b bytes.Buffer
  36. writer := multipart.NewWriter(&b)
  37. w.Header().Set("Content-Type", writer.FormDataContentType())
  38. // Добавляем JSON-данные как часть
  39. partHeader := make(textproto.MIMEHeader)
  40. partHeader.Set("Content-Type", "application/json")
  41. partHeader.Set("Content-Disposition", `form-data; name="data"`)
  42. dataPart, err := writer.CreatePart(partHeader)
  43. if err != nil {
  44. return rest.ErrorMessage("ErrResponsePartDataCreate", err.Error())
  45. }
  46. if err := json.NewEncoder(dataPart).Encode(s.RData()); err != nil {
  47. return rest.ErrorMessage("ErrResponseDataJsonEncode", err.Error())
  48. }
  49. // Добавляем файлы
  50. for filename, file := range files {
  51. part, err := writer.CreateFormFile("file", filename)
  52. if err != nil {
  53. return rest.ErrorMessage("ErrResponsePartFileCreate", err.Error())
  54. }
  55. if _, err := io.Copy(part, file); err != nil {
  56. return rest.ErrorMessage("ErrResponsePartFileCopy", err.Error())
  57. }
  58. }
  59. // Закрываем multipart writer
  60. if err := writer.Close(); err != nil {
  61. return rest.ErrorMessage("ErrResponsePartFileClose", err.Error())
  62. }
  63. // Отправляем multipart response
  64. w.Header().Set("Content-Type", writer.FormDataContentType())
  65. w.Write(b.Bytes())
  66. } else {
  67. // Если нет файлов, просто отправляем JSON
  68. w.Header().Set("Content-Type", "application/json")
  69. if err := json.NewEncoder(w).Encode(s.RData()); err != nil {
  70. return rest.ErrorMessage("ErrResponseDataJsonEncode", err.Error())
  71. }
  72. }
  73. return nil
  74. }
  75. // Успрешный ответ
  76. func ResponseSuccess(req rest.IRequest) rest.IRequestOut {
  77. return &RequestOut{
  78. IRequest: req,
  79. }
  80. }
  81. func ResponseError(err rest.IErrorArgs) rest.IRequestOut {
  82. return &RequestOut{
  83. Err: err,
  84. }
  85. }