A Go "clone" of the great and famous Requests library
Switch branches/tags
Nothing to show
Clone or download
Latest commit f3f67e7 Nov 22, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
testdata Changed test data dir name Dec 13, 2015
.gitignore Init Jun 11, 2015
.travis.yml Bump go version Oct 29, 2018
LICENSE Cosmetic fixes Jun 15, 2015
README.md Cleaned up readme and fixed #65 Jul 15, 2018
base.go Make doRegularRequest public #63 Jul 15, 2018
base_delete_test.go Init sessions Jul 8, 2015
base_get_test.go Added request hook function Jul 15, 2018
base_head_test.go Init sessions Jul 8, 2015
base_options_test.go Init sessions Jul 8, 2015
base_patch_test.go Init sessions Jul 8, 2015
base_post_test.go Allow to define mime-type when uploading a new file (#58) Oct 9, 2017
base_put_test.go Fixed broken tests Jul 15, 2018
example_test.go Fixed #23 cookies now takes the value of Response.Cookies() https://g… Apr 27, 2016
file_upload.go Allow to define mime-type when uploading a new file (#58) Oct 9, 2017
file_upload_test.go Changed test data dir name Dec 13, 2015
go.mod Add mod file Nov 23, 2018
request.go You can now send requests from the local addr Jul 15, 2018
request_test.go Ensured that HTTPClient is reused unless a custom http.Transport is n… Jun 25, 2015
response.go clean up error handling Jul 17, 2018
response_test.go Added individual request proxy support Jul 2, 2015
session.go support global options within sessions (#42) Nov 2, 2016
utils.go Don't allow single hop headers on redirect Nov 20, 2016
utils_test.go Added support for PUT, PATCH and DELETE as well as reworked some inte… Jun 19, 2015

README.md

GRequests

A Go "clone" of the great and famous Requests library

Build Status GoDoc Coverage Status Join the chat at https://gitter.im/levigross/grequests

License

GRequests is licensed under the Apache License, Version 2.0. See LICENSE for the full license text

Features

  • Responses can be serialized into JSON and XML
  • Easy file uploads
  • Easy file downloads
  • Support for the following HTTP verbs GET, HEAD, POST, PUT, DELETE, PATCH, OPTIONS

Install

go get -u github.com/levigross/grequests

Usage

import "github.com/levigross/grequests"

Basic Examples

Basic GET request:

resp, err := grequests.Get("http://httpbin.org/get", nil)
// You can modify the request by passing an optional RequestOptions struct

if err != nil {
	log.Fatalln("Unable to make request: ", err)
}

fmt.Println(resp.String())
// {
//   "args": {},
//   "headers": {
//     "Accept": "*/*",
//     "Host": "httpbin.org",

If an error occurs all of the other properties and methods of a Response will be nil

Quirks

Request Quirks

When passing parameters to be added to a URL, if the URL has existing parameters that contradict with what has been passed within ParamsParams will be the "source of authority" and overwrite the contradicting URL parameter.

Lets see how it works...

ro := &RequestOptions{
	Params: map[string]string{"Hello": "Goodbye"},
}
Get("http://httpbin.org/get?Hello=World", ro)
// The URL is now http://httpbin.org/get?Hello=Goodbye

Response Quirks

Order matters! This is because grequests.Response is implemented as an io.ReadCloser which proxies the http.Response.Body io.ReadCloser interface. It also includes an internal buffer for use in Response.String() and Response.Bytes().

Here are a list of methods that consume the http.Response.Body io.ReadCloser interface.

  • Response.JSON
  • Response.XML
  • Response.DownloadToFile
  • Response.Close
  • Response.Read

The following methods make use of an internal byte buffer

  • Response.String
  • Response.Bytes

In the code below, once the file is downloaded – the Response struct no longer has access to the request bytes

response := Get("http://some-wonderful-file.txt", nil)

if err := response.DownloadToFile("randomFile"); err != nil {
	log.Println("Unable to download file: ", err)
}

// At this point the .String and .Bytes method will return empty responses

response.Bytes() == nil // true
response.String() == "" // true

But if we were to call response.Bytes() or response.String() first, every operation will succeed until the internal buffer is cleared:

response := Get("http://some-wonderful-file.txt", nil)

// This call to .Bytes caches the request bytes in an internal byte buffer – which can be used again and again until it is cleared
response.Bytes() == `file-bytes`
response.String() == "file-string"

// This will work because it will use the internal byte buffer
if err := resp.DownloadToFile("randomFile"); err != nil {
	log.Println("Unable to download file: ", err)
}

// Now if we clear the internal buffer....
response.ClearInternalBuffer()

// At this point the .String and .Bytes method will return empty responses

response.Bytes() == nil // true
response.String() == "" // true