fix(files): UpdateFile uses PUT (#25) #26
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -357,21 +358,32 @@ func (c *Client) UploadToFolder(ctx context.Context, folderID, localPath string)
|
|||||||
|
|
||||||
// UpdateFile uploads a new version of an existing file (same id, name and
|
// UpdateFile uploads a new version of an existing file (same id, name and
|
||||||
// folder). It does not delete and does not create a second file.
|
// folder). It does not delete and does not create a second file.
|
||||||
|
//
|
||||||
|
// The Documents API method is PUT /api/2.0/files/{id}/update; POST is kept as
|
||||||
|
// a fallback for older servers. The path is tried with and without .json.
|
||||||
func (c *Client) UpdateFile(ctx context.Context, fileID, localPath string) (*FileEntry, error) {
|
func (c *Client) UpdateFile(ctx context.Context, fileID, localPath string) (*FileEntry, error) {
|
||||||
if fileID == "" || localPath == "" {
|
if fileID == "" || localPath == "" {
|
||||||
return nil, fmt.Errorf("file id and local path are required")
|
return nil, fmt.Errorf("file id and local path are required")
|
||||||
}
|
}
|
||||||
uploadPath := fmt.Sprintf("/api/2.0/files/%s/update", url.PathEscape(fileID))
|
base := fmt.Sprintf("/api/2.0/files/%s/update", url.PathEscape(fileID))
|
||||||
raw, err := c.uploadMultipart(ctx, uploadPath, "file", localPath)
|
attempts := []struct {
|
||||||
if err != nil {
|
method, path string
|
||||||
uploadPath = fmt.Sprintf("/api/2.0/files/%s/update.json", url.PathEscape(fileID))
|
}{
|
||||||
raw, err = c.uploadMultipart(ctx, uploadPath, "file", localPath)
|
{http.MethodPut, base},
|
||||||
if err != nil {
|
{http.MethodPut, base + ".json"},
|
||||||
return nil, err
|
{http.MethodPost, base},
|
||||||
}
|
{http.MethodPost, base + ".json"},
|
||||||
}
|
}
|
||||||
|
var lastErr error
|
||||||
|
for _, a := range attempts {
|
||||||
|
raw, err := c.uploadMultipartMethod(ctx, a.method, a.path, "file", localPath)
|
||||||
|
if err == nil {
|
||||||
return decodeResponseFileEntry(raw)
|
return decodeResponseFileEntry(raw)
|
||||||
}
|
}
|
||||||
|
lastErr = err
|
||||||
|
}
|
||||||
|
return nil, lastErr
|
||||||
|
}
|
||||||
|
|
||||||
// FileFolderID returns the parent folder id string for a file entry, if known.
|
// FileFolderID returns the parent folder id string for a file entry, if known.
|
||||||
func FileFolderID(f *FileEntry) string {
|
func FileFolderID(f *FileEntry) string {
|
||||||
|
|||||||
@@ -346,6 +346,14 @@ func (c *Client) putJSON(ctx context.Context, path string, body any) (json.RawMe
|
|||||||
|
|
||||||
// uploadMultipart posts a single file to path under the given form field name.
|
// uploadMultipart posts a single file to path under the given form field name.
|
||||||
func (c *Client) uploadMultipart(ctx context.Context, path, fieldName, filePath string) (json.RawMessage, error) {
|
func (c *Client) uploadMultipart(ctx context.Context, path, fieldName, filePath string) (json.RawMessage, error) {
|
||||||
|
return c.uploadMultipartMethod(ctx, http.MethodPost, path, fieldName, filePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// uploadMultipartMethod sends a single-file multipart request with the given
|
||||||
|
// HTTP method. The OnlyOffice Documents API needs PUT for /update (a new
|
||||||
|
// version) and POST for /upload (a new file); sending POST to /update answers
|
||||||
|
// 500 on current servers.
|
||||||
|
func (c *Client) uploadMultipartMethod(ctx context.Context, method, path, fieldName, filePath string) (json.RawMessage, error) {
|
||||||
auth, err := c.authHeader()
|
auth, err := c.authHeader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -368,7 +376,7 @@ func (c *Client) uploadMultipart(ctx context.Context, path, fieldName, filePath
|
|||||||
if err := mw.Close(); err != nil {
|
if err := mw.Close(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL()+path, &buf)
|
req, err := http.NewRequestWithContext(ctx, method, c.baseURL()+path, &buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user