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