Validate the response from InfluxDB after writing/creating a database to avoid json parsing panics/errors (#8775)
* Validate the response from InfluxDB after writing/creating a database to avoid json parsing panics. * Testing windows signing - ignore * Update config.yml * adding signing to workflow - test * Updated config.yml * Updated config.yml * Updated config.yml * Updated config.yml * revert circleci test changes * Various updates
This commit is contained in:
parent
3a66b57d2c
commit
c25ae5295b
|
|
@ -1,9 +1,11 @@
|
|||
package influxdb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
|
@ -216,8 +218,19 @@ func (c *httpClient) CreateDatabase(ctx context.Context, database string) error
|
|||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := c.validateResponse(resp.Body)
|
||||
|
||||
// Check for poorly formatted response (can't be decoded)
|
||||
if err != nil {
|
||||
return &APIError{
|
||||
StatusCode: resp.StatusCode,
|
||||
Title: resp.Status,
|
||||
Description: "An error response was received while attempting to create the following database: " + database + ". Error: " + err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
queryResp := &QueryResponse{}
|
||||
dec := json.NewDecoder(resp.Body)
|
||||
dec := json.NewDecoder(body)
|
||||
err = dec.Decode(queryResp)
|
||||
|
||||
if err != nil {
|
||||
|
|
@ -341,8 +354,19 @@ func (c *httpClient) writeBatch(ctx context.Context, db, rp string, metrics []te
|
|||
return nil
|
||||
}
|
||||
|
||||
body, err := c.validateResponse(resp.Body)
|
||||
|
||||
// Check for poorly formatted response (can't be decoded)
|
||||
if err != nil {
|
||||
return &APIError{
|
||||
StatusCode: resp.StatusCode,
|
||||
Title: resp.Status,
|
||||
Description: "An error response was received while attempting to write metrics. Error: " + err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
writeResp := &WriteResponse{}
|
||||
dec := json.NewDecoder(resp.Body)
|
||||
dec := json.NewDecoder(body)
|
||||
|
||||
var desc string
|
||||
err = dec.Decode(writeResp)
|
||||
|
|
@ -466,6 +490,27 @@ func (c *httpClient) addHeaders(req *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *httpClient) validateResponse(response io.ReadCloser) (io.ReadCloser, error) {
|
||||
bodyBytes, err := ioutil.ReadAll(response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Close()
|
||||
|
||||
originalResponse := ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
|
||||
|
||||
// Empty response is valid.
|
||||
if response == http.NoBody || len(bodyBytes) == 0 || bodyBytes == nil {
|
||||
return originalResponse, nil
|
||||
}
|
||||
|
||||
if valid := json.Valid(bodyBytes); !valid {
|
||||
err = errors.New(string(bodyBytes))
|
||||
}
|
||||
|
||||
return originalResponse, err
|
||||
}
|
||||
|
||||
func makeWriteURL(loc *url.URL, db, rp, consistency string) (string, error) {
|
||||
params := url.Values{}
|
||||
params.Set("db", db)
|
||||
|
|
|
|||
|
|
@ -212,6 +212,26 @@ func TestHTTP_CreateDatabase(t *testing.T) {
|
|||
w.WriteHeader(http.StatusOK)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid json response is handled",
|
||||
config: influxdb.HTTPConfig{
|
||||
URL: u,
|
||||
Database: `database`,
|
||||
},
|
||||
queryHandlerFunc: func(t *testing.T, w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`invalid response`))
|
||||
},
|
||||
errFunc: func(t *testing.T, err error) {
|
||||
expected := &influxdb.APIError{
|
||||
StatusCode: 400,
|
||||
Title: "400 Bad Request",
|
||||
Description: "An error response was received while attempting to create the following database: database. Error: invalid response",
|
||||
}
|
||||
|
||||
require.Equal(t, expected, err)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
|
|||
Loading…
Reference in New Issue