rest.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. switch detailed := err.(type) {
  12. case *json.SyntaxError:
  13. start := detailed.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. case *json.UnmarshalTypeError:
  25. start := detailed.Offset - limit
  26. if start < 0 {
  27. start = 0
  28. }
  29. badPart := string(data[start:detailed.Offset])
  30. return fmt.Errorf("%s:\n%s", err.Error(), badPart)
  31. }
  32. return err
  33. }
  34. //JSONDecoder decodes json from given bytes array to target object.
  35. func JSONDecoder(data []byte, target interface{}) error {
  36. err := json.Unmarshal(data, target)
  37. if err != nil {
  38. err = getDetailedError(data, err)
  39. }
  40. return err
  41. }
  42. //GET returns bytes buffer of response body.
  43. func GET(url string) (*bytes.Buffer, error) {
  44. resp, err := http.Get(url)
  45. if resp != nil {
  46. defer resp.Body.Close()
  47. }
  48. if err != nil {
  49. return nil, fmt.Errorf("Response error: %v", err)
  50. }
  51. body, err := BodyToBuffer(resp.Body)
  52. if err != nil {
  53. return nil, fmt.Errorf("Error reading body: %v", err)
  54. }
  55. if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent {
  56. return body, fmt.Errorf("Request unsuccessful: %v - %v", resp.Status, url)
  57. }
  58. return body, nil
  59. }
  60. //HEAD returns map[string][]string of response header.
  61. func HEAD(url string) (map[string][]string, error) {
  62. resp, err := http.Head(url)
  63. if err != nil {
  64. return nil, fmt.Errorf("Response error: %v", err)
  65. }
  66. if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent {
  67. return resp.Header, fmt.Errorf("Request unsuccessful: %v - %v", resp.Status, url)
  68. }
  69. return resp.Header, nil
  70. }
  71. //BodyToBuffer reads data from ReadCloser and returns bytes buffer.
  72. func BodyToBuffer(data io.ReadCloser) (*bytes.Buffer, error) {
  73. var buffer bytes.Buffer
  74. _, err := buffer.ReadFrom(data)
  75. if err != nil {
  76. return nil, err
  77. }
  78. return &buffer, nil
  79. }