esapi.response.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Licensed to Elasticsearch B.V. under one or more contributor
  2. // license agreements. See the NOTICE file distributed with
  3. // this work for additional information regarding copyright
  4. // ownership. Elasticsearch B.V. licenses this file to you under
  5. // the Apache License, Version 2.0 (the "License"); you may
  6. // not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. package esapi
  18. import (
  19. "bytes"
  20. "fmt"
  21. "io"
  22. "io/ioutil"
  23. "net/http"
  24. "strconv"
  25. "strings"
  26. )
  27. // Response represents the API response.
  28. //
  29. type Response struct {
  30. StatusCode int
  31. Header http.Header
  32. Body io.ReadCloser
  33. }
  34. // String returns the response as a string.
  35. //
  36. // The intended usage is for testing or debugging only.
  37. //
  38. func (r *Response) String() string {
  39. var (
  40. out = new(bytes.Buffer)
  41. b1 = bytes.NewBuffer([]byte{})
  42. b2 = bytes.NewBuffer([]byte{})
  43. tr io.Reader
  44. )
  45. if r != nil && r.Body != nil {
  46. tr = io.TeeReader(r.Body, b1)
  47. defer r.Body.Close()
  48. if _, err := io.Copy(b2, tr); err != nil {
  49. out.WriteString(fmt.Sprintf("<error reading response body: %v>", err))
  50. return out.String()
  51. }
  52. defer func() { r.Body = ioutil.NopCloser(b1) }()
  53. }
  54. if r != nil {
  55. out.WriteString(fmt.Sprintf("[%d %s]", r.StatusCode, http.StatusText(r.StatusCode)))
  56. if r.StatusCode > 0 {
  57. out.WriteRune(' ')
  58. }
  59. } else {
  60. out.WriteString("[0 <nil>]")
  61. }
  62. if r != nil && r.Body != nil {
  63. out.ReadFrom(b2) // errcheck exclude (*bytes.Buffer).ReadFrom
  64. }
  65. return out.String()
  66. }
  67. // Status returns the response status as a string.
  68. //
  69. func (r *Response) Status() string {
  70. var b strings.Builder
  71. if r != nil {
  72. b.WriteString(strconv.Itoa(r.StatusCode))
  73. b.WriteString(" ")
  74. b.WriteString(http.StatusText(r.StatusCode))
  75. }
  76. return b.String()
  77. }
  78. // IsError returns true when the response status indicates failure.
  79. //
  80. func (r *Response) IsError() bool {
  81. return r.StatusCode > 299
  82. }
  83. // Warnings returns the deprecation warnings from response headers.
  84. //
  85. func (r *Response) Warnings() []string {
  86. return r.Header["Warning"]
  87. }
  88. // HasWarnings returns true when the response headers contain deprecation warnings.
  89. //
  90. func (r *Response) HasWarnings() bool {
  91. return len(r.Warnings()) > 0
  92. }