2022-10-18 01:24:12 +00:00
|
|
|
// Copyright 2022 Woodpecker Authors
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2021-10-02 22:27:43 +00:00
|
|
|
package woodpecker
|
2019-04-06 19:32:14 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2024-04-26 11:46:55 +00:00
|
|
|
pathLogLevel = "%s/api/log-level"
|
|
|
|
|
2021-11-25 23:03:19 +00:00
|
|
|
// TODO: implement endpoints
|
|
|
|
// pathFeed = "%s/api/user/feed"
|
|
|
|
// pathVersion = "%s/version"
|
2019-04-06 19:32:14 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type client struct {
|
|
|
|
client *http.Client
|
|
|
|
addr string
|
|
|
|
}
|
|
|
|
|
|
|
|
// New returns a client at the specified url.
|
|
|
|
func New(uri string) Client {
|
|
|
|
return &client{http.DefaultClient, strings.TrimSuffix(uri, "/")}
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewClient returns a client at the specified url.
|
|
|
|
func NewClient(uri string, cli *http.Client) Client {
|
|
|
|
return &client{cli, strings.TrimSuffix(uri, "/")}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetClient sets the http.Client.
|
|
|
|
func (c *client) SetClient(client *http.Client) {
|
|
|
|
c.client = client
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetAddress sets the server address.
|
|
|
|
func (c *client) SetAddress(addr string) {
|
|
|
|
c.addr = addr
|
|
|
|
}
|
|
|
|
|
2021-10-18 23:25:20 +00:00
|
|
|
// LogLevel returns the current logging level
|
|
|
|
func (c *client) LogLevel() (*LogLevel, error) {
|
|
|
|
out := new(LogLevel)
|
|
|
|
uri := fmt.Sprintf(pathLogLevel, c.addr)
|
|
|
|
err := c.get(uri, out)
|
|
|
|
return out, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetLogLevel sets the logging level of the server
|
|
|
|
func (c *client) SetLogLevel(in *LogLevel) (*LogLevel, error) {
|
|
|
|
out := new(LogLevel)
|
|
|
|
uri := fmt.Sprintf(pathLogLevel, c.addr)
|
|
|
|
err := c.post(uri, in, out)
|
|
|
|
return out, err
|
|
|
|
}
|
|
|
|
|
2019-04-06 19:32:14 +00:00
|
|
|
//
|
|
|
|
// http request helper functions
|
|
|
|
//
|
|
|
|
|
2024-04-26 11:46:55 +00:00
|
|
|
// Helper function for making an http GET request.
|
2023-11-12 17:23:48 +00:00
|
|
|
func (c *client) get(rawurl string, out any) error {
|
2023-03-19 17:32:19 +00:00
|
|
|
return c.do(rawurl, http.MethodGet, nil, out)
|
2019-04-06 19:32:14 +00:00
|
|
|
}
|
|
|
|
|
2024-04-26 11:46:55 +00:00
|
|
|
// Helper function for making an http POST request.
|
2023-11-12 17:23:48 +00:00
|
|
|
func (c *client) post(rawurl string, in, out any) error {
|
2023-03-19 17:32:19 +00:00
|
|
|
return c.do(rawurl, http.MethodPost, in, out)
|
2019-04-06 19:32:14 +00:00
|
|
|
}
|
|
|
|
|
2024-04-26 11:46:55 +00:00
|
|
|
// Helper function for making an http PATCH request.
|
2023-11-12 17:23:48 +00:00
|
|
|
func (c *client) patch(rawurl string, in, out any) error {
|
2023-03-19 17:32:19 +00:00
|
|
|
return c.do(rawurl, http.MethodPatch, in, out)
|
2019-04-06 19:32:14 +00:00
|
|
|
}
|
|
|
|
|
2024-04-26 11:46:55 +00:00
|
|
|
// Helper function for making an http DELETE request.
|
2019-04-06 19:32:14 +00:00
|
|
|
func (c *client) delete(rawurl string) error {
|
2023-03-19 17:32:19 +00:00
|
|
|
return c.do(rawurl, http.MethodDelete, nil, nil)
|
2019-04-06 19:32:14 +00:00
|
|
|
}
|
|
|
|
|
2024-04-26 11:46:55 +00:00
|
|
|
// Helper function to make an http request.
|
2023-11-12 17:23:48 +00:00
|
|
|
func (c *client) do(rawurl, method string, in, out any) error {
|
2023-03-18 19:35:27 +00:00
|
|
|
body, err := c.open(rawurl, method, in)
|
2019-04-06 19:32:14 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer body.Close()
|
|
|
|
if out != nil {
|
|
|
|
return json.NewDecoder(body).Decode(out)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-04-26 11:46:55 +00:00
|
|
|
// Helper function to open an http request.
|
2023-11-12 17:23:48 +00:00
|
|
|
func (c *client) open(rawurl, method string, in any) (io.ReadCloser, error) {
|
2019-04-06 19:32:14 +00:00
|
|
|
uri, err := url.Parse(rawurl)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
req, err := http.NewRequest(method, uri.String(), nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if in != nil {
|
2024-01-27 20:15:10 +00:00
|
|
|
decoded, decodeErr := json.Marshal(in)
|
|
|
|
if decodeErr != nil {
|
|
|
|
return nil, decodeErr
|
2019-04-06 19:32:14 +00:00
|
|
|
}
|
|
|
|
buf := bytes.NewBuffer(decoded)
|
2022-08-29 23:14:07 +00:00
|
|
|
req.Body = io.NopCloser(buf)
|
2019-04-06 19:32:14 +00:00
|
|
|
req.ContentLength = int64(len(decoded))
|
|
|
|
req.Header.Set("Content-Length", strconv.Itoa(len(decoded)))
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
}
|
|
|
|
resp, err := c.client.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if resp.StatusCode > http.StatusPartialContent {
|
|
|
|
defer resp.Body.Close()
|
2022-08-29 23:14:07 +00:00
|
|
|
out, _ := io.ReadAll(resp.Body)
|
2019-04-06 19:32:14 +00:00
|
|
|
return nil, fmt.Errorf("client error %d: %s", resp.StatusCode, string(out))
|
|
|
|
}
|
|
|
|
return resp.Body, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// mapValues converts a map to url.Values
|
|
|
|
func mapValues(params map[string]string) url.Values {
|
|
|
|
values := url.Values{}
|
|
|
|
for key, val := range params {
|
|
|
|
values.Add(key, val)
|
|
|
|
}
|
|
|
|
return values
|
|
|
|
}
|