rest.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package rest
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "net/http"
  8. )
  9. func getDetailedError(data []byte, err error) error {
  10. var limit int64 = 20
  11. syntaxError, ok := err.(*json.SyntaxError)
  12. if ok {
  13. start := syntaxError.Offset - 1
  14. if start < 0 {
  15. start = 0
  16. }
  17. end := start + limit
  18. dataLength := int64(len(data))
  19. if end > dataLength {
  20. end = dataLength
  21. }
  22. badPart := string(data[start:end])
  23. return fmt.Errorf("%s:\n%s", err.Error(), badPart)
  24. }
  25. typeError, ok := err.(*json.UnmarshalTypeError)
  26. if ok {
  27. start := typeError.Offset - limit
  28. if start < 0 {
  29. start = 0
  30. }
  31. badPart := string(data[start:typeError.Offset])
  32. return fmt.Errorf("%s:\n%s", err.Error(), badPart)
  33. }
  34. return err
  35. }
  36. //JSONDecoder decodes json from given bytes array to target object.
  37. func JSONDecoder(data []byte, target interface{}) error {
  38. err := json.Unmarshal(data, target)
  39. if err != nil {
  40. err = getDetailedError(data, err)
  41. }
  42. return err
  43. }
  44. //GET returns bytes buffer of response body.
  45. func GET(url string) (*bytes.Buffer, error) {
  46. resp, err := http.Get(url)
  47. if resp != nil {
  48. defer resp.Body.Close()
  49. }
  50. if err != nil {
  51. return nil, fmt.Errorf("Response error: %v", err)
  52. }
  53. body, err := BodyToBuffer(resp.Body)
  54. if err != nil {
  55. return nil, fmt.Errorf("Error reading body: %v", err)
  56. }
  57. if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent {
  58. return body, fmt.Errorf("Request unsuccessful: %v - %v", resp.Status, url)
  59. }
  60. return body, nil
  61. }
  62. //HEAD returns map[string][]string of response header.
  63. func HEAD(url string) (map[string][]string, error) {
  64. resp, err := http.Head(url)
  65. if err != nil {
  66. return nil, fmt.Errorf("Response error: %v", err)
  67. }
  68. if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent {
  69. return resp.Header, fmt.Errorf("Request unsuccessful: %v - %v", resp.Status, url)
  70. }
  71. return resp.Header, nil
  72. }
  73. //BodyToBuffer reads data from ReadCloser and returns bytes buffer.
  74. func BodyToBuffer(data io.ReadCloser) (*bytes.Buffer, error) {
  75. var buffer bytes.Buffer
  76. _, err := buffer.ReadFrom(data)
  77. if err != nil {
  78. return nil, err
  79. }
  80. return &buffer, nil
  81. }