123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- package cloud
- import (
- "bytes"
- "encoding/xml"
- "fmt"
- "io/ioutil"
- "net/http"
- "net/url"
- "path/filepath"
- )
- // A client represents a client connection to a {own|next}cloud
- type Client struct {
- Url *url.URL
- Username string
- Password string
- }
- // Error type encapsulates the returned error messages from the
- // server.
- type Error struct {
- // Exception contains the type of the exception returned by
- // the server.
- Exception string `xml:"exception"`
- // Message contains the error message string from the server.
- Message string `xml:"message"`
- }
- func (e *Error) Error() string {
- return fmt.Sprintf("Exception: %s, Message: %s", e.Exception, e.Message)
- }
- // Dial connects to an {own|next}Cloud instance at the specified
- // address using the given credentials.
- func Dial(host, username, password string) (*Client, error) {
- url, err := url.Parse(host)
- if err != nil {
- return nil, err
- }
- return &Client{
- Url: url,
- Username: username,
- Password: password,
- }, nil
- }
- // Mkdir creates a new directory on the cloud with the specified name.
- func (c *Client) Mkdir(path string) error {
- _, err := c.sendRequest("MKCOL", path, nil)
- return err
- }
- // Delete removes the specified folder from the cloud.
- func (c *Client) Delete(path string) error {
- _, err := c.sendRequest("DELETE", path, nil)
- return err
- }
- // Upload uploads the specified source to the specified destination
- // path on the cloud.
- func (c *Client) Upload(src []byte, dest string) error {
- _, err := c.sendRequest("PUT", dest, src)
- return err
- }
- // UploadDir uploads an entire directory on the cloud. It returns the
- // path of uploaded files or error. It uses glob pattern in src.
- func (c *Client) UploadDir(src string, dest string) ([]string, error) {
- files, err := filepath.Glob(src)
- if err != nil {
- return nil, err
- }
- for _, file := range files {
- data, err := ioutil.ReadFile(file)
- if err != nil {
- return nil, err
- }
- err = c.Upload(data, filepath.Join(dest, filepath.Base(file)))
- if err != nil {
- return nil, err
- }
- }
- return files, nil
- }
- // Download downloads a file from the specified path.
- func (c *Client) Download(path string) ([]byte, error) {
- pathUrl, err := url.Parse(path)
- if err != nil {
- return nil, err
- }
- // Create the https request
- client := &http.Client{}
- req, err := http.NewRequest("GET", c.Url.ResolveReference(pathUrl).String(), nil)
- if err != nil {
- return nil, err
- }
- req.SetBasicAuth(c.Username, c.Password)
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return nil, err
- }
- error := Error{}
- err = xml.Unmarshal(body, &error)
- if err == nil {
- if error.Exception != "" {
- return nil, err
- }
- }
- return body, nil
- }
- func (c *Client) Exists(path string) bool {
- _, err := c.sendRequest("PROPFIND", path, nil)
- return err == nil
- }
- func (c *Client) sendRequest(request string, path string, data []byte) ([]byte, error) {
- // Create the https request
- folderUrl, err := url.Parse(path)
- if err != nil {
- return nil, err
- }
- client := &http.Client{}
- req, err := http.NewRequest(request, c.Url.ResolveReference(folderUrl).String(), bytes.NewReader(data))
- if err != nil {
- return nil, err
- }
- req.SetBasicAuth(c.Username, c.Password)
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return nil, err
- }
- if len(body) > 0 {
- error := Error{}
- err = xml.Unmarshal(body, &error)
- if err != nil {
- return body, err
- }
- if error.Exception != "" {
- return nil, err
- }
- }
- return body, nil
- }
|