Skip to content

Commit 09a7f17

Browse files
authored
Request body reader (levigross#24)
Signed-off-by: Levi Gross <[email protected]> Allow for custom cookie jars and fix nil pointer dereference Signed-off-by: Levi Gross <[email protected]> If we add a cookie jar to request options – use it Signed-off-by: Levi Gross <[email protected]> Remove unneeded error check Signed-off-by: Levi Gross <[email protected]>
1 parent 9a75678 commit 09a7f17

File tree

4 files changed

+104
-3
lines changed

4 files changed

+104
-3
lines changed

base_get_test.go

+48-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/xml"
77
"io"
88
"net/http"
9+
"net/http/cookiejar"
910
"net/http/httptest"
1011
"net/url"
1112
"os"
@@ -222,6 +223,50 @@ func TestGetWithCookies(t *testing.T) {
222223

223224
}
224225

226+
func TestGetWithCookiesCustomCookieJar(t *testing.T) {
227+
cookieJar, _ := cookiejar.New(nil)
228+
resp, err := Get("http://httpbin.org/cookies",
229+
&RequestOptions{
230+
CookieJar: cookieJar,
231+
Cookies: []*http.Cookie{
232+
{
233+
Name: "TestCookie",
234+
Value: "Random Value",
235+
HttpOnly: true,
236+
Secure: false,
237+
}, {
238+
Name: "AnotherCookie",
239+
Value: "Some Value",
240+
HttpOnly: true,
241+
Secure: false,
242+
},
243+
},
244+
})
245+
246+
if err != nil {
247+
t.Error("Unable to make request", err)
248+
}
249+
250+
if resp.Ok != true {
251+
t.Error("Request did not return OK")
252+
}
253+
254+
myJSONStruct := &TestJSONCookies{}
255+
256+
if err := resp.JSON(myJSONStruct); err != nil {
257+
t.Error("Cannot serialize cookie JSON: ", err)
258+
}
259+
260+
if myJSONStruct.Cookies.TestCookie != "Random Value" {
261+
t.Errorf("Cookie value not set properly: %#v", myJSONStruct)
262+
}
263+
264+
if myJSONStruct.Cookies.AnotherCookie != "Some Value" {
265+
t.Errorf("Cookie value not set properly: %#v", myJSONStruct)
266+
}
267+
268+
}
269+
225270
func TestGetSession(t *testing.T) {
226271
session := NewSession(nil)
227272

@@ -296,11 +341,13 @@ func xmlASCIIDecoder(charset string, input io.Reader) (io.Reader, error) {
296341
}
297342

298343
func TestGetInvalidURL(t *testing.T) {
299-
_, err := Get("%../dir/", &RequestOptions{Params: map[string]string{"1": "2"}})
344+
resp, err := Get("%../dir/", &RequestOptions{Params: map[string]string{"1": "2"}})
300345

301346
if err == nil {
302347
t.Error("Some how the request was valid to make request", err)
303348
}
349+
350+
resp.ClearInternalBuffer() // This will panic without our nil checks
304351
}
305352

306353
func TestGetInvalidURLNoParams(t *testing.T) {

base_post_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,40 @@ func TestXMLPostRequest(t *testing.T) {
351351

352352
}
353353

354+
func TestXMLPostRequestReaderBody(t *testing.T) {
355+
msg := XMLPostMessage{Name: "Human", Age: 1, Height: 1}
356+
derBytes, err := xml.Marshal(msg)
357+
if err != nil {
358+
t.Fatal("Unable to marshal XML", err)
359+
}
360+
361+
resp, _ := Post("http://httpbin.org/post",
362+
&RequestOptions{RequestBody: bytes.NewReader(derBytes)})
363+
364+
if resp.Error != nil {
365+
t.Fatal("Unable to make request", resp.Error)
366+
}
367+
368+
if resp.Ok != true {
369+
t.Error("Request did not return OK")
370+
}
371+
372+
myJSONStruct := &BasicPostJSONResponse{}
373+
374+
if err := resp.JSON(myJSONStruct); err != nil {
375+
t.Error("Unable to coerce to JSON", err)
376+
}
377+
378+
myXMLStruct := &XMLPostMessage{}
379+
380+
xml.Unmarshal([]byte(myJSONStruct.Data), myXMLStruct)
381+
382+
if myXMLStruct.Age != 1 {
383+
t.Errorf("Unable to serialize XML response from within JSON %#v ", myXMLStruct)
384+
}
385+
386+
}
387+
354388
func TestXMLMarshaledStringPostRequest(t *testing.T) {
355389
xmlStruct := XMLPostMessage{Name: "Human", Age: 1, Height: 1}
356390
encoded, _ := xml.Marshal(xmlStruct)

request.go

+20
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ type RequestOptions struct {
117117
// before returning an error be default this is set to 30. You can change this
118118
// globally by modifying the `RedirectLimit` variable.
119119
RedirectLimit int
120+
121+
// RequestBody allows you to put anything matching an `io.Reader` into the request
122+
// this option will take precedence over any other request option specified
123+
RequestBody io.Reader
124+
125+
// CookieJar allows you to specify a special cookiejar to use with your request.
126+
// this option will take precedence over the `UseCookieJar` option above.
127+
CookieJar http.CookieJar
120128
}
121129

122130
func doRegularRequest(requestVerb, url string, ro *RequestOptions) (*Response, error) {
@@ -132,6 +140,11 @@ func buildRequest(httpMethod, url string, ro *RequestOptions, httpClient *http.C
132140
if ro == nil {
133141
ro = &RequestOptions{}
134142
}
143+
144+
if ro.CookieJar != nil {
145+
ro.UseCookieJar = true
146+
}
147+
135148
// Create our own HTTP client
136149

137150
if httpClient == nil {
@@ -166,6 +179,10 @@ func buildRequest(httpMethod, url string, ro *RequestOptions, httpClient *http.C
166179
}
167180

168181
func buildHTTPRequest(httpMethod, userURL string, ro *RequestOptions) (*http.Request, error) {
182+
if ro.RequestBody != nil {
183+
return http.NewRequest(httpMethod, userURL, ro.RequestBody)
184+
}
185+
169186
if ro.JSON != nil {
170187
return createBasicJSONRequest(httpMethod, userURL, ro)
171188
}
@@ -411,6 +428,9 @@ func BuildHTTPClient(ro RequestOptions) *http.Client {
411428
var cookieJar http.CookieJar
412429

413430
if ro.UseCookieJar {
431+
if ro.CookieJar != nil {
432+
cookieJar = ro.CookieJar
433+
}
414434
// The function does not return an error ever... so we are just ignoring it
415435
cookieJar, _ = cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
416436
}

response.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ func (r *Response) String() string {
207207
// data. Once you have used these functions – you may want to free up the memory.
208208
func (r *Response) ClearInternalBuffer() {
209209

210-
if r.Error != nil {
211-
return // This is a noop as we will be dereferencing a null pointer
210+
if r == nil || r.internalByteBuffer == nil {
211+
return
212212
}
213213

214214
r.internalByteBuffer.Reset()

0 commit comments

Comments
 (0)