/* * Hexacode Request * This program is Http Request Client * Package: gitlab.hexacode.org/go-libs/requests * Maintainer: Azzis Arswendo * * Copyright (C) 2023 Hexacode Teknologi Indonesia * All Rights Reserved */ package requests import ( "bytes" "fmt" "io" "net/http" "gitlab.hexacode.org/go-libs/hctypes" ) // Input represents the input of the Request function. type Input struct { Method string // GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE URL string // the URL to send the request to URLParams hctypes.Dict // the URL parameters to include in the request Headers hctypes.Dict // the headers to include in the request Body hctypes.Buffer // the request body to send } // Http represents the HTTP client. type Http struct { Headers hctypes.Dict // the headers to include in the request } // Output represents the output of the Request function. type Output struct { Status int // the HTTP status code returned by the server StatusText string // the HTTP status text returned by the server Headers hctypes.Dict // the headers returned by the server Body hctypes.Buffer // the body returned by the server } // DefaultHeaders is a dictionary of default headers to use in the request. var default_headers = hctypes.Dict{ "User-Agent": hctypes.String("Requests/1.0 (go-requests)"), // HTTP User-Agent header "Accept": hctypes.String("*/*"), // HTTP Accept header "Accept-Language": hctypes.String("en-US,en;q=0.5"), // HTTP Accept-Language header "DNT": hctypes.String("1"), // HTTP DNT header } func base(in *Input) (*Output, error) { url := in.URL method := in.Method if in.Body == nil { in.Body = hctypes.Buffer{} } body := bytes.NewReader(in.Body) if in.URLParams != nil { url = fmt.Sprintf("%s?%s", url, in.URLParams.Copy().ToQueryString().Encode()) } req, err := http.NewRequest(method, url, body) if err != nil { return nil, err } if default_headers == nil { default_headers = hctypes.Dict{} } if in.Headers == nil { in.Headers = hctypes.Dict{} } for k, v := range default_headers.Copy() { val, ok := v.(hctypes.String) if ok { req.Header.Set(k, string(val)) } } for k, v := range in.Headers.Copy() { val, ok := v.(hctypes.String) if ok { req.Header.Set(k, string(val)) } } client := &http.Client{} resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() bytes, err := io.ReadAll(resp.Body) if err != nil { return nil, err } out_headers := hctypes.Dict{} for k, v := range resp.Header { out_headers[k] = hctypes.String(v[0]) } return &Output{ Status: resp.StatusCode, StatusText: StatusText(resp.StatusCode), Headers: out_headers, Body: hctypes.Buffer(bytes), }, nil } // SetDefaultHeaders sets the default headers to use in the request. // // headers: hctypes.Dict representing the HTTP headers. func SetDefaultHeaders(headers hctypes.Dict) { if headers == nil { default_headers = hctypes.Dict{} } else { default_headers = headers } } // Request sends an HTTP request. // // in: *Input representing the input of the Request function. func Request(in *Input) (*Output, error) { return base(in) } // NewHttp creates a new Http instance. // // headers: hctypes.Dict representing the HTTP headers. // Returns a pointer to Http. func NewHttp(headers hctypes.Dict) *Http { return &Http{ Headers: headers, } } // Request sends an HTTP request. // // method: string representing the HTTP method. // url: string representing the URL of the request. // url_param: hctypes.Dict representing the URL parameters. // body: hctypes.Buffer representing the request body. // Returns a pointer to Output and an error. func (http *Http) Request(method string, url string, url_param hctypes.Dict, body hctypes.Buffer) (*Output, error) { in := &Input{ Method: method, URL: url, URLParams: url_param, Headers: http.Headers, Body: body, } return base(in) } // Get sends a GET request to the specified URL. // // url: the URL to send the request to // url_param: the URL parameters to include in the request // body: the request body to send // Returns *Output and error func (http *Http) Get(url string, url_param hctypes.Dict, body hctypes.Buffer) (*Output, error) { return http.Request("GET", url, url_param, body) } // Post sends a POST request to the specified URL. // // url: the URL to send the request to // url_param: the URL parameters to include in the request // body: the request body to send // Returns *Output and error func (http *Http) Post(url string, url_param hctypes.Dict, body hctypes.Buffer) (*Output, error) { return http.Request("POST", url, url_param, body) } // Put sends a PUT request to the specified URL. // // url: the URL to send the request to // url_param: the URL parameters to include in the request // body: the request body to send // Returns *Output and error func (http *Http) Put(url string, url_param hctypes.Dict, body hctypes.Buffer) (*Output, error) { return http.Request("PUT", url, url_param, body) } // Delete sends a DELETE request to the specified URL. // // url: the URL to send the request to // url_param: the URL parameters to include in the request // body: the request body to send // Returns *Output and error func (http *Http) Delete(url string, url_param hctypes.Dict, body hctypes.Buffer) (*Output, error) { return http.Request("DELETE", url, url_param, body) } // Patch sends a PATCH request to the specified URL. // // url: the URL to send the request to // url_param: the URL parameters to include in the request // body: the request body to send // Returns *Output and error func (http *Http) Patch(url string, url_param hctypes.Dict, body hctypes.Buffer) (*Output, error) { return http.Request("PATCH", url, url_param, body) } // Options sends an OPTIONS request to the specified URL. // // url: the URL to send the request to // url_param: the URL parameters to include in the request // body: the request body to send // Returns *Output and error func (http *Http) Options(url string, url_param hctypes.Dict, body hctypes.Buffer) (*Output, error) { return http.Request("OPTIONS", url, url_param, body) } // Head sends a HEAD request to the specified URL. // // url: the URL to send the request to // url_param: the URL parameters to include in the request // body: the request body to send // Returns *Output and error func (http *Http) Head(url string, url_param hctypes.Dict, body hctypes.Buffer) (*Output, error) { return http.Request("HEAD", url, url_param, body) } // Trace sends a TRACE request to the specified URL. // // url: the URL to send the request to // url_param: the URL parameters to include in the request // body: the request body to send // Returns *Output and error func (http *Http) Trace(url string, url_param hctypes.Dict, body hctypes.Buffer) (*Output, error) { return http.Request("TRACE", url, url_param, body) }