2017-12-10 19:17:09 +00:00
package request
import (
"bytes"
"encoding/json"
"io"
"net/http"
"net/http/cookiejar"
"net/url"
"github.com/pkg/errors"
2018-09-18 18:02:21 +00:00
"golang.org/x/net/publicsuffix"
2017-12-10 19:17:09 +00:00
)
type Client struct {
BaseURL * url . URL
2018-09-17 04:44:41 +00:00
BaseHttpHeader * http . Header
HttpClient * http . Client
2017-12-10 19:17:09 +00:00
}
func NewClient ( baseurl string ) ( * Client , error ) {
var err error
var jar * cookiejar . Jar
2018-09-18 18:02:21 +00:00
options := cookiejar . Options { PublicSuffixList : publicsuffix . List }
2017-12-10 19:17:09 +00:00
if jar , err = cookiejar . New ( & options ) ; err != nil {
return nil , errors . Wrap ( err , "failed to create client object" )
}
var u * url . URL
if u , err = url . Parse ( baseurl ) ; err != nil {
return nil , errors . Wrap ( err , "failed to create client object" )
}
header := make ( http . Header )
2018-09-19 19:12:06 +00:00
header . Set ( "User-Agent" , "Mozilla/5.0 (iPhone; CPU iPhone OS 11_1_2 like Mac OS X) AppleWebKit/604.3.5 (KHTML, like Gecko) Mobile/15B202 NETGEAR/v1 (iOS Vuezone)" )
header . Set ( "Content-Type" , "application/json" )
header . Set ( "Accept" , "application/json" )
2017-12-10 19:17:09 +00:00
return & Client {
BaseURL : u ,
2018-09-17 04:44:41 +00:00
BaseHttpHeader : & header ,
HttpClient : & http . Client { Jar : jar } ,
2017-12-10 19:17:09 +00:00
} , nil
}
func ( c * Client ) Get ( uri string , header http . Header ) ( * Response , error ) {
req , err := c . newRequest ( "GET" , uri , nil , header )
if err != nil {
return nil , errors . WithMessage ( err , "get request " + uri + " failed" )
}
return c . do ( req )
}
func ( c * Client ) Post ( uri string , body interface { } , header http . Header ) ( * Response , error ) {
req , err := c . newRequest ( "POST" , uri , body , header )
if err != nil {
return nil , errors . WithMessage ( err , "post request " + uri + " failed" )
}
return c . do ( req )
}
func ( c * Client ) Put ( uri string , body interface { } , header http . Header ) ( * Response , error ) {
req , err := c . newRequest ( "PUT" , uri , body , header )
if err != nil {
return nil , errors . WithMessage ( err , "put request " + uri + " failed" )
}
return c . do ( req )
}
func ( c * Client ) newRequest ( method string , uri string , body interface { } , header http . Header ) ( * Request , error ) {
var buf io . ReadWriter
if body != nil {
buf = new ( bytes . Buffer )
err := json . NewEncoder ( buf ) . Encode ( body )
if err != nil {
return nil , errors . Wrap ( err , "failed to create request object" )
}
}
2018-09-18 18:02:21 +00:00
2017-12-10 19:17:09 +00:00
u := c . BaseURL . String ( ) + uri
req , err := http . NewRequest ( method , u , buf )
if err != nil {
return nil , errors . Wrap ( err , "failed to create request object" )
}
2018-09-17 04:44:41 +00:00
for k , v := range * c . BaseHttpHeader {
2017-12-10 19:17:09 +00:00
for _ , h := range v {
2018-09-19 19:12:06 +00:00
//log.Printf("Adding header (%s): (%s - %s)\n\n", u, k, h)
req . Header . Set ( k , h )
2017-12-10 19:17:09 +00:00
}
}
for k , v := range header {
for _ , h := range v {
2018-09-19 19:12:06 +00:00
//log.Printf("Adding header (%s): (%s - %s)\n\n", u, k, h)
req . Header . Set ( k , h )
2017-12-10 19:17:09 +00:00
}
}
return & Request {
Request : * req ,
} , nil
}
func ( c * Client ) newResponse ( resp * http . Response ) ( * Response , error ) {
return & Response {
Response : * resp ,
} , nil
}
func ( c * Client ) do ( req * Request ) ( * Response , error ) {
2018-09-19 19:12:06 +00:00
//log.Printf("\n\nCOOKIES (%s): %v\n\n", req.URL, c.HttpClient.Jar.Cookies(req.URL))
//log.Printf("\n\nHEADERS (%s): %v\n\n", req.URL, req.Header)
2017-12-10 19:17:09 +00:00
2018-09-17 04:44:41 +00:00
resp , err := c . HttpClient . Do ( & req . Request )
2017-12-10 19:17:09 +00:00
if err != nil {
return nil , errors . Wrap ( err , "failed to execute http request" )
}
2018-09-17 04:44:41 +00:00
if resp . StatusCode >= http . StatusBadRequest {
2017-12-10 19:17:09 +00:00
defer resp . Body . Close ( )
return nil , errors . New ( "http request failed with status: " + resp . Status )
}
return c . newResponse ( resp )
}