Go の勉強がてら http リクエストを行うプログラムを作成したので適当に貼っておきます。
検索して引っかかってきた人の一助になれば幸いです。
httput.go
package httput
import (
"context"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
"time"
"golang.org/x/text/encoding"
"golang.org/x/text/transform"
)
const UserAgent = "My User Agent" // FIXME
type HTTPClient struct {
http.Client
CookieJar http.CookieJar
UserAgent string
}
func NewClient(ctx context.Context, timeout time.Duration) (*HTTPClient, error) {
cookieJar, err := cookiejar.New(nil)
if err != nil {
return nil, fmt.Errorf("error creating cookie jar: %v", err)
}
client := &HTTPClient{
Client: http.Client{Timeout: timeout, Jar: cookieJar},
CookieJar: cookieJar,
UserAgent: UserAgent,
}
return client, nil
}
func (client *HTTPClient) String() string {
return fmt.Sprintf("Client=%v, Cookie=%v", client.Client, client.CookieJar)
}
func (client *HTTPClient) GetCookies(rawurl string) ([]*http.Cookie, error) {
url, err := url.Parse(rawurl)
if err != nil {
return nil, err
}
cookies := client.CookieJar.Cookies(url)
return cookies, nil
}
func (client *HTTPClient) GetCookie(rawurl, name string) (*http.Cookie, error) {
cookies, err := client.GetCookies(rawurl)
if err != nil {
return nil, err
}
for i := range cookies {
if strings.EqualFold(cookies[i].Name, name) {
return cookies[i], nil
}
}
return nil, nil
}
func (client *HTTPClient) AddCookie(rawurl, name, value, path string) error {
url, err := url.Parse(rawurl)
if err != nil {
return err
}
cookie := http.Cookie{
Name: name,
Value: value,
Path: path,
Domain: url.Host,
}
cookies := client.CookieJar.Cookies(url)
cookies = append(cookies, &cookie)
client.CookieJar.SetCookies(url, cookies)
return nil
}
func (client *HTTPClient) GetURLResponse(ctx context.Context, url, method string, headers map[string]string) (*http.Response, error) {
req, err := http.NewRequestWithContext(ctx, method, url, nil)
if err != nil {
return nil, err
}
for key, value := range headers {
req.Header.Add(key, value)
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return resp, nil
}
func (client *HTTPClient) GetURL(ctx context.Context, url, method string, encoding encoding.Encoding, headers map[string]string) (string, error) {
resp, err := client.GetURLResponse(ctx, url, method, headers)
if err != nil {
return "", err
}
defer resp.Body.Close()
return GetBody(ctx, resp.Body, encoding)
}
func (client *HTTPClient) PostBodyURLResponse(ctx context.Context, url string, body io.Reader, headers map[string]string) (*http.Response, error) {
req, err := http.NewRequestWithContext(ctx, "POST", url, body)
if err != nil {
return nil, err
}
for key, value := range headers {
req.Header.Add(key, value)
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return resp, nil
}
func (client *HTTPClient) PostURLResponse(ctx context.Context, url string, values url.Values, headers map[string]string) (*http.Response, error) {
copyHeaders := make(map[string]string)
for k, v := range headers {
copyHeaders[k] = v
}
copyHeaders["Content-Type"] = "application/x-www-form-urlencoded"
return client.PostBodyURLResponse(ctx, url, strings.NewReader(values.Encode()), copyHeaders)
}
func (client *HTTPClient) PostURL(ctx context.Context, url string, values url.Values, encoding encoding.Encoding, headers map[string]string) (string, error) {
resp, err := client.PostURLResponse(ctx, url, values, headers)
if err != nil {
return "", err
}
defer resp.Body.Close()
return GetBody(ctx, resp.Body, encoding)
}
func GetBody(ctx context.Context, body io.ReadCloser, encoding encoding.Encoding) (string, error) {
var bytes []byte
var err error
if encoding == nil {
bytes, err = ioutil.ReadAll(body)
} else {
bytes, err = ioutil.ReadAll(transform.NewReader(body, encoding.NewDecoder()))
}
if err != nil {
return "", err
}
content := string(bytes)
return content, nil
}