diff --git a/client.go b/client.go index ea628dc..af2e449 100644 --- a/client.go +++ b/client.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/base64" "encoding/xml" + "io" "net/http" "os" "strings" @@ -185,14 +186,22 @@ func (c *Client) Copy(oldpath string, newpath string, overwrite bool) error { } func (c *Client) Read(path string) ([]byte, error) { + if stream, err := c.ReadStream(path); err == nil { + defer stream.Close() + buf := new(bytes.Buffer) + buf.ReadFrom(stream) + return buf.Bytes(), nil + } else { + return nil, err + } +} + +func (c *Client) ReadStream(path string) (io.ReadCloser, error) { rs, err := c.reqDo("GET", path, nil) if err != nil { - return nil, newPathErrorErr("Read", path, err) + return nil, newPathErrorErr("ReadStream", path, err) } - defer rs.Body.Close() - buf := new(bytes.Buffer) - buf.ReadFrom(rs.Body) - return buf.Bytes(), nil + return rs.Body, nil } func (c *Client) Write(path string, data []byte, _ os.FileMode) error { @@ -217,3 +226,15 @@ func (c *Client) Write(path string, data []byte, _ os.FileMode) error { } return newPathError("Write", path, s) } + +func (c *Client) WriteStream(path string, stream io.Reader, _ os.FileMode) error { + // TODO check if parent collection exists + s := c.put(path, stream) + switch s { + case 200, 201: + return nil + + default: + return newPathError("WriteStream", path, s) + } +} diff --git a/main/client.go b/main/client.go index 3b5223d..7a8648b 100644 --- a/main/client.go +++ b/main/client.go @@ -1,7 +1,6 @@ package main import ( - "bytes" "errors" "flag" "fmt" @@ -132,11 +131,11 @@ func main() { } case "PUT", "PUSH", "WRITE": - bytes, err := getBytes(a1) + stream, err := getStream(a1) if err != nil { Fail(err) } - if err := c.Write(a0, bytes, 0644); err != nil { + if err := c.WriteStream(a0, stream, 0644); err != nil { fmt.Println(err) } else { fmt.Println(fmt.Sprintf("Written: '%s' -> %s", a1, a0)) @@ -150,7 +149,7 @@ func main() { } } -func getBytes(pathOrString string) ([]byte, error) { +func getStream(pathOrString string) (io.ReadCloser, error) { fi, err := os.Stat(pathOrString) if err == nil { if fi.IsDir() { @@ -158,15 +157,18 @@ func getBytes(pathOrString string) ([]byte, error) { } f, err := os.Open(pathOrString) if err == nil { - defer f.Close() - buf := bytes.NewBuffer(nil) - _, err := io.Copy(buf, f) - if err == nil { - return buf.Bytes(), nil - } + return f, nil } return nil, &os.PathError{"Open", pathOrString, err} } else { - return []byte(pathOrString), nil + return nopCloser{strings.NewReader(pathOrString)}, nil } } + +type nopCloser struct { + io.Reader +} + +func (nopCloser) Close() error { + return nil +}