Skip to content

Commit 70fb78a

Browse files
committed
feat: Handle form post 307/308 status codes
On status codes 307/308, the original request should be repeated. A form post should therefore be a new post with the same body.
1 parent a9ca7c8 commit 70fb78a

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

html/form_data.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ func (d *FormData) Has(name string) bool {
124124
return slices.IndexFunc(d.Entries, elementByName(name)) != -1
125125
}
126126

127-
func (d *FormData) GetReader() io.Reader {
128-
return strings.NewReader(d.QueryString())
127+
func (d *FormData) GetReader() io.ReadCloser {
128+
return io.NopCloser(strings.NewReader(d.QueryString()))
129129
}
130130

131131
// QueryString returns the formdata as a &-separated URL encoded key-value pair.

html/html_form_element.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const (
2020
)
2121

2222
type GetReader interface {
23-
GetReader() io.Reader
23+
GetReader() io.ReadCloser
2424
}
2525

2626
type FormDataEventInit struct {
@@ -110,6 +110,7 @@ func (e *htmlFormElement) Elements() dom.NodeList {
110110
}
111111

112112
func (e *htmlFormElement) submitFormData(formData *FormData) error {
113+
fmt.Println("Submit data", e.Method(), e.Action())
113114
e.DispatchEvent(newFormDataEvent(formData))
114115

115116
var (
@@ -121,8 +122,8 @@ func (e *htmlFormElement) submitFormData(formData *FormData) error {
121122
targetURL := replaceSearchParams(e.action(), searchParams)
122123
req, err = http.NewRequest("GET", targetURL, nil)
123124
} else {
124-
getReader := GetReader(formData)
125-
req, err = http.NewRequest("POST", e.Action(), getReader.GetReader())
125+
req, err = http.NewRequest("POST", e.Action(), formData.GetReader())
126+
req.GetBody = func() (io.ReadCloser, error) { return formData.GetReader(), nil }
126127
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
127128
}
128129
if err != nil {

html/html_form_element_submit_test.go

+40-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package html_test
22

33
import (
4+
"fmt"
45
"net/http"
56
"net/url"
67
"reflect"
@@ -52,20 +53,25 @@ type WindowFixture struct {
5253
form html.HTMLFormElement
5354
actualRequest *http.Request
5455
submittedForm url.Values
56+
handler http.Handler
5557
}
5658

5759
func (f *WindowFixture) Setup() {
58-
win := html.NewWindow(html.WindowOptions{
59-
HttpClient: gosthttp.NewHttpClientFromHandler(
60+
handler := f.handler
61+
if handler == nil {
62+
fmt.Println("Overwrite handler")
63+
handler =
6064
http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
6165
if req.ParseForm() != nil {
6266
panic("Error parsing form")
6367
}
6468
f.actualRequest = req
6569
f.submittedForm = req.Form
6670
f.requests = append(f.requests, req)
67-
}),
68-
),
71+
})
72+
}
73+
win := html.NewWindow(html.WindowOptions{
74+
HttpClient: gosthttp.NewHttpClientFromHandler(handler),
6975
BaseLocation: string(f.BaseLocationFixture),
7076
})
7177
f.Window = htmltest.NewWindowHelper(f.TB, win)
@@ -298,3 +304,33 @@ func TestHTMLFormElementSubmitInputWithClickResetButton(t *testing.T) {
298304
w.Submitter.Click()
299305
w.Assert().Nil(w.submittedForm, "A form was submitted")
300306
}
307+
308+
func TestResubmitFormOn307Redirects(t *testing.T) {
309+
var (
310+
actualRequest *http.Request
311+
submittedForm url.Values
312+
)
313+
314+
mux := http.NewServeMux()
315+
mux.Handle("POST /form-destination", http.RedirectHandler("/form-redirected", 307))
316+
mux.HandleFunc("POST /form-redirected", func(w http.ResponseWriter, r *http.Request) {
317+
r.ParseForm()
318+
actualRequest = r
319+
submittedForm = r.Form
320+
})
321+
322+
w, setup := InitFixture(
323+
t,
324+
&HTMLFormSubmitInputFixture{},
325+
BaseLocationFixture("http://example.com/forms"),
326+
)
327+
328+
w.HTMLFormFixture.handler = mux
329+
setup.Setup()
330+
form := w.Form()
331+
form.SetMethod("post")
332+
form.SetAction("/form-destination")
333+
form.Submit()
334+
w.Assert().NotNil(actualRequest, "Request sent to the redirected location")
335+
w.Assert().Equal([]string{"bar"}, submittedForm["foo"], "Form on second request")
336+
}

0 commit comments

Comments
 (0)