cloud.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package cloud
  2. import (
  3. "bytes"
  4. "encoding/xml"
  5. "fmt"
  6. "io/ioutil"
  7. "net/http"
  8. "net/url"
  9. "path/filepath"
  10. )
  11. // A client represents a client connection to a {own|next}cloud
  12. type Client struct {
  13. Url *url.URL
  14. Username string
  15. Password string
  16. }
  17. // Error type encapsulates the returned error messages from the
  18. // server.
  19. type Error struct {
  20. // Exception contains the type of the exception returned by
  21. // the server.
  22. Exception string `xml:"exception"`
  23. // Message contains the error message string from the server.
  24. Message string `xml:"message"`
  25. }
  26. // Dial connects to an {own|next}Cloud instance at the specified
  27. // address using the given credentials.
  28. func Dial(host, username, password string) (*Client, error) {
  29. url, err := url.Parse(host)
  30. if err != nil {
  31. return nil, err
  32. }
  33. return &Client{
  34. Url: url,
  35. Username: username,
  36. Password: password,
  37. }, nil
  38. }
  39. // Mkdir creates a new directory on the cloud with the specified name.
  40. func (c *Client) Mkdir(path string) error {
  41. _, err := c.sendRequest("MKCOL", path, nil)
  42. return err
  43. }
  44. // Delete removes the specified folder from the cloud.
  45. func (c *Client) Delete(path string) error {
  46. _, err := c.sendRequest("DELETE", path, nil)
  47. return err
  48. }
  49. // Upload uploads the specified source to the specified destination
  50. // path on the cloud.
  51. func (c *Client) Upload(src []byte, dest string) error {
  52. _, err := c.sendRequest("PUT", dest, src)
  53. return err
  54. }
  55. // UploadDir uploads an entire directory on the cloud. It returns the
  56. // number of uploaded files or error. It uses glob pattern in src.
  57. func (c *Client) UploadDir(src string, dest string) (int, error) {
  58. files, err := filepath.Glob(src)
  59. if err != nil {
  60. return 0, err
  61. }
  62. for _, file := range files {
  63. data, err := ioutil.ReadFile(file)
  64. if err != nil {
  65. return 0, err
  66. }
  67. err = c.Upload(data, filepath.Join(dest, filepath.Base(file)))
  68. if err != nil {
  69. return 0, err
  70. }
  71. }
  72. return len(files), nil
  73. }
  74. // Download downloads a file from the specified path.
  75. func (c *Client) Download(path string) ([]byte, error) {
  76. pathUrl, err := url.Parse(path)
  77. if err != nil {
  78. return nil, err
  79. }
  80. // Create the https request
  81. client := &http.Client{}
  82. req, err := http.NewRequest("GET", c.Url.ResolveReference(pathUrl).String(), nil)
  83. if err != nil {
  84. return nil, err
  85. }
  86. req.SetBasicAuth(c.Username, c.Password)
  87. resp, err := client.Do(req)
  88. if err != nil {
  89. return nil, err
  90. }
  91. body, err := ioutil.ReadAll(resp.Body)
  92. if err != nil {
  93. return nil, err
  94. }
  95. error := Error{}
  96. err = xml.Unmarshal(body, &error)
  97. if err == nil {
  98. if error.Exception != "" {
  99. return nil, fmt.Errorf("Exception: %s, Message: %s", error.Exception, error.Message)
  100. }
  101. }
  102. return body, nil
  103. }
  104. func (c *Client) Exists(path string) bool {
  105. _, err := c.sendRequest("PROPFIND", path, nil)
  106. return err == nil
  107. }
  108. func (c *Client) sendRequest(request string, path string, data []byte) ([]byte, error) {
  109. // Create the https request
  110. folderUrl, err := url.Parse(path)
  111. if err != nil {
  112. return nil, err
  113. }
  114. client := &http.Client{}
  115. req, err := http.NewRequest(request, c.Url.ResolveReference(folderUrl).String(), bytes.NewReader(data))
  116. if err != nil {
  117. return nil, err
  118. }
  119. req.SetBasicAuth(c.Username, c.Password)
  120. resp, err := client.Do(req)
  121. if err != nil {
  122. return nil, err
  123. }
  124. body, err := ioutil.ReadAll(resp.Body)
  125. if err != nil {
  126. return nil, err
  127. }
  128. if len(body) > 0 {
  129. error := Error{}
  130. err = xml.Unmarshal(body, &error)
  131. if err != nil {
  132. return body, fmt.Errorf("Error during XML Unmarshal for response %s. The error was %s", body, err)
  133. }
  134. if error.Exception != "" {
  135. return nil, fmt.Errorf("Exception: %s, Message: %s", error.Exception, error.Message)
  136. }
  137. }
  138. return body, nil
  139. }