Merge pull request #17090 from jwa/state-remote-webdav

allow HTTP 201 & 204 when storing remote state
This commit is contained in:
James Bardin 2018-01-25 13:43:05 -05:00 committed by GitHub
commit 522ae01e73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 3 deletions

View File

@ -313,7 +313,7 @@ func (c *HTTPClient) Put(data []byte) error {
// Handle the error codes // Handle the error codes
switch resp.StatusCode { switch resp.StatusCode {
case http.StatusOK: case http.StatusOK, http.StatusCreated, http.StatusNoContent:
return nil return nil
default: default:
return fmt.Errorf("HTTP error: %d", resp.StatusCode) return fmt.Errorf("HTTP error: %d", resp.StatusCode)

View File

@ -7,6 +7,7 @@ import (
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"reflect"
"testing" "testing"
"github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-cleanhttp"
@ -31,6 +32,14 @@ func TestHTTPClient(t *testing.T) {
client := &HTTPClient{URL: url, Client: cleanhttp.DefaultClient()} client := &HTTPClient{URL: url, Client: cleanhttp.DefaultClient()}
testClient(t, client) testClient(t, client)
// test just a single PUT
p := &HTTPClient{
URL: url,
UpdateMethod: "PUT",
Client: cleanhttp.DefaultClient(),
}
testClient(t, p)
// Test locking and alternative UpdateMethod // Test locking and alternative UpdateMethod
a := &HTTPClient{ a := &HTTPClient{
URL: url, URL: url,
@ -52,6 +61,19 @@ func TestHTTPClient(t *testing.T) {
} }
TestRemoteLocks(t, a, b) TestRemoteLocks(t, a, b)
// test a WebDAV-ish backend
davhandler := new(testHTTPHandler)
ts = httptest.NewServer(http.HandlerFunc(davhandler.HandleWebDAV))
defer ts.Close()
url, err = url.Parse(ts.URL)
c := &HTTPClient{
URL: url,
UpdateMethod: "PUT",
Client: cleanhttp.DefaultClient(),
}
testClient(t, c) // first time through: 201
testClient(t, c) // second time, with identical data: 204
} }
func assertError(t *testing.T, err error, expected string) { func assertError(t *testing.T, err error, expected string) {
@ -134,12 +156,18 @@ func (h *testHTTPHandler) Handle(w http.ResponseWriter, r *http.Request) {
switch r.Method { switch r.Method {
case "GET": case "GET":
w.Write(h.Data) w.Write(h.Data)
case "POST", "PUT": case "PUT":
buf := new(bytes.Buffer)
if _, err := io.Copy(buf, r.Body); err != nil {
w.WriteHeader(500)
}
w.WriteHeader(201)
h.Data = buf.Bytes()
case "POST":
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
if _, err := io.Copy(buf, r.Body); err != nil { if _, err := io.Copy(buf, r.Body); err != nil {
w.WriteHeader(500) w.WriteHeader(500)
} }
h.Data = buf.Bytes() h.Data = buf.Bytes()
case "LOCK": case "LOCK":
if h.Locked { if h.Locked {
@ -157,3 +185,29 @@ func (h *testHTTPHandler) Handle(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(fmt.Sprintf("Unknown method: %s", r.Method))) w.Write([]byte(fmt.Sprintf("Unknown method: %s", r.Method)))
} }
} }
// mod_dav-ish behavior
func (h *testHTTPHandler) HandleWebDAV(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
w.Write(h.Data)
case "PUT":
buf := new(bytes.Buffer)
if _, err := io.Copy(buf, r.Body); err != nil {
w.WriteHeader(500)
}
if reflect.DeepEqual(h.Data, buf.Bytes()) {
h.Data = buf.Bytes()
w.WriteHeader(204)
} else {
h.Data = buf.Bytes()
w.WriteHeader(201)
}
case "DELETE":
h.Data = nil
w.WriteHeader(200)
default:
w.WriteHeader(500)
w.Write([]byte(fmt.Sprintf("Unknown method: %s", r.Method)))
}
}