diff --git a/gitea/attachment.go b/gitea/attachment.go index f02c721..1c4d393 100644 --- a/gitea/attachment.go +++ b/gitea/attachment.go @@ -109,3 +109,11 @@ func (c *Client) DeleteReleaseAttachment(user, repo string, release, id int64) ( _, resp, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/releases/%d/assets/%d", user, repo, release, id), nil, nil) return resp, err } + +// DownloadReleaseAttachment Download an Attachment of the Release by UUID +func (c *Client) DownloadReleaseAttachment(UUID string) (io.ReadCloser, *Response, error) { + if err := escapeValidatePathSegments(&UUID); err != nil { + return nil, nil, err + } + return c.getWebResponseReader(http.MethodGet, fmt.Sprintf("/attachments/%s", UUID), nil) +} diff --git a/gitea/client.go b/gitea/client.go index b8c610b..dda704c 100644 --- a/gitea/client.go +++ b/gitea/client.go @@ -221,32 +221,59 @@ func SetDebugMode() ClientOption { } } -func (c *Client) getWebResponse(method, path string, body io.Reader) ([]byte, *Response, error) { +func (c *Client) doWebRequest(method, path string, body io.Reader) (*Response, error) { c.mutex.RLock() + debug := c.debug if debug { fmt.Printf("%s: %s\nBody: %v\n", method, c.url+path, body) } + req, err := http.NewRequestWithContext(c.ctx, method, c.url+path, body) + if err != nil { + c.mutex.RUnlock() + return nil, err + } client := c.client // client ref can change from this point on so safe it c.mutex.RUnlock() - if err != nil { - return nil, nil, err - } - resp, err := client.Do(req) if err != nil { - return nil, nil, err + return nil, err } - defer resp.Body.Close() - data, err := ioutil.ReadAll(resp.Body) - if debug { - fmt.Printf("Response: %v\n\n", resp) + return &Response{resp}, err +} + +func (c *Client) getWebResponseReader(method, path string, body io.Reader) (io.ReadCloser, *Response, error) { + resp, err := c.doWebRequest(method, path, body) + if err != nil { + return nil, resp, err } - return data, &Response{resp}, err + + // check for errors + data, err := statusCodeToErr(resp) + if err != nil { + return io.NopCloser(bytes.NewReader(data)), resp, err + } + + return resp.Body, resp, nil +} + +func (c *Client) getWebResponse(method, path string, body io.Reader) ([]byte, *Response, error) { + rd, resp, err := c.getWebResponseReader(method, path, body) + defer func() { + if rd != nil { + rd.Close() + } + }() + if err != nil || rd == nil { + return nil, resp, err + } + + data, err := ioutil.ReadAll(rd) + return data, resp, err } func (c *Client) doRequest(method, path string, header http.Header, body io.Reader) (*Response, error) {