mirror of https://github.com/dexidp/dex.git
33 changed files with 628 additions and 1105 deletions
@ -0,0 +1,254 @@
|
||||
package mailgun |
||||
|
||||
import ( |
||||
"bytes" |
||||
"encoding/json" |
||||
"io" |
||||
"io/ioutil" |
||||
"mime/multipart" |
||||
"net/http" |
||||
"net/url" |
||||
"os" |
||||
"path" |
||||
) |
||||
|
||||
type httpRequest struct { |
||||
URL string |
||||
Parameters map[string][]string |
||||
Headers map[string]string |
||||
BasicAuthUser string |
||||
BasicAuthPassword string |
||||
Client *http.Client |
||||
} |
||||
|
||||
type httpResponse struct { |
||||
Code int |
||||
Data []byte |
||||
} |
||||
|
||||
type payload interface { |
||||
getPayloadBuffer() (*bytes.Buffer, error) |
||||
getContentType() string |
||||
} |
||||
|
||||
type keyValuePair struct { |
||||
key string |
||||
value string |
||||
} |
||||
|
||||
type keyNameRC struct { |
||||
key string |
||||
name string |
||||
value io.ReadCloser |
||||
} |
||||
|
||||
type formDataPayload struct { |
||||
contentType string |
||||
Values []keyValuePair |
||||
Files []keyValuePair |
||||
ReadClosers []keyNameRC |
||||
} |
||||
|
||||
type urlEncodedPayload struct { |
||||
Values []keyValuePair |
||||
} |
||||
|
||||
func newHTTPRequest(url string) *httpRequest { |
||||
return &httpRequest{URL: url, Client: http.DefaultClient} |
||||
} |
||||
|
||||
func (r *httpRequest) addParameter(name, value string) { |
||||
if r.Parameters == nil { |
||||
r.Parameters = make(map[string][]string) |
||||
} |
||||
r.Parameters[name] = append(r.Parameters[name], value) |
||||
} |
||||
|
||||
func (r *httpRequest) setClient(c *http.Client) { |
||||
r.Client = c |
||||
} |
||||
|
||||
func (r *httpRequest) setBasicAuth(user, password string) { |
||||
r.BasicAuthUser = user |
||||
r.BasicAuthPassword = password |
||||
} |
||||
|
||||
func newUrlEncodedPayload() *urlEncodedPayload { |
||||
return &urlEncodedPayload{} |
||||
} |
||||
|
||||
func (f *urlEncodedPayload) addValue(key, value string) { |
||||
f.Values = append(f.Values, keyValuePair{key: key, value: value}) |
||||
} |
||||
|
||||
func (f *urlEncodedPayload) getPayloadBuffer() (*bytes.Buffer, error) { |
||||
data := url.Values{} |
||||
for _, keyVal := range f.Values { |
||||
data.Add(keyVal.key, keyVal.value) |
||||
} |
||||
return bytes.NewBufferString(data.Encode()), nil |
||||
} |
||||
|
||||
func (f *urlEncodedPayload) getContentType() string { |
||||
return "application/x-www-form-urlencoded" |
||||
} |
||||
|
||||
func (r *httpResponse) parseFromJSON(v interface{}) error { |
||||
return json.Unmarshal(r.Data, v) |
||||
} |
||||
|
||||
func newFormDataPayload() *formDataPayload { |
||||
return &formDataPayload{} |
||||
} |
||||
|
||||
func (f *formDataPayload) addValue(key, value string) { |
||||
f.Values = append(f.Values, keyValuePair{key: key, value: value}) |
||||
} |
||||
|
||||
func (f *formDataPayload) addFile(key, file string) { |
||||
f.Files = append(f.Files, keyValuePair{key: key, value: file}) |
||||
} |
||||
|
||||
func (f *formDataPayload) addReadCloser(key, name string, rc io.ReadCloser) { |
||||
f.ReadClosers = append(f.ReadClosers, keyNameRC{key: key, name: name, value: rc}) |
||||
} |
||||
|
||||
func (f *formDataPayload) getPayloadBuffer() (*bytes.Buffer, error) { |
||||
data := &bytes.Buffer{} |
||||
writer := multipart.NewWriter(data) |
||||
defer writer.Close() |
||||
|
||||
for _, keyVal := range f.Values { |
||||
if tmp, err := writer.CreateFormField(keyVal.key); err == nil { |
||||
tmp.Write([]byte(keyVal.value)) |
||||
} else { |
||||
return nil, err |
||||
} |
||||
} |
||||
|
||||
for _, file := range f.Files { |
||||
if tmp, err := writer.CreateFormFile(file.key, path.Base(file.value)); err == nil { |
||||
if fp, err := os.Open(file.value); err == nil { |
||||
defer fp.Close() |
||||
io.Copy(tmp, fp) |
||||
} else { |
||||
return nil, err |
||||
} |
||||
} else { |
||||
return nil, err |
||||
} |
||||
} |
||||
|
||||
for _, file := range f.ReadClosers { |
||||
if tmp, err := writer.CreateFormFile(file.key, file.name); err == nil { |
||||
defer file.value.Close() |
||||
io.Copy(tmp, file.value) |
||||
} else { |
||||
return nil, err |
||||
} |
||||
} |
||||
|
||||
f.contentType = writer.FormDataContentType() |
||||
|
||||
return data, nil |
||||
} |
||||
|
||||
func (f *formDataPayload) getContentType() string { |
||||
if f.contentType == "" { |
||||
f.getPayloadBuffer() |
||||
} |
||||
return f.contentType |
||||
} |
||||
|
||||
func (r *httpRequest) addHeader(name, value string) { |
||||
if r.Headers == nil { |
||||
r.Headers = make(map[string]string) |
||||
} |
||||
r.Headers[name] = value |
||||
} |
||||
|
||||
func (r *httpRequest) makeGetRequest() (*httpResponse, error) { |
||||
return r.makeRequest("GET", nil) |
||||
} |
||||
|
||||
func (r *httpRequest) makePostRequest(payload payload) (*httpResponse, error) { |
||||
return r.makeRequest("POST", payload) |
||||
} |
||||
|
||||
func (r *httpRequest) makePutRequest(payload payload) (*httpResponse, error) { |
||||
return r.makeRequest("PUT", payload) |
||||
} |
||||
|
||||
func (r *httpRequest) makeDeleteRequest() (*httpResponse, error) { |
||||
return r.makeRequest("DELETE", nil) |
||||
} |
||||
|
||||
func (r *httpRequest) makeRequest(method string, payload payload) (*httpResponse, error) { |
||||
url, err := r.generateUrlWithParameters() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
var body io.Reader |
||||
if payload != nil { |
||||
if body, err = payload.getPayloadBuffer(); err != nil { |
||||
return nil, err |
||||
} |
||||
} else { |
||||
body = nil |
||||
} |
||||
|
||||
req, err := http.NewRequest(method, url, body) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if payload != nil && payload.getContentType() != "" { |
||||
req.Header.Add("Content-Type", payload.getContentType()) |
||||
} |
||||
|
||||
if r.BasicAuthUser != "" && r.BasicAuthPassword != "" { |
||||
req.SetBasicAuth(r.BasicAuthUser, r.BasicAuthPassword) |
||||
} |
||||
|
||||
for header, value := range r.Headers { |
||||
req.Header.Add(header, value) |
||||
} |
||||
|
||||
response := httpResponse{} |
||||
|
||||
resp, err := r.Client.Do(req) |
||||
if resp != nil { |
||||
response.Code = resp.StatusCode |
||||
} |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
defer resp.Body.Close() |
||||
responseBody, err := ioutil.ReadAll(resp.Body) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
response.Data = responseBody |
||||
return &response, nil |
||||
} |
||||
|
||||
func (r *httpRequest) generateUrlWithParameters() (string, error) { |
||||
url, err := url.Parse(r.URL) |
||||
if err != nil { |
||||
return "", err |
||||
} |
||||
q := url.Query() |
||||
if r.Parameters != nil && len(r.Parameters) > 0 { |
||||
for name, values := range r.Parameters { |
||||
for _, value := range values { |
||||
q.Add(name, value) |
||||
} |
||||
} |
||||
} |
||||
url.RawQuery = q.Encode() |
||||
|
||||
return url.String(), nil |
||||
} |
||||
@ -1 +0,0 @@
|
||||
desktop.ini |
||||
@ -1,11 +0,0 @@
|
||||
language: go |
||||
go: |
||||
- 1.3 |
||||
- 1.4 |
||||
env: |
||||
- GOARCH=amd64 |
||||
- GOARCH=386 |
||||
script: |
||||
- go get github.com/mbanzon/callbackenv |
||||
- go get github.com/mbanzon/dummyserver |
||||
- go test |
||||
@ -1,27 +0,0 @@
|
||||
Copyright (c) 2013-2014, Michael Banzon |
||||
All rights reserved. |
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, |
||||
are permitted provided that the following conditions are met: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this |
||||
list of conditions and the following disclaimer. |
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this |
||||
list of conditions and the following disclaimer in the documentation and/or |
||||
other materials provided with the distribution. |
||||
|
||||
* Neither the name of the {organization} nor the names of its |
||||
contributors may be used to endorse or promote products derived from |
||||
this software without specific prior written permission. |
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
@ -1,15 +0,0 @@
|
||||
simplehttp |
||||
========== |
||||
|
||||
[](https://travis-ci.org/mbanzon/simplehttp) |
||||
|
||||
Simple HTTP library for Go. |
||||
|
||||
This small library adds some utility functions for doing HTTP request and easilly gettings results as |
||||
structs from JSON and XML. |
||||
|
||||
Supports alternative `http.Client` instances to support use on Google App Engine. |
||||
|
||||
Examples are coming soon. |
||||
|
||||
The code is released under a 3-clause BSD license. See the LICENSE file for more information. |
||||
@ -1,17 +0,0 @@
|
||||
package simplehttp |
||||
|
||||
func (r *HTTPRequest) GetResponseFromJSON(v interface{}) error { |
||||
response, err := r.MakeGetRequest() |
||||
if err != nil { |
||||
return err |
||||
} |
||||
return response.ParseFromJSON(v) |
||||
} |
||||
|
||||
func (r *HTTPRequest) PostResponseFromJSON(payload Payload, v interface{}) error { |
||||
response, err := r.MakePostRequest(payload) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
return response.ParseFromJSON(v) |
||||
} |
||||
@ -1,133 +0,0 @@
|
||||
package simplehttp |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"encoding/xml" |
||||
"testing" |
||||
) |
||||
|
||||
func TestParsingGetFromJson(t *testing.T) { |
||||
tmp := testStruct{ |
||||
Value1: "1", |
||||
Value2: "2", |
||||
Value3: "3", |
||||
} |
||||
|
||||
data, err := json.Marshal(tmp) |
||||
if err != nil { |
||||
t.Fail() |
||||
} |
||||
|
||||
server.SetNextResponse(data) |
||||
|
||||
request := NewHTTPRequest(dummyurl) |
||||
var retVal testStruct |
||||
err = request.GetResponseFromJSON(&retVal) |
||||
|
||||
if err != nil { |
||||
t.Fail() |
||||
} |
||||
|
||||
if tmp.Value1 != retVal.Value1 { |
||||
t.Fail() |
||||
} |
||||
|
||||
if tmp.Value2 != retVal.Value2 { |
||||
t.Fail() |
||||
} |
||||
|
||||
if tmp.Value3 != retVal.Value3 { |
||||
t.Fail() |
||||
} |
||||
} |
||||
|
||||
func TestFailingParsingGetFromJson(t *testing.T) { |
||||
request := NewHTTPRequest(invalidurl) |
||||
var retVal testStruct |
||||
err := request.GetResponseFromJSON(&retVal) |
||||
|
||||
if err == nil { |
||||
t.Fail() |
||||
} |
||||
} |
||||
|
||||
func TestParsingPostFromJson(t *testing.T) { |
||||
tmp := testStruct{ |
||||
Value1: "1", |
||||
Value2: "2", |
||||
Value3: "3", |
||||
} |
||||
|
||||
data, err := json.Marshal(tmp) |
||||
if err != nil { |
||||
t.Fail() |
||||
} |
||||
|
||||
server.SetNextResponse(data) |
||||
|
||||
request := NewHTTPRequest(dummyurl) |
||||
var retVal testStruct |
||||
err = request.PostResponseFromJSON(nil, &retVal) |
||||
|
||||
if err != nil { |
||||
t.Fail() |
||||
} |
||||
|
||||
if tmp.Value1 != retVal.Value1 { |
||||
t.Fail() |
||||
} |
||||
|
||||
if tmp.Value2 != retVal.Value2 { |
||||
t.Fail() |
||||
} |
||||
|
||||
if tmp.Value3 != retVal.Value3 { |
||||
t.Fail() |
||||
} |
||||
} |
||||
|
||||
func TestFailingParsingPostFromJson(t *testing.T) { |
||||
request := NewHTTPRequest(invalidurl) |
||||
var retVal testStruct |
||||
err := request.PostResponseFromJSON(nil, &retVal) |
||||
|
||||
if err == nil { |
||||
t.Fail() |
||||
} |
||||
} |
||||
|
||||
func TestParsingGetFromXml(t *testing.T) { |
||||
tmp := testStruct{ |
||||
Value1: "1", |
||||
Value2: "2", |
||||
Value3: "3", |
||||
} |
||||
|
||||
data, err := xml.Marshal(tmp) |
||||
if err != nil { |
||||
t.Fail() |
||||
} |
||||
|
||||
server.SetNextResponse(data) |
||||
|
||||
request := NewHTTPRequest(dummyurl) |
||||
var retVal testStruct |
||||
response, err := request.MakeGetRequest() |
||||
response.ParseFromXML(&retVal) |
||||
|
||||
if err != nil { |
||||
t.Fail() |
||||
} |
||||
|
||||
if tmp.Value1 != retVal.Value1 { |
||||
t.Fail() |
||||
} |
||||
|
||||
if tmp.Value2 != retVal.Value2 { |
||||
t.Fail() |
||||
} |
||||
|
||||
if tmp.Value3 != retVal.Value3 { |
||||
t.Fail() |
||||
} |
||||
} |
||||
@ -1,31 +0,0 @@
|
||||
package simplehttp |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"net/http" |
||||
) |
||||
|
||||
func GetJSONInput(r *http.Request, w http.ResponseWriter, v interface{}) (err error) { |
||||
decoder := json.NewDecoder(r.Body) |
||||
err = decoder.Decode(v) |
||||
if err != nil { |
||||
http.Error(w, "Bad request.", http.StatusBadRequest) |
||||
return err |
||||
} |
||||
|
||||
return nil |
||||
} |
||||
|
||||
func OutputJSON(w http.ResponseWriter, v interface{}) (err error) { |
||||
var data []byte |
||||
data, err = json.Marshal(v) |
||||
if err != nil { |
||||
http.Error(w, "Internal error.", http.StatusInternalServerError) |
||||
return err |
||||
} |
||||
|
||||
w.Header().Add("Content-Type", "application/json") |
||||
_, err = w.Write(data) |
||||
|
||||
return nil |
||||
} |
||||
@ -1,15 +0,0 @@
|
||||
package simplehttp |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"encoding/xml" |
||||
) |
||||
|
||||
// Parses the HTTPResponse as JSON to the given interface.
|
||||
func (r *HTTPResponse) ParseFromJSON(v interface{}) error { |
||||
return json.Unmarshal(r.Data, v) |
||||
} |
||||
|
||||
func (r *HTTPResponse) ParseFromXML(v interface{}) error { |
||||
return xml.Unmarshal(r.Data, v) |
||||
} |
||||
@ -1,38 +0,0 @@
|
||||
package simplehttp |
||||
|
||||
import ( |
||||
"bytes" |
||||
"github.com/mbanzon/callbackenv" |
||||
"io/ioutil" |
||||
"testing" |
||||
) |
||||
|
||||
const ( |
||||
FILE_ENV = "SIMPLEHTTP_TEST_FILE" |
||||
) |
||||
|
||||
func TestFormDataPayloadPost(t *testing.T) { |
||||
payload := NewFormDataPayload() |
||||
payload.AddValue("key", "value") |
||||
|
||||
buf := &bytes.Buffer{} |
||||
buf.Write([]byte("testing testing testing")) |
||||
|
||||
rc := ioutil.NopCloser(buf) |
||||
payload.AddReadCloser("foo", "bar", rc) |
||||
|
||||
callbackenv.RequireEnv(FILE_ENV, |
||||
func(file string) { |
||||
payload.AddFile("file", file) |
||||
}, nil) |
||||
|
||||
request := NewHTTPRequest(dummyurl) |
||||
request.MakePostRequest(payload) |
||||
} |
||||
|
||||
func TestUrlEncodedPayloadPost(t *testing.T) { |
||||
payload := NewUrlEncodedPayload() |
||||
payload.AddValue("key", "value") |
||||
request := NewHTTPRequest(dummyurl) |
||||
request.MakePostRequest(payload) |
||||
} |
||||
@ -1,141 +0,0 @@
|
||||
package simplehttp |
||||
|
||||
import ( |
||||
"bytes" |
||||
"io" |
||||
"mime/multipart" |
||||
"net/url" |
||||
"os" |
||||
"path" |
||||
) |
||||
|
||||
type keyValuePair struct { |
||||
key string |
||||
value string |
||||
} |
||||
|
||||
type keyNameRC struct { |
||||
key string |
||||
name string |
||||
value io.ReadCloser |
||||
} |
||||
|
||||
type Payload interface { |
||||
GetPayloadBuffer() (*bytes.Buffer, error) |
||||
GetContentType() string |
||||
} |
||||
|
||||
type RawPayload struct { |
||||
Data []byte |
||||
} |
||||
|
||||
type FormDataPayload struct { |
||||
contentType string |
||||
Values []keyValuePair |
||||
Files []keyValuePair |
||||
ReadClosers []keyNameRC |
||||
} |
||||
|
||||
type UrlEncodedPayload struct { |
||||
Values []keyValuePair |
||||
} |
||||
|
||||
func NewRawPayload(data []byte) *RawPayload { |
||||
return &RawPayload{Data: data} |
||||
} |
||||
|
||||
func (r *RawPayload) GetPayloadBuffer() (*bytes.Buffer, error) { |
||||
data := &bytes.Buffer{} |
||||
c, err := data.Write(r.Data) |
||||
if c != len(r.Data) || err != nil { |
||||
return data, err |
||||
} |
||||
return data, nil |
||||
} |
||||
|
||||
func (r *RawPayload) GetContentType() string { |
||||
return "" |
||||
} |
||||
|
||||
func NewFormDataPayload() *FormDataPayload { |
||||
return &FormDataPayload{} |
||||
} |
||||
|
||||
func (f *FormDataPayload) AddValue(key, value string) { |
||||
f.Values = append(f.Values, keyValuePair{key: key, value: value}) |
||||
} |
||||
|
||||
func (f *FormDataPayload) AddFile(key, file string) { |
||||
f.Files = append(f.Files, keyValuePair{key: key, value: file}) |
||||
} |
||||
|
||||
func (f *FormDataPayload) AddReadCloser(key, name string, rc io.ReadCloser) { |
||||
f.ReadClosers = append(f.ReadClosers, keyNameRC{key: key, name: name, value: rc}) |
||||
} |
||||
|
||||
func (f *FormDataPayload) GetPayloadBuffer() (*bytes.Buffer, error) { |
||||
data := &bytes.Buffer{} |
||||
writer := multipart.NewWriter(data) |
||||
defer writer.Close() |
||||
|
||||
for _, keyVal := range f.Values { |
||||
if tmp, err := writer.CreateFormField(keyVal.key); err == nil { |
||||
tmp.Write([]byte(keyVal.value)) |
||||
} else { |
||||
return nil, err |
||||
} |
||||
} |
||||
|
||||
for _, file := range f.Files { |
||||
if tmp, err := writer.CreateFormFile(file.key, path.Base(file.value)); err == nil { |
||||
if fp, err := os.Open(file.value); err == nil { |
||||
defer fp.Close() |
||||
io.Copy(tmp, fp) |
||||
} else { |
||||
return nil, err |
||||
} |
||||
} else { |
||||
return nil, err |
||||
} |
||||
} |
||||
|
||||
for _, file := range f.ReadClosers { |
||||
if tmp, err := writer.CreateFormFile(file.key, file.name); err == nil { |
||||
defer file.value.Close() |
||||
io.Copy(tmp, file.value) |
||||
} else { |
||||
return nil, err |
||||
} |
||||
} |
||||
|
||||
f.contentType = writer.FormDataContentType() |
||||
|
||||
return data, nil |
||||
} |
||||
|
||||
func (f *FormDataPayload) GetContentType() string { |
||||
if f.contentType == "" { |
||||
f.GetPayloadBuffer() |
||||
} |
||||
return f.contentType |
||||
} |
||||
|
||||
func NewUrlEncodedPayload() *UrlEncodedPayload { |
||||
return &UrlEncodedPayload{} |
||||
} |
||||
|
||||
func (f *UrlEncodedPayload) AddValue(key, value string) { |
||||
f.Values = append(f.Values, keyValuePair{key: key, value: value}) |
||||
} |
||||
|
||||
func (f *UrlEncodedPayload) GetPayloadBuffer() (*bytes.Buffer, error) { |
||||
data := url.Values{} |
||||
for _, keyVal := range f.Values { |
||||
data.Add(keyVal.key, keyVal.value) |
||||
} |
||||
return bytes.NewBufferString(data.Encode()), nil |
||||
} |
||||
|
||||
func (f *UrlEncodedPayload) GetContentType() string { |
||||
return "application/x-www-form-urlencoded" |
||||
} |
||||
@ -1,74 +0,0 @@
|
||||
package simplehttp |
||||
|
||||
// Type to encapsulate basic authentication for requests.
|
||||
type BasicAuthentication struct { |
||||
User string |
||||
Password string |
||||
} |
||||
|
||||
// Type to wrap requests.
|
||||
type Request struct { |
||||
Url string |
||||
Authentication BasicAuthentication |
||||
UserAgent string |
||||
Data []byte |
||||
} |
||||
|
||||
func createHttpRequest(req Request) *HTTPRequest { |
||||
r := NewHTTPRequest(req.Url) |
||||
if req.Authentication.User != "" { |
||||
r.SetBasicAuth(req.Authentication.User, req.Authentication.Password) |
||||
} |
||||
if req.UserAgent != "" { |
||||
r.AddHeader("User-Agent", req.UserAgent) |
||||
} |
||||
return r |
||||
} |
||||
|
||||
func (r Request) Get() (int, []byte, error) { |
||||
req := createHttpRequest(r) |
||||
res, err := req.MakeGetRequest() |
||||
if err == nil { |
||||
return res.Code, res.Data, err |
||||
} else { |
||||
return -1, nil, err |
||||
} |
||||
} |
||||
|
||||
func (r Request) Post() (int, []byte, error) { |
||||
req := createHttpRequest(r) |
||||
var payload Payload = nil |
||||
if r.Data != nil { |
||||
payload = NewRawPayload(r.Data) |
||||
} |
||||
res, err := req.MakePostRequest(payload) |
||||
if err == nil { |
||||
return res.Code, res.Data, err |
||||
} else { |
||||
return -1, nil, err |
||||
} |
||||
} |
||||
|
||||
func (r Request) Put() (int, []byte, error) { |
||||
req := createHttpRequest(r) |
||||
var payload Payload = nil |
||||
if r.Data != nil { |
||||
payload = NewRawPayload(r.Data) |
||||
} |
||||
res, err := req.MakePutRequest(payload) |
||||
if err == nil { |
||||
return res.Code, res.Data, err |
||||
} else { |
||||
return -1, nil, err |
||||
} |
||||
} |
||||
|
||||
func (r Request) Delete() (int, []byte, error) { |
||||
req := createHttpRequest(r) |
||||
res, err := req.MakeDeleteRequest() |
||||
if err == nil { |
||||
return res.Code, res.Data, err |
||||
} else { |
||||
return -1, nil, err |
||||
} |
||||
} |
||||
@ -1,104 +0,0 @@
|
||||
package simplehttp |
||||
|
||||
import ( |
||||
"testing" |
||||
) |
||||
|
||||
func TestShorthandFailingPayload(t *testing.T) { |
||||
Request{ |
||||
Url: dummyurl, |
||||
Data: nil, |
||||
}.Post() |
||||
} |
||||
|
||||
func TestShorthandGet(t *testing.T) { |
||||
code, _, err := Request{ |
||||
Url: dummyurl, |
||||
UserAgent: "simplehttp go test", |
||||
}.Get() |
||||
|
||||
if code == -1 || err != nil { |
||||
t.Fail() |
||||
} |
||||
} |
||||
|
||||
func TestShorthandPost(t *testing.T) { |
||||
code, _, err := Request{ |
||||
Url: dummyurl, |
||||
Data: []byte("foobar"), |
||||
UserAgent: "simplehttp go test", |
||||
Authentication: BasicAuthentication{ |
||||
User: "test", |
||||
Password: "test", |
||||
}, |
||||
}.Post() |
||||
|
||||
if code == -1 || err != nil { |
||||
t.Fail() |
||||
} |
||||
} |
||||
|
||||
func TestShorthandPut(t *testing.T) { |
||||
code, _, err := Request{ |
||||
Url: dummyurl, |
||||
Data: []byte("foobar"), |
||||
UserAgent: "simplehttp go test", |
||||
}.Put() |
||||
|
||||
if code == -1 || err != nil { |
||||
t.Fail() |
||||
} |
||||
} |
||||
|
||||
func TestShorthandDelete(t *testing.T) { |
||||
code, _, err := Request{ |
||||
Url: dummyurl, |
||||
UserAgent: "simplehttp go test", |
||||
}.Delete() |
||||
|
||||
if code == -1 || err != nil { |
||||
t.Fail() |
||||
} |
||||
} |
||||
|
||||
func TestFailingShorthandGet(t *testing.T) { |
||||
code, _, err := Request{ |
||||
Url: invalidurl, |
||||
}.Get() |
||||
|
||||
if code != -1 || err == nil { |
||||
t.Fail() |
||||
} |
||||
} |
||||
|
||||
func TestFailingShorthandPost(t *testing.T) { |
||||
code, _, err := Request{ |
||||
Url: invalidurl, |
||||
Data: []byte("foobar"), |
||||
}.Post() |
||||
|
||||
if code != -1 || err == nil { |
||||
t.Fail() |
||||
} |
||||
} |
||||
|
||||
func TestFailingShorthandPut(t *testing.T) { |
||||
code, _, err := Request{ |
||||
Url: invalidurl, |
||||
Data: []byte("foobar"), |
||||
}.Put() |
||||
|
||||
if code != -1 || err == nil { |
||||
t.Fail() |
||||
} |
||||
} |
||||
|
||||
func TestFailingShorthandDelete(t *testing.T) { |
||||
code, _, err := Request{ |
||||
Url: invalidurl, |
||||
}.Delete() |
||||
|
||||
if code != -1 || err == nil { |
||||
t.Fail() |
||||
} |
||||
} |
||||
@ -1,147 +0,0 @@
|
||||
// Package simplehttp provides some simple methods and types to do
|
||||
// HTTP queries with form values and parameters easily - especially
|
||||
// if the returned result is expected to be JSON or XML.
|
||||
//
|
||||
// Author: Michael Banzon
|
||||
package simplehttp |
||||
|
||||
import ( |
||||
"io" |
||||
"io/ioutil" |
||||
"net/http" |
||||
"net/url" |
||||
) |
||||
|
||||
// Holds all information used to make a HTTP request.
|
||||
type HTTPRequest struct { |
||||
URL string |
||||
Parameters map[string][]string |
||||
Headers map[string]string |
||||
BasicAuthUser string |
||||
BasicAuthPassword string |
||||
Client *http.Client |
||||
} |
||||
|
||||
type HTTPResponse struct { |
||||
Code int |
||||
Data []byte |
||||
} |
||||
|
||||
// Creates a new HTTPRequest instance.
|
||||
func NewHTTPRequest(url string) *HTTPRequest { |
||||
return &HTTPRequest{URL: url, Client: http.DefaultClient} |
||||
} |
||||
|
||||
// Adds a parameter to the generated query string.
|
||||
func (r *HTTPRequest) AddParameter(name, value string) { |
||||
if r.Parameters == nil { |
||||
r.Parameters = make(map[string][]string) |
||||
} |
||||
r.Parameters[name] = append(r.Parameters[name], value) |
||||
} |
||||
|
||||
// Adds a header that will be sent with the HTTP request.
|
||||
func (r *HTTPRequest) AddHeader(name, value string) { |
||||
// hej
|
||||
if r.Headers == nil { |
||||
r.Headers = make(map[string]string) |
||||
} |
||||
r.Headers[name] = value |
||||
} |
||||
|
||||
// Sets username and password for basic authentication.
|
||||
func (r *HTTPRequest) SetBasicAuth(user, password string) { |
||||
r.BasicAuthUser = user |
||||
r.BasicAuthPassword = password |
||||
} |
||||
|
||||
func (r *HTTPRequest) MakeGetRequest() (*HTTPResponse, error) { |
||||
return r.MakeRequest("GET", nil) |
||||
} |
||||
|
||||
func (r *HTTPRequest) MakePostRequest(payload Payload) (*HTTPResponse, error) { |
||||
return r.MakeRequest("POST", payload) |
||||
} |
||||
|
||||
func (r *HTTPRequest) MakePutRequest(payload Payload) (*HTTPResponse, error) { |
||||
return r.MakeRequest("PUT", payload) |
||||
} |
||||
|
||||
func (r *HTTPRequest) MakeDeleteRequest() (*HTTPResponse, error) { |
||||
return r.MakeRequest("DELETE", nil) |
||||
} |
||||
|
||||
func (r *HTTPRequest) MakeRequest(method string, payload Payload) (*HTTPResponse, error) { |
||||
url, err := r.generateUrlWithParameters() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
var body io.Reader |
||||
if payload != nil { |
||||
if body, err = payload.GetPayloadBuffer(); err != nil { |
||||
return nil, err |
||||
} |
||||
} else { |
||||
body = nil |
||||
} |
||||
|
||||
req, err := http.NewRequest(method, url, body) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if payload != nil && payload.GetContentType() != "" { |
||||
req.Header.Add("Content-Type", payload.GetContentType()) |
||||
} |
||||
|
||||
if r.BasicAuthUser != "" && r.BasicAuthPassword != "" { |
||||
req.SetBasicAuth(r.BasicAuthUser, r.BasicAuthPassword) |
||||
} |
||||
|
||||
for header, value := range r.Headers { |
||||
req.Header.Add(header, value) |
||||
} |
||||
|
||||
response := HTTPResponse{} |
||||
|
||||
resp, err := r.Client.Do(req) |
||||
if resp != nil { |
||||
response.Code = resp.StatusCode |
||||
} |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
defer resp.Body.Close() |
||||
responseBody, err := ioutil.ReadAll(resp.Body) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
response.Data = responseBody |
||||
return &response, nil |
||||
} |
||||
|
||||
// Generates the complete URL using GET parameters.
|
||||
func (r *HTTPRequest) generateUrlWithParameters() (string, error) { |
||||
url, err := url.Parse(r.URL) |
||||
if err != nil { |
||||
return "", err |
||||
} |
||||
q := url.Query() |
||||
if r.Parameters != nil && len(r.Parameters) > 0 { |
||||
for name, values := range r.Parameters { |
||||
for _, value := range values { |
||||
q.Add(name, value) |
||||
} |
||||
} |
||||
} |
||||
url.RawQuery = q.Encode() |
||||
|
||||
return url.String(), nil |
||||
} |
||||
|
||||
func (r *HTTPRequest) SetClient(c *http.Client) { |
||||
r.Client = c |
||||
} |
||||
@ -1,37 +0,0 @@
|
||||
package simplehttp |
||||
|
||||
import ( |
||||
"github.com/mbanzon/dummyserver" |
||||
"log" |
||||
"strconv" |
||||
"testing" |
||||
) |
||||
|
||||
var ( |
||||
server *dummyserver.DummyServer |
||||
dummyurl string |
||||
invalidurl string |
||||
) |
||||
|
||||
type testStruct struct { |
||||
Value1 string `json:"value1" xml:"value1"` |
||||
Value2 string `json:"value2" xml:"value2"` |
||||
Value3 string `json:"value3" xml:"value3"` |
||||
} |
||||
|
||||
func init() { |
||||
server = dummyserver.NewRandomServer() |
||||
go func() { |
||||
err := server.Start() |
||||
log.Fatal(err) |
||||
}() |
||||
dummyurl = "http://localhost:" + strconv.Itoa(server.GetPort()) + "/" |
||||
invalidurl = "invalid://invalid" |
||||
} |
||||
|
||||
func TestAddParameters(t *testing.T) { |
||||
request := NewHTTPRequest(dummyurl) |
||||
request.AddParameter("p1", "v1") |
||||
|
||||
request.MakeGetRequest() |
||||
} |
||||
Loading…
Reference in new issue