diff --git a/recaptcha.go b/recaptcha.go index c1a9a02..09a4838 100644 --- a/recaptcha.go +++ b/recaptcha.go @@ -1,12 +1,11 @@ package recaptcha import ( - "bytes" "encoding/json" "fmt" - "io" "io/ioutil" "net/http" + "net/url" "time" ) @@ -27,7 +26,7 @@ type reCHAPTCHAResponse struct { // custom client so we can mock in tests type netClient interface { - Post(url string, contentType string, body io.Reader) (resp *http.Response, err error) + PostForm(url string, formValues url.Values) (resp *http.Response, err error) } type ReCAPTCHA struct { @@ -67,13 +66,13 @@ func (r *ReCAPTCHA) VerifyNoRemoteIP(challengeResponse string) (bool, error) { func (r *ReCAPTCHA) confirm(recaptcha reCHAPTCHARequest) (Ok bool, Err error) { Ok, Err = false, nil - - formValue := []byte(`secret=` + recaptcha.Secret + `&response=` + recaptcha.Response) - response, err := r.Client.Post( - r.ReCAPTCHALink, - "application/x-www-form-urlencoded; charset=utf-8", - bytes.NewBuffer(formValue), - ) + var formValues url.Values + if recaptcha.RemoteIP != "" { + formValues = url.Values{"secret": {recaptcha.Secret}, "remoteip": {recaptcha.RemoteIP}, "response": {recaptcha.Response}} + } else { + formValues = url.Values{"secret": {recaptcha.Secret}, "response": {recaptcha.Response}} + } + response, err := r.Client.PostForm(r.ReCAPTCHALink, formValues) if err != nil { Err = fmt.Errorf("error posting to recaptcha endpoint: %s", err) return diff --git a/recaptcha_test.go b/recaptcha_test.go index 46e992e..0968a25 100644 --- a/recaptcha_test.go +++ b/recaptcha_test.go @@ -2,9 +2,9 @@ package recaptcha import ( "fmt" - "io" "io/ioutil" "net/http" + "net/url" "strings" "testing" @@ -19,7 +19,7 @@ var _ = Suite(&ReCaptchaSuite{}) type mockSuccessClient struct{} -func (*mockSuccessClient) Post(url string, contentType string, body io.Reader) (resp *http.Response, err error) { +func (*mockSuccessClient) PostForm(url string, formValues url.Values) (resp *http.Response, err error) { resp = &http.Response{ Status: "200 OK", StatusCode: 200, @@ -36,7 +36,7 @@ func (*mockSuccessClient) Post(url string, contentType string, body io.Reader) ( type mockFailedClient struct{} -func (*mockFailedClient) Post(url string, contentType string, body io.Reader) (resp *http.Response, err error) { +func (*mockFailedClient) PostForm(url string, formValues url.Values) (resp *http.Response, err error) { resp = &http.Response{ Status: "200 OK", StatusCode: 200, @@ -55,7 +55,7 @@ func (*mockFailedClient) Post(url string, contentType string, body io.Reader) (r type mockInvalidClient struct{} // bad json body -func (*mockInvalidClient) Post(url string, contentType string, body io.Reader) (resp *http.Response, err error) { +func (*mockInvalidClient) PostForm(url string, formValues url.Values) (resp *http.Response, err error) { resp = &http.Response{ Status: "200 OK", StatusCode: 200, @@ -66,7 +66,7 @@ func (*mockInvalidClient) Post(url string, contentType string, body io.Reader) ( type mockUnavailableClient struct{} -func (*mockUnavailableClient) Post(url string, contentType string, body io.Reader) (resp *http.Response, err error) { +func (*mockUnavailableClient) PostForm(url string, formValues url.Values) (resp *http.Response, err error) { resp = &http.Response{ Status: "Not Found", StatusCode: 404,