Skip to content

Commit

Permalink
Merge branch 'release/v0.2.5'
Browse files Browse the repository at this point in the history
  • Loading branch information
parnurzeal committed Jul 1, 2015
2 parents 30f5049 + fc6093f commit c7d711c
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 7 deletions.
14 changes: 11 additions & 3 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
Changelog
=========

v0.2.5 (2015-07-01)

Features
* Added Basic Auth support (pull request #24 by @dickeyxxx)

Bug/Fixes
# Fix #31 incorrect number conversion (PR #34 by @killix)

v0.2.4 (2015-04-13)

Features
* Query() now supports Struct as same as Send() (pull request by @figlief)
* Query() now supports Struct as same as Send() (pull request #25 by @figlief)

v0.2.3 (2015-02-08)

Expand All @@ -18,8 +26,8 @@ v0.2.2 (2015-01-03)

Features
* Added TLSClientConfig for better control over tls
* Added AddCookie func to set "Cookie" field in request (pull request by @austinov) - Issue #7
* Added CookieJar (pull request by @kemadz)
* Added AddCookie func to set "Cookie" field in request (pull request #17 by @austinov) - Issue #7
* Added CookieJar (pull request #15 by @kemadz)

v0.2.1 (2014-07-06)

Expand Down
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Sending request would never been fun and easier than this. It comes with lots of
* RedirectPolicy
* Cookie - setting cookies for your request
* CookieJar - automatic in-memory cookiejar
* BasicAuth - setting basic authentication header
* more to come..

## Installation
Expand Down Expand Up @@ -153,9 +154,21 @@ In the case when you are behind proxy, GoRequest can handle it easily with Proxy

```go
request := gorequest.New().Proxy("http://proxy:999")
resp, body, errs:= request.Get("http://example-proxy.com").End()
resp, body, errs := request.Get("http://example-proxy.com").End()
// To reuse same client with no_proxy, use empty string:
resp, body, errs= request.Proxy("").("http://example-no-proxy.com").End()
resp, body, errs = request.Proxy("").("http://example-no-proxy.com").End()
```

## Basic Authentication

To add a basic authentication header:

```go
request := gorequest.New().SetBasicAuth("username", "password")
resp, body, errs := request.Get("http://example-proxy.com").End()
// To unset it for any following request, just set both username and password to empty string:
request.SetBasicAuth("","")
resp, body, errs := request.Get("http://example-proxy-noauth.com").End()
```

## Timeout
Expand All @@ -176,6 +189,10 @@ As the underlying gorequest is based on http.Client in most usecases, gorequest.

If you find any improvement or issue you want to fix, feel free to send me a pull request with testing.

Thanks to all contributers thus far:

@kemadz, @austinov, @figlief, @dickeyxxx, @killix

## Credits

* Renee French - the creator of Gopher mascot
Expand Down
36 changes: 34 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type SuperAgent struct {
Transport *http.Transport
Cookies []*http.Cookie
Errors []error
BasicAuth struct{ Username, Password string }
}

// Used to create a new SuperAgent object.
Expand All @@ -63,6 +64,7 @@ func New() *SuperAgent {
Transport: &http.Transport{},
Cookies: make([]*http.Cookie, 0),
Errors: nil,
BasicAuth: struct{ Username, Password string }{},
}
return s
}
Expand Down Expand Up @@ -141,6 +143,18 @@ func (s *SuperAgent) Set(param string, value string) *SuperAgent {
return s
}

// SetBasicAuth sets the basic authentication header
// Example. To set the header for username "myuser" and password "mypass"
//
// gorequest.New()
// Post("/gamelist").
// SetBasicAuth("myuser", "mypass").
// End()
func (s *SuperAgent) SetBasicAuth(username string, password string) *SuperAgent {
s.BasicAuth = struct{ Username, Password string }{username, password}
return s
}

// AddCookie adds a cookie to the request. The behavior is the same as AddCookie on Request from net/http
func (s *SuperAgent) AddCookie(c *http.Cookie) *SuperAgent {
s.Cookies = append(s.Cookies, c)
Expand Down Expand Up @@ -384,7 +398,9 @@ func (s *SuperAgent) sendStruct(content interface{}) *SuperAgent {
s.Errors = append(s.Errors, err)
} else {
var val map[string]interface{}
if err := json.Unmarshal(marshalContent, &val); err != nil {
d := json.NewDecoder(bytes.NewBuffer(marshalContent))
d.UseNumber()
if err := d.Decode(&val); err != nil {
s.Errors = append(s.Errors, err)
} else {
for k, v := range val {
Expand All @@ -401,7 +417,9 @@ func (s *SuperAgent) sendStruct(content interface{}) *SuperAgent {
func (s *SuperAgent) SendString(content string) *SuperAgent {
var val map[string]interface{}
// check if it is json format
if err := json.Unmarshal([]byte(content), &val); err == nil {
d := json.NewDecoder(strings.NewReader(content))
d.UseNumber()
if err := d.Decode(&val); err == nil {
for k, v := range val {
s.Data[k] = v
}
Expand Down Expand Up @@ -441,6 +459,12 @@ func changeMapToURLValues(data map[string]interface{}) url.Values {
for _, element := range val {
newUrlValues.Add(k, element)
}
// if a number, change to string
// json.Number used to protect against a wrong (for GoRequest) default conversion
// which always converts number to float64.
// This type is caused by using Decoder.UseNumber()
case json.Number:
newUrlValues.Add(k, string(val))
}
}
return newUrlValues
Expand Down Expand Up @@ -512,6 +536,14 @@ func (s *SuperAgent) End(callback ...func(response Response, body string, errs [
}
req.URL.RawQuery = q.Encode()

// Add basic auth
// Unset if struct is empty
if s.BasicAuth != struct{ Username, Password string }{} {
req.SetBasicAuth(s.BasicAuth.Username, s.BasicAuth.Password)
} else {
req.Header.Del("Authorization")
}

// Add cookies
for _, cookie := range s.Cookies {
req.AddCookie(cookie)
Expand Down
46 changes: 46 additions & 0 deletions request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package gorequest

import (
"bytes"
"encoding/base64"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -57,6 +59,9 @@ func TestPost(t *testing.T) {
const case5_integration_send_json_string = "/integration_send_json_string"
const case6_set_query = "/set_query"
const case7_integration_send_json_struct = "/integration_send_json_struct"
// Check that the number conversion should be converted as string not float64
const case8_send_json_with_long_id_number = "/send_json_with_long_id_number"
const case9_send_json_string_with_long_id_number_as_form_result = "/send_json_string_with_long_id_number_as_form_result"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// check method is PATCH before going to check other features
if r.Method != POST {
Expand Down Expand Up @@ -116,6 +121,20 @@ func TestPost(t *testing.T) {
if !bytes.Equal(body, comparedBody) {
t.Errorf(`Expected correct json but got ` + string(body))
}
case case8_send_json_with_long_id_number:
t.Logf("case %v ", case8_send_json_with_long_id_number)
defer r.Body.Close()
body, _ := ioutil.ReadAll(r.Body)
if string(body) != `{"id":123456789,"name":"nemo"}` {
t.Error(`Expected Body with {"id":123456789,"name":"nemo"}`, "| but got", string(body))
}
case case9_send_json_string_with_long_id_number_as_form_result:
t.Logf("case %v ", case9_send_json_string_with_long_id_number_as_form_result)
defer r.Body.Close()
body, _ := ioutil.ReadAll(r.Body)
if string(body) != `id=123456789&name=nemo` {
t.Error(`Expected Body with "id=123456789&name=nemo"`, `| but got`, string(body))
}
}
}))

Expand Down Expand Up @@ -176,6 +195,15 @@ func TestPost(t *testing.T) {
Send(`{"a":"a"}`).
Send(myStyle).
End()

New().Post(ts.URL + case8_send_json_with_long_id_number).
Send(`{"id":123456789, "name":"nemo"}`).
End()

New().Post(ts.URL + case9_send_json_string_with_long_id_number_as_form_result).
Type("form").
Send(`{"id":123456789, "name":"nemo"}`).
End()
}

// testing for Patch method
Expand Down Expand Up @@ -413,3 +441,21 @@ func TestErrorTypeWrongKey(t *testing.T) {
t.Errorf("Should have error")
}
}

func TestBasicAuth(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := strings.SplitN(r.Header["Authorization"][0], " ", 2)
if len(auth) != 2 || auth[0] != "Basic" {
t.Error("bad syntax")
}
payload, _ := base64.StdEncoding.DecodeString(auth[1])
pair := strings.SplitN(string(payload), ":", 2)
if pair[0] != "myusername" || pair[1] != "mypassword" {
t.Error("Wrong username/password")
}
}))
defer ts.Close()
New().Post(ts.URL).
SetBasicAuth("myusername", "mypassword").
End()
}

0 comments on commit c7d711c

Please sign in to comment.