package api import ( "bytes" "encoding/json" "errors" "fmt" "io" "io/ioutil" "mime/multipart" "net/http" ) type API struct { Protocol string Host string Port int Opts APIOptions } type APIOptions struct { KeyAuth bool Key string BasicAuth bool Username string Password string } type UploadDocumentResponse struct { Info UploadDocumentResponseInfo `json:"info"` Message string `json:"message"` } type UploadDocumentResponseInfo struct { Bucket string `json:"bucket"` Object string `json:"key"` Size float64 `json:"size"` } func New(protocol, host string, port int, opts APIOptions) (*API, error) { api := API{ Protocol: protocol, Host: host, Port: port, Opts: opts, } return &api, nil } // Call returns a []byte representing a response body. // Can be used for GET or DELETE methods func (a *API) Call(method, route string) ([]byte, error) { endpoint := fmt.Sprintf("%s://%s:%d", a.Protocol, a.Host, a.Port, ) request := fmt.Sprintf("%s%s", endpoint, route) switch method { case http.MethodGet: // Create client client := &http.Client{} // Create request request, err := http.NewRequest(http.MethodGet, request, nil) if err != nil { return nil, err } if a.Opts.KeyAuth { request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key)) } // Fetch Request response, err := client.Do(request) if err != nil { return nil, err } defer response.Body.Close() body, err := ioutil.ReadAll(response.Body) if err != nil { return nil, err } return body, nil case http.MethodDelete: // Create client client := &http.Client{} // Create request req, err := http.NewRequest(http.MethodDelete, request, nil) if err != nil { return nil, err } if a.Opts.KeyAuth { req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key)) } // Fetch Request resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() // Read Response Body respBody, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } return respBody, nil } //return nil, errors.New(fmt.Sprintf("method must be 'GET' or 'DELETE', got '%s'", method)) return nil, errors.New(fmt.Sprintf("method must be 'GET' or 'DELETE', got '%s'", method)) } func (a *API) UploadDocument(bucket string, file_header *multipart.FileHeader) (UploadDocumentResponse, error) { endpoint := fmt.Sprintf("%s://%s:%d", a.Protocol, a.Host, a.Port, ) url := fmt.Sprintf("%s/v1/bucket/%s", endpoint, bucket) // Create a new multipart writer body := &bytes.Buffer{} writer := multipart.NewWriter(body) // Add the file to the request file, err := file_header.Open() if err != nil { return UploadDocumentResponse{}, fmt.Errorf("UploadDocument#file_header.Open: %s", err) } defer file.Close() part, err := writer.CreateFormFile("document", file_header.Filename) if err != nil { return UploadDocumentResponse{}, fmt.Errorf("UploadDocument#writer.CreateFormFile: %s", err) } _, err = io.Copy(part, file) if err != nil { return UploadDocumentResponse{}, fmt.Errorf("UploadDocument#io.Copy: %s", err) } err = writer.Close() if err != nil { return UploadDocumentResponse{}, fmt.Errorf("UploadDocument#writer.Close: %s", err) } // Create a new HTTP request with the multipart body req, err := http.NewRequest(http.MethodPost, url, body) if err != nil { return UploadDocumentResponse{}, fmt.Errorf("UploadDocument#http.NewRequest: %s", err) } req.Header.Set("Content-Type", writer.FormDataContentType()) if a.Opts.KeyAuth { req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key)) } // Send the HTTP request client := &http.Client{} resp, err := client.Do(req) if err != nil { return UploadDocumentResponse{}, fmt.Errorf("UploadDocument#client.Do: %s", err) } defer resp.Body.Close() // Handle the response var res UploadDocumentResponse json.NewDecoder(resp.Body).Decode(&res) return res, nil } // CallWithData takes data and returns a string representing a response body. // Can be used for POST or PUT methods func (a *API) CallWithData(method, route string, data []byte) (string, error) { endpoint := fmt.Sprintf("%s://%s:%d", a.Protocol, a.Host, a.Port, ) request := fmt.Sprintf("%s%s", endpoint, route) switch method { case http.MethodPost: // initialize http client client := &http.Client{} // set the HTTP method, url, and request body req, err := http.NewRequest(http.MethodPost, request, bytes.NewBuffer(data)) if err != nil { return "", err } if a.Opts.KeyAuth { req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key)) } // set the request header Content-Type for json req.Header.Set("Content-Type", "application/json; charset=utf-8") resp, err := client.Do(req) if err != nil { return "", err } var res map[string]interface{} json.NewDecoder(resp.Body).Decode(&res) return fmt.Sprintf("%s\n", res["message"]), nil /* case http.MethodPut: // initialize http client client := &http.Client{} // set the HTTP method, url, and request body req, err := http.NewRequest(http.MethodPut, request, bytes.NewBuffer(data)) if err != nil { return "", err } if a.Opts.KeyAuth { req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key)) } // set the request header Content-Type for json //req.Header.Set("Content-Type", "application/json; charset=utf-8") resp, err := client.Do(req) if err != nil { return "", err } var res map[string]interface{} json.NewDecoder(resp.Body).Decode(&res) return fmt.Sprintf("%s\n", res["message"]), nil */ } //return "", errors.New(fmt.Sprintf("method must be 'POST' or 'PUT', got '%s'", method)) return "", errors.New(fmt.Sprintf("method must be 'POST', got '%s'", method)) }