소스 검색

feat(cli): add grafana version header to all request against grafana.net

bergquist 9 년 전
부모
커밋
3c92f78ee7

+ 3 - 0
pkg/cmd/grafana-cli/main.go

@@ -8,6 +8,7 @@ import (
 	"github.com/codegangsta/cli"
 	"github.com/grafana/grafana/pkg/cmd/grafana-cli/commands"
 	"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
+	"github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
 	"github.com/grafana/grafana/pkg/cmd/grafana-cli/utils"
 )
 
@@ -16,6 +17,8 @@ var version = "master"
 func main() {
 	setupLogging()
 
+	services.Init(version)
+
 	app := cli.NewApp()
 	app.Name = "Grafana cli"
 	app.Usage = ""

+ 70 - 19
pkg/cmd/grafana-cli/services/services.go

@@ -1,35 +1,59 @@
 package services
 
 import (
+	"crypto/tls"
 	"encoding/json"
 	"errors"
 	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
 	"path"
+	"time"
 
-	"github.com/franela/goreq"
 	"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
 	m "github.com/grafana/grafana/pkg/cmd/grafana-cli/models"
 )
 
-var IoHelper m.IoUtil = IoUtilImp{}
+var (
+	IoHelper       m.IoUtil = IoUtilImp{}
+	HttpClient     http.Client
+	grafanaVersion string
+)
+
+func Init(version string) {
+	grafanaVersion = version
+
+	tr := &http.Transport{
+		TLSClientConfig: &tls.Config{InsecureSkipVerify: false},
+	}
+
+	HttpClient = http.Client{
+		Timeout:   time.Duration(10 * time.Second),
+		Transport: tr,
+	}
+}
 
 func ListAllPlugins(repoUrl string) (m.PluginRepo, error) {
-	fullUrl := repoUrl + "/repo"
-	res, err := goreq.Request{Uri: fullUrl, MaxRedirects: 3}.Do()
+	body, err := createRequest(repoUrl, "repo")
+
 	if err != nil {
-		return m.PluginRepo{}, err
+		logger.Info("Failed to create request", "error", err)
+		return m.PluginRepo{}, fmt.Errorf("Failed to create request. error: %v", err)
 	}
-	if res.StatusCode != 200 {
-		return m.PluginRepo{}, fmt.Errorf("Could not access %s statuscode %v", fullUrl, res.StatusCode)
+
+	if err != nil {
+		return m.PluginRepo{}, err
 	}
 
-	var resp m.PluginRepo
-	err = res.Body.FromJsonTo(&resp)
+	var data m.PluginRepo
+	err = json.Unmarshal(body, &data)
 	if err != nil {
-		return m.PluginRepo{}, errors.New("Could not load plugin data")
+		logger.Info("Failed to unmarshal graphite response error: %v", err)
+		return m.PluginRepo{}, err
 	}
 
-	return resp, nil
+	return data, nil
 }
 
 func ReadPlugin(pluginDir, pluginName string) (m.InstalledPlugin, error) {
@@ -88,21 +112,48 @@ func RemoveInstalledPlugin(pluginPath, pluginName string) error {
 }
 
 func GetPlugin(pluginId, repoUrl string) (m.Plugin, error) {
-	fullUrl := repoUrl + "/repo/" + pluginId
+	body, err := createRequest(repoUrl, "repo", pluginId)
+
+	if err != nil {
+		logger.Info("Failed to create request", "error", err)
+		return m.Plugin{}, fmt.Errorf("Failed to create request. error: %v", err)
+	}
 
-	res, err := goreq.Request{Uri: fullUrl, MaxRedirects: 3}.Do()
 	if err != nil {
 		return m.Plugin{}, err
 	}
-	if res.StatusCode != 200 {
-		return m.Plugin{}, fmt.Errorf("Could not access %s statuscode %v", fullUrl, res.StatusCode)
+
+	var data m.Plugin
+	err = json.Unmarshal(body, &data)
+	if err != nil {
+		logger.Info("Failed to unmarshal graphite response error: %v", err)
+		return m.Plugin{}, err
+	}
+
+	return data, nil
+}
+
+func createRequest(repoUrl string, subPaths ...string) ([]byte, error) {
+	u, _ := url.Parse(repoUrl)
+	for _, v := range subPaths {
+		u.Path = path.Join(u.Path, v)
 	}
 
-	var resp m.Plugin
-	err = res.Body.FromJsonTo(&resp)
+	req, err := http.NewRequest(http.MethodGet, u.String(), nil)
+
+	logger.Info("grafanaVersion ", grafanaVersion)
+
+	req.Header.Set("grafana-version", grafanaVersion)
+	req.Header.Set("User-Agent", "grafana "+grafanaVersion)
+
 	if err != nil {
-		return m.Plugin{}, errors.New("Could not load plugin data")
+		return []byte{}, err
 	}
 
-	return resp, nil
+	res, err := HttpClient.Do(req)
+
+	body, err := ioutil.ReadAll(res.Body)
+	defer res.Body.Close()
+
+	return body, err
 }

+ 0 - 24
vendor/github.com/franela/goreq/.gitignore

@@ -1,24 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-
-src

+ 0 - 8
vendor/github.com/franela/goreq/.travis.yml

@@ -1,8 +0,0 @@
-language: go
-go:
- - 1.5.3
- - tip
-notifications:
-  email:
-      - ionathan@gmail.com
-      - marcosnils@gmail.com

+ 0 - 20
vendor/github.com/franela/goreq/LICENSE

@@ -1,20 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 Jonathan Leibiusky and Marcos Lilljedahl
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 0 - 3
vendor/github.com/franela/goreq/Makefile

@@ -1,3 +0,0 @@
-test:
-	go get -v -d -t ./...
-	go test -v

+ 0 - 444
vendor/github.com/franela/goreq/README.md

@@ -1,444 +0,0 @@
-[![Build Status](https://img.shields.io/travis/franela/goreq/master.svg)](https://travis-ci.org/franela/goreq)
-[![GoDoc](https://godoc.org/github.com/franela/goreq?status.svg)](https://godoc.org/github.com/franela/goreq)
-
-GoReq
-=======
-
-Simple and sane HTTP request library for Go language.
-
-
-
-**Table of Contents**
-
-- [Why GoReq?](#user-content-why-goreq)
-- [How do I install it?](#user-content-how-do-i-install-it)
-- [What can I do with it?](#user-content-what-can-i-do-with-it)
-  - [Making requests with different methods](#user-content-making-requests-with-different-methods)
-  - [GET](#user-content-get)
-    - [Tags](#user-content-tags)
-  - [POST](#user-content-post)
-    - [Sending payloads in the Body](#user-content-sending-payloads-in-the-body)
-  - [Specifiying request headers](#user-content-specifiying-request-headers)
-  - [Sending Cookies](#cookie-support)
-  - [Setting timeouts](#user-content-setting-timeouts)
- - [Using the Response and Error](#user-content-using-the-response-and-error)
- - [Receiving JSON](#user-content-receiving-json)
- - [Sending/Receiving Compressed Payloads](#user-content-sendingreceiving-compressed-payloads)
-    - [Using gzip compression:](#user-content-using-gzip-compression)
-    - [Using deflate compression:](#user-content-using-deflate-compression)
-    - [Using compressed responses:](#user-content-using-compressed-responses)
- - [Proxy](#proxy)
- - [Debugging requests](#debug)
-     - [Getting raw Request & Response](#getting-raw-request--response)
- - [TODO:](#user-content-todo)
-
-
-
-Why GoReq?
-==========
-
-Go has very nice native libraries that allows you to do lots of cool things. But sometimes those libraries are too low level, which means that to do a simple thing, like an HTTP Request, it takes some time. And if you want to do something as simple as adding a timeout to a request, you will end up writing several lines of code.
-
-This is why we think GoReq is useful. Because you can do all your HTTP requests in a very simple and comprehensive way, while enabling you to do more advanced stuff by giving you access to the native API.
-
-How do I install it?
-====================
-
-```bash
-go get github.com/franela/goreq
-```
-
-What can I do with it?
-======================
-
-## Making requests with different methods
-
-#### GET
-```go
-res, err := goreq.Request{ Uri: "http://www.google.com" }.Do()
-```
-
-GoReq default method is GET.
-
-You can also set value to GET method easily
-
-```go
-type Item struct {
-        Limit int
-        Skip int
-        Fields string
-}
-
-item := Item {
-        Limit: 3,
-        Skip: 5,
-        Fields: "Value",
-}
-
-res, err := goreq.Request{
-        Uri: "http://localhost:3000/",
-        QueryString: item,
-}.Do()
-```
-The sample above will send `http://localhost:3000/?limit=3&skip=5&fields=Value`
-
-Alternatively the `url` tag can be used in struct fields to customize encoding properties
-
-```go
-type Item struct {
-        TheLimit int `url:"the_limit"`
-        TheSkip string `url:"the_skip,omitempty"`
-        TheFields string `url:"-"`
-}
-
-item := Item {
-        TheLimit: 3,
-        TheSkip: "",
-        TheFields: "Value",
-}
-
-res, err := goreq.Request{
-        Uri: "http://localhost:3000/",
-        QueryString: item,
-}.Do()
-```
-The sample above will send `http://localhost:3000/?the_limit=3`
-
-
-QueryString also support url.Values
-
-```go
-item := url.Values{}
-item.Set("Limit", 3)
-item.Add("Field", "somefield")
-item.Add("Field", "someotherfield")
-
-res, err := goreq.Request{
-        Uri: "http://localhost:3000/",
-        QueryString: item,
-}.Do()
-```
-
-The sample above will send `http://localhost:3000/?limit=3&field=somefield&field=someotherfield`
-
-### Tags
-
-Struct field `url` tag is mainly used as the request parameter name.
-Tags can be comma separated multiple values, 1st value is for naming and rest has special meanings.
-
-- special tag for 1st value
-    - `-`: value is ignored if set this
-
-- special tag for rest 2nd value
-    - `omitempty`: zero-value is ignored if set this
-    - `squash`: the fields of embedded struct is used for parameter
-
-#### Tag Examples
-
-```go
-type Place struct {
-    Country string `url:"country"`
-    City    string `url:"city"`
-    ZipCode string `url:"zipcode,omitempty"`
-}
-
-type Person struct {
-    Place `url:",squash"`
-
-    FirstName string `url:"first_name"`
-    LastName  string `url:"last_name"`
-    Age       string `url:"age,omitempty"`
-    Password  string `url:"-"`
-}
-
-johnbull := Person{
-	Place: Place{ // squash the embedded struct value
-		Country: "UK",
-		City:    "London",
-		ZipCode: "SW1",
-	},
-	FirstName: "John",
-	LastName:  "Doe",
-	Age:       "35",
-	Password:  "my-secret", // ignored for parameter
-}
-
-goreq.Request{
-	Uri:         "http://localhost/",
-	QueryString: johnbull,
-}.Do()
-// =>  `http://localhost/?first_name=John&last_name=Doe&age=35&country=UK&city=London&zip_code=SW1`
-
-
-// age and zipcode will be ignored because of `omitempty`
-// but firstname isn't.
-samurai := Person{
-	Place: Place{ // squash the embedded struct value
-		Country: "Japan",
-		City:    "Tokyo",
-	},
-	LastName: "Yagyu",
-}
-
-goreq.Request{
-	Uri:         "http://localhost/",
-	QueryString: samurai,
-}.Do()
-// =>  `http://localhost/?first_name=&last_name=yagyu&country=Japan&city=Tokyo`
-```
-
-
-#### POST
-
-```go
-res, err := goreq.Request{ Method: "POST", Uri: "http://www.google.com" }.Do()
-```
-
-## Sending payloads in the Body
-
-You can send ```string```, ```Reader``` or ```interface{}``` in the body. The first two will be sent as text. The last one will be marshalled to JSON, if possible.
-
-```go
-type Item struct {
-    Id int
-    Name string
-}
-
-item := Item{ Id: 1111, Name: "foobar" }
-
-res, err := goreq.Request{
-    Method: "POST",
-    Uri: "http://www.google.com",
-    Body: item,
-}.Do()
-```
-
-## Specifiying request headers
-
-We think that most of the times the request headers that you use are: ```Host```, ```Content-Type```, ```Accept``` and ```User-Agent```. This is why we decided to make it very easy to set these headers.
-
-```go
-res, err := goreq.Request{
-    Uri: "http://www.google.com",
-    Host: "foobar.com",
-    Accept: "application/json",
-    ContentType: "application/json",
-    UserAgent: "goreq",
-}.Do()
-```
-
-But sometimes you need to set other headers. You can still do it.
-
-```go
-req := goreq.Request{ Uri: "http://www.google.com" }
-
-req.AddHeader("X-Custom", "somevalue")
-
-req.Do()
-```
-
-Alternatively you can use the `WithHeader` function to keep the syntax short
-
-```go
-res, err = goreq.Request{ Uri: "http://www.google.com" }.WithHeader("X-Custom", "somevalue").Do()
-```
-
-## Cookie support
-
-Cookies can be either set at the request level by sending a [CookieJar](http://golang.org/pkg/net/http/cookiejar/) in the `CookieJar` request field
-or you can use goreq's one-liner WithCookie method as shown below
-
-```go
-res, err := goreq.Request{
-    Uri: "http://www.google.com",
-}.
-WithCookie(&http.Cookie{Name: "c1", Value: "v1"}).
-Do()
-```
-
-## Setting timeouts
-
-GoReq supports 2 kind of timeouts. A general connection timeout and a request specific one. By default the connection timeout is of 1 second. There is no default for request timeout, which means it will wait forever.
-
-You can change the connection timeout doing:
-
-```go
-goreq.SetConnectTimeout(100 * time.Millisecond)
-```
-
-And specify the request timeout doing:
-
-```go
-res, err := goreq.Request{
-    Uri: "http://www.google.com",
-    Timeout: 500 * time.Millisecond,
-}.Do()
-```
-
-## Using the Response and Error
-
-GoReq will always return 2 values: a ```Response``` and an ```Error```.
-If ```Error``` is not ```nil``` it means that an error happened while doing the request and you shouldn't use the ```Response``` in any way.
-You can check what happened by getting the error message:
-
-```go
-fmt.Println(err.Error())
-```
-And to make it easy to know if it was a timeout error, you can ask the error or return it:
-
-```go
-if serr, ok := err.(*goreq.Error); ok {
-    if serr.Timeout() {
-        ...
-    }
-}
-return err
-```
-
-If you don't get an error, you can safely use the ```Response```.
-
-```go
-res.Uri // return final URL location of the response (fulfilled after redirect was made)
-res.StatusCode // return the status code of the response
-res.Body // gives you access to the body
-res.Body.ToString() // will return the body as a string
-res.Header.Get("Content-Type") // gives you access to all the response headers
-```
-Remember that you should **always** close `res.Body` if it's not `nil`
-
-## Receiving JSON
-
-GoReq will help you to receive and unmarshal JSON.
-
-```go
-type Item struct {
-    Id int
-    Name string
-}
-
-var item Item
-
-res.Body.FromJsonTo(&item)
-```
-
-## Sending/Receiving Compressed Payloads
-GoReq supports gzip, deflate and zlib compression of requests' body and transparent decompression of responses provided they have a correct `Content-Encoding` header.
-
-#####Using gzip compression:
-```go
-res, err := goreq.Request{
-    Method: "POST",
-    Uri: "http://www.google.com",
-    Body: item,
-    Compression: goreq.Gzip(),
-}.Do()
-```
-#####Using deflate/zlib compression:
-```go
-res, err := goreq.Request{
-    Method: "POST",
-    Uri: "http://www.google.com",
-    Body: item,
-    Compression: goreq.Deflate(),
-}.Do()
-```
-#####Using compressed responses:
-If servers replies a correct and matching `Content-Encoding` header (gzip requires `Content-Encoding: gzip` and deflate `Content-Encoding: deflate`) goreq transparently decompresses the response so the previous example should always work:
-```go
-type Item struct {
-    Id int
-    Name string
-}
-res, err := goreq.Request{
-    Method: "POST",
-    Uri: "http://www.google.com",
-    Body: item,
-    Compression: goreq.Gzip(),
-}.Do()
-var item Item
-res.Body.FromJsonTo(&item)
-```
-If no `Content-Encoding` header is replied by the server GoReq will return the crude response.
-
-## Proxy
-If you need to use a proxy for your requests GoReq supports the standard `http_proxy` env variable as well as manually setting the proxy for each request
-
-```go
-res, err := goreq.Request{
-    Method: "GET",
-    Proxy: "http://myproxy:myproxyport",
-    Uri: "http://www.google.com",
-}.Do()
-```
-
-### Proxy basic auth is also supported
-
-```go
-res, err := goreq.Request{
-    Method: "GET",
-    Proxy: "http://user:pass@myproxy:myproxyport",
-    Uri: "http://www.google.com",
-}.Do()
-```
-
-## Debug
-If you need to debug your http requests, it can print the http request detail.
-
-```go
-res, err := goreq.Request{
-	Method:      "GET",
-	Uri:         "http://www.google.com",
-	Compression: goreq.Gzip(),
-	ShowDebug:   true,
-}.Do()
-fmt.Println(res, err)
-```
-
-and it will print the log:
-```
-GET / HTTP/1.1
-Host: www.google.com
-Accept:
-Accept-Encoding: gzip
-Content-Encoding: gzip
-Content-Type:
-```
-
-
-### Getting raw Request & Response 
-
-To get the Request:
-
-```go
-req := goreq.Request{
-        Host: "foobar.com",
-}
-
-//req.Request will return a new instance of an http.Request so you can safely use it for something else
-request, _ := req.NewRequest()
-
-```
-
-
-To get the Response:
-
-```go
-res, err := goreq.Request{
-	Method:      "GET",
-	Uri:         "http://www.google.com",
-	Compression: goreq.Gzip(),
-	ShowDebug:   true,
-}.Do()
-
-// res.Response will contain the original http.Response structure 
-fmt.Println(res.Response, err)
-```
-
-
-
-
-TODO:
------
-
-We do have a couple of [issues](https://github.com/franela/goreq/issues) pending we'll be addressing soon. But feel free to
-contribute and send us PRs (with tests please :smile:).

+ 0 - 491
vendor/github.com/franela/goreq/goreq.go

@@ -1,491 +0,0 @@
-package goreq
-
-import (
-	"bufio"
-	"bytes"
-	"compress/gzip"
-	"compress/zlib"
-	"crypto/tls"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net"
-	"net/http"
-	"net/http/httputil"
-	"net/url"
-	"reflect"
-	"strings"
-	"time"
-)
-
-type itimeout interface {
-	Timeout() bool
-}
-type Request struct {
-	headers           []headerTuple
-	cookies           []*http.Cookie
-	Method            string
-	Uri               string
-	Body              interface{}
-	QueryString       interface{}
-	Timeout           time.Duration
-	ContentType       string
-	Accept            string
-	Host              string
-	UserAgent         string
-	Insecure          bool
-	MaxRedirects      int
-	RedirectHeaders   bool
-	Proxy             string
-	Compression       *compression
-	BasicAuthUsername string
-	BasicAuthPassword string
-	CookieJar         http.CookieJar
-	ShowDebug         bool
-	OnBeforeRequest   func(goreq *Request, httpreq *http.Request)
-}
-
-type compression struct {
-	writer          func(buffer io.Writer) (io.WriteCloser, error)
-	reader          func(buffer io.Reader) (io.ReadCloser, error)
-	ContentEncoding string
-}
-
-type Response struct {
-	*http.Response
-	Uri  string
-	Body *Body
-	req  *http.Request
-}
-
-func (r Response) CancelRequest() {
-	cancelRequest(DefaultTransport, r.req)
-
-}
-
-func cancelRequest(transport interface{}, r *http.Request) {
-	if tp, ok := transport.(transportRequestCanceler); ok {
-		tp.CancelRequest(r)
-	}
-}
-
-type headerTuple struct {
-	name  string
-	value string
-}
-
-type Body struct {
-	reader           io.ReadCloser
-	compressedReader io.ReadCloser
-}
-
-type Error struct {
-	timeout bool
-	Err     error
-}
-
-type transportRequestCanceler interface {
-	CancelRequest(*http.Request)
-}
-
-func (e *Error) Timeout() bool {
-	return e.timeout
-}
-
-func (e *Error) Error() string {
-	return e.Err.Error()
-}
-
-func (b *Body) Read(p []byte) (int, error) {
-	if b.compressedReader != nil {
-		return b.compressedReader.Read(p)
-	}
-	return b.reader.Read(p)
-}
-
-func (b *Body) Close() error {
-	err := b.reader.Close()
-	if b.compressedReader != nil {
-		return b.compressedReader.Close()
-	}
-	return err
-}
-
-func (b *Body) FromJsonTo(o interface{}) error {
-	return json.NewDecoder(b).Decode(o)
-}
-
-func (b *Body) ToString() (string, error) {
-	body, err := ioutil.ReadAll(b)
-	if err != nil {
-		return "", err
-	}
-	return string(body), nil
-}
-
-func Gzip() *compression {
-	reader := func(buffer io.Reader) (io.ReadCloser, error) {
-		return gzip.NewReader(buffer)
-	}
-	writer := func(buffer io.Writer) (io.WriteCloser, error) {
-		return gzip.NewWriter(buffer), nil
-	}
-	return &compression{writer: writer, reader: reader, ContentEncoding: "gzip"}
-}
-
-func Deflate() *compression {
-	reader := func(buffer io.Reader) (io.ReadCloser, error) {
-		return zlib.NewReader(buffer)
-	}
-	writer := func(buffer io.Writer) (io.WriteCloser, error) {
-		return zlib.NewWriter(buffer), nil
-	}
-	return &compression{writer: writer, reader: reader, ContentEncoding: "deflate"}
-}
-
-func Zlib() *compression {
-	return Deflate()
-}
-
-func paramParse(query interface{}) (string, error) {
-	switch query.(type) {
-	case url.Values:
-		return query.(url.Values).Encode(), nil
-	case *url.Values:
-		return query.(*url.Values).Encode(), nil
-	default:
-		var v = &url.Values{}
-		err := paramParseStruct(v, query)
-		return v.Encode(), err
-	}
-}
-
-func paramParseStruct(v *url.Values, query interface{}) error {
-	var (
-		s = reflect.ValueOf(query)
-		t = reflect.TypeOf(query)
-	)
-	for t.Kind() == reflect.Ptr || t.Kind() == reflect.Interface {
-		s = s.Elem()
-		t = s.Type()
-	}
-
-	if t.Kind() != reflect.Struct {
-		return errors.New("Can not parse QueryString.")
-	}
-
-	for i := 0; i < t.NumField(); i++ {
-		var name string
-
-		field := s.Field(i)
-		typeField := t.Field(i)
-
-		if !field.CanInterface() {
-			continue
-		}
-
-		urlTag := typeField.Tag.Get("url")
-		if urlTag == "-" {
-			continue
-		}
-
-		name, opts := parseTag(urlTag)
-
-		var omitEmpty, squash bool
-		omitEmpty = opts.Contains("omitempty")
-		squash = opts.Contains("squash")
-
-		if squash {
-			err := paramParseStruct(v, field.Interface())
-			if err != nil {
-				return err
-			}
-			continue
-		}
-
-		if urlTag == "" {
-			name = strings.ToLower(typeField.Name)
-		}
-
-		if val := fmt.Sprintf("%v", field.Interface()); !(omitEmpty && len(val) == 0) {
-			v.Add(name, val)
-		}
-	}
-	return nil
-}
-
-func prepareRequestBody(b interface{}) (io.Reader, error) {
-	switch b.(type) {
-	case string:
-		// treat is as text
-		return strings.NewReader(b.(string)), nil
-	case io.Reader:
-		// treat is as text
-		return b.(io.Reader), nil
-	case []byte:
-		//treat as byte array
-		return bytes.NewReader(b.([]byte)), nil
-	case nil:
-		return nil, nil
-	default:
-		// try to jsonify it
-		j, err := json.Marshal(b)
-		if err == nil {
-			return bytes.NewReader(j), nil
-		}
-		return nil, err
-	}
-}
-
-var DefaultDialer = &net.Dialer{Timeout: 1000 * time.Millisecond}
-var DefaultTransport http.RoundTripper = &http.Transport{Dial: DefaultDialer.Dial, Proxy: http.ProxyFromEnvironment}
-var DefaultClient = &http.Client{Transport: DefaultTransport}
-
-var proxyTransport http.RoundTripper
-var proxyClient *http.Client
-
-func SetConnectTimeout(duration time.Duration) {
-	DefaultDialer.Timeout = duration
-}
-
-func (r *Request) AddHeader(name string, value string) {
-	if r.headers == nil {
-		r.headers = []headerTuple{}
-	}
-	r.headers = append(r.headers, headerTuple{name: name, value: value})
-}
-
-func (r Request) WithHeader(name string, value string) Request {
-	r.AddHeader(name, value)
-	return r
-}
-
-func (r *Request) AddCookie(c *http.Cookie) {
-	r.cookies = append(r.cookies, c)
-}
-
-func (r Request) WithCookie(c *http.Cookie) Request {
-	r.AddCookie(c)
-	return r
-
-}
-
-func (r Request) Do() (*Response, error) {
-	var client = DefaultClient
-	var transport = DefaultTransport
-	var resUri string
-	var redirectFailed bool
-
-	r.Method = valueOrDefault(r.Method, "GET")
-
-	// use a client with a cookie jar if necessary. We create a new client not
-	// to modify the default one.
-	if r.CookieJar != nil {
-		client = &http.Client{
-			Transport: transport,
-			Jar:       r.CookieJar,
-		}
-	}
-
-	if r.Proxy != "" {
-		proxyUrl, err := url.Parse(r.Proxy)
-		if err != nil {
-			// proxy address is in a wrong format
-			return nil, &Error{Err: err}
-		}
-
-		//If jar is specified new client needs to be built
-		if proxyTransport == nil || client.Jar != nil {
-			proxyTransport = &http.Transport{Dial: DefaultDialer.Dial, Proxy: http.ProxyURL(proxyUrl)}
-			proxyClient = &http.Client{Transport: proxyTransport, Jar: client.Jar}
-		} else if proxyTransport, ok := proxyTransport.(*http.Transport); ok {
-			proxyTransport.Proxy = http.ProxyURL(proxyUrl)
-		}
-		transport = proxyTransport
-		client = proxyClient
-	}
-
-	client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
-
-		if len(via) > r.MaxRedirects {
-			redirectFailed = true
-			return errors.New("Error redirecting. MaxRedirects reached")
-		}
-
-		resUri = req.URL.String()
-
-		//By default Golang will not redirect request headers
-		// https://code.google.com/p/go/issues/detail?id=4800&q=request%20header
-		if r.RedirectHeaders {
-			for key, val := range via[0].Header {
-				req.Header[key] = val
-			}
-		}
-		return nil
-	}
-
-	if transport, ok := transport.(*http.Transport); ok {
-		if r.Insecure {
-			if transport.TLSClientConfig != nil {
-				transport.TLSClientConfig.InsecureSkipVerify = true
-			} else {
-				transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
-			}
-		} else if transport.TLSClientConfig != nil {
-			// the default TLS client (when transport.TLSClientConfig==nil) is
-			// already set to verify, so do nothing in that case
-			transport.TLSClientConfig.InsecureSkipVerify = false
-		}
-	}
-
-	req, err := r.NewRequest()
-
-	if err != nil {
-		// we couldn't parse the URL.
-		return nil, &Error{Err: err}
-	}
-
-	timeout := false
-	if r.Timeout > 0 {
-		client.Timeout = r.Timeout
-	}
-
-	if r.ShowDebug {
-		dump, err := httputil.DumpRequest(req, true)
-		if err != nil {
-			log.Println(err)
-		}
-		log.Println(string(dump))
-	}
-
-	if r.OnBeforeRequest != nil {
-		r.OnBeforeRequest(&r, req)
-	}
-	res, err := client.Do(req)
-
-	if err != nil {
-		if !timeout {
-			if t, ok := err.(itimeout); ok {
-				timeout = t.Timeout()
-			}
-			if ue, ok := err.(*url.Error); ok {
-				if t, ok := ue.Err.(itimeout); ok {
-					timeout = t.Timeout()
-				}
-			}
-		}
-
-		var response *Response
-		//If redirect fails we still want to return response data
-		if redirectFailed {
-			if res != nil {
-				response = &Response{res, resUri, &Body{reader: res.Body}, req}
-			} else {
-				response = &Response{res, resUri, nil, req}
-			}
-		}
-
-		//If redirect fails and we haven't set a redirect count we shouldn't return an error
-		if redirectFailed && r.MaxRedirects == 0 {
-			return response, nil
-		}
-
-		return response, &Error{timeout: timeout, Err: err}
-	}
-
-	if r.Compression != nil && strings.Contains(res.Header.Get("Content-Encoding"), r.Compression.ContentEncoding) {
-		compressedReader, err := r.Compression.reader(res.Body)
-		if err != nil {
-			return nil, &Error{Err: err}
-		}
-		return &Response{res, resUri, &Body{reader: res.Body, compressedReader: compressedReader}, req}, nil
-	}
-
-	return &Response{res, resUri, &Body{reader: res.Body}, req}, nil
-}
-
-func (r Request) addHeaders(headersMap http.Header) {
-	if len(r.UserAgent) > 0 {
-		headersMap.Add("User-Agent", r.UserAgent)
-	}
-	if r.Accept != "" {
-		headersMap.Add("Accept", r.Accept)
-	}
-	if r.ContentType != "" {
-		headersMap.Add("Content-Type", r.ContentType)
-	}
-}
-
-func (r Request) NewRequest() (*http.Request, error) {
-
-	b, e := prepareRequestBody(r.Body)
-	if e != nil {
-		// there was a problem marshaling the body
-		return nil, &Error{Err: e}
-	}
-
-	if r.QueryString != nil {
-		param, e := paramParse(r.QueryString)
-		if e != nil {
-			return nil, &Error{Err: e}
-		}
-		r.Uri = r.Uri + "?" + param
-	}
-
-	var bodyReader io.Reader
-	if b != nil && r.Compression != nil {
-		buffer := bytes.NewBuffer([]byte{})
-		readBuffer := bufio.NewReader(b)
-		writer, err := r.Compression.writer(buffer)
-		if err != nil {
-			return nil, &Error{Err: err}
-		}
-		_, e = readBuffer.WriteTo(writer)
-		writer.Close()
-		if e != nil {
-			return nil, &Error{Err: e}
-		}
-		bodyReader = buffer
-	} else {
-		bodyReader = b
-	}
-
-	req, err := http.NewRequest(r.Method, r.Uri, bodyReader)
-	if err != nil {
-		return nil, err
-	}
-	// add headers to the request
-	req.Host = r.Host
-
-	r.addHeaders(req.Header)
-	if r.Compression != nil {
-		req.Header.Add("Content-Encoding", r.Compression.ContentEncoding)
-		req.Header.Add("Accept-Encoding", r.Compression.ContentEncoding)
-	}
-	if r.headers != nil {
-		for _, header := range r.headers {
-			req.Header.Add(header.name, header.value)
-		}
-	}
-
-	//use basic auth if required
-	if r.BasicAuthUsername != "" {
-		req.SetBasicAuth(r.BasicAuthUsername, r.BasicAuthPassword)
-	}
-
-	for _, c := range r.cookies {
-		req.AddCookie(c)
-	}
-	return req, nil
-}
-
-// Return value if nonempty, def otherwise.
-func valueOrDefault(value, def string) string {
-	if value != "" {
-		return value
-	}
-	return def
-}

+ 0 - 64
vendor/github.com/franela/goreq/tags.go

@@ -1,64 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package goreq
-
-import (
-	"strings"
-	"unicode"
-)
-
-// tagOptions is the string following a comma in a struct field's "json"
-// tag, or the empty string. It does not include the leading comma.
-type tagOptions string
-
-// parseTag splits a struct field's json tag into its name and
-// comma-separated options.
-func parseTag(tag string) (string, tagOptions) {
-	if idx := strings.Index(tag, ","); idx != -1 {
-		return tag[:idx], tagOptions(tag[idx+1:])
-	}
-	return tag, tagOptions("")
-}
-
-// Contains reports whether a comma-separated list of options
-// contains a particular substr flag. substr must be surrounded by a
-// string boundary or commas.
-func (o tagOptions) Contains(optionName string) bool {
-	if len(o) == 0 {
-		return false
-	}
-	s := string(o)
-	for s != "" {
-		var next string
-		i := strings.Index(s, ",")
-		if i >= 0 {
-			s, next = s[:i], s[i+1:]
-		}
-		if s == optionName {
-			return true
-		}
-		s = next
-	}
-	return false
-}
-
-func isValidTag(s string) bool {
-	if s == "" {
-		return false
-	}
-	for _, c := range s {
-		switch {
-		case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
-			// Backslash and quote chars are reserved, but
-			// otherwise any punctuation chars are allowed
-			// in a tag name.
-		default:
-			if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
-				return false
-			}
-		}
-	}
-	return true
-}