Files
mostlymatter/vendor/github.com/mattermost/rsc/appfs/client/client.go
Christopher Speller 38ee83e45b Moving to glide
2016-05-12 23:56:07 -04:00

151 строка
3.0 KiB
Go

// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package client implements a basic appfs client.
package client
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"strings"
"time"
"github.com/mattermost/rsc/appfs/proto"
)
type Client struct {
Host string
User string
Password string
}
func (c *Client) url(op, path string) string {
scheme := "https"
if strings.HasPrefix(c.Host, "localhost:") {
scheme = "http"
}
if strings.HasSuffix(op, "/") && strings.HasPrefix(path, "/") {
path = path[1:]
}
return scheme + "://"+ c.User + ":" + c.Password + "@" + c.Host + op + path
}
func (c *Client) do(u string) error {
_, err := c.get(u)
return err
}
func (c *Client) get(u string) ([]byte, error) {
tries := 0
for {
r, err := http.Get(u)
if err != nil {
return nil, err
}
defer r.Body.Close()
data, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil, err
}
if r.StatusCode != 200 {
if r.StatusCode == 500 {
if tries++; tries < 3 {
fmt.Printf("%s %s; sleeping\n", r.Status, data)
time.Sleep(5*time.Second)
continue
}
}
return nil, fmt.Errorf("%s %s", r.Status, data)
}
return data, nil
}
panic("unreachable")
}
func (c *Client) post(u string, data []byte) ([]byte, error) {
tries := 0
for {
r, err := http.Post(u, proto.PostContentType, bytes.NewBuffer(data))
if err != nil {
return nil, err
}
defer r.Body.Close()
rdata, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil, err
}
if r.StatusCode != 200 {
if r.StatusCode == 500 {
if tries++; tries < 3 {
fmt.Printf("%s %s; sleeping\n", r.Status, rdata)
time.Sleep(5*time.Second)
continue
}
}
return nil, fmt.Errorf("%s %s", r.Status, rdata)
}
return rdata, nil
}
panic("unreachable")
}
func (c *Client) Create(path string, isdir bool) error {
u := c.url(proto.CreateURL, path)
if isdir {
u += "?dir=1"
}
return c.do(u)
}
func (c *Client) Read(path string) ([]byte, error) {
return c.get(c.url(proto.ReadURL, path))
}
func (c *Client) Write(path string, data []byte) error {
u := c.url(proto.WriteURL, path)
_, err := c.post(u, data)
return err
}
func (c *Client) Mkfs() error {
return c.do(c.url(proto.MkfsURL, ""))
}
func (c *Client) Stat(path string) (*proto.FileInfo, error) {
data, err := c.get(c.url(proto.StatURL, path))
if err != nil {
return nil, err
}
var fi proto.FileInfo
if err := json.Unmarshal(data, &fi); err != nil {
return nil, err
}
return &fi, nil
}
func (c *Client) ReadDir(path string) ([]*proto.FileInfo, error) {
data, err := c.Read(path)
if err != nil {
return nil, err
}
dec := json.NewDecoder(bytes.NewBuffer(data))
var out []*proto.FileInfo
for {
var fi proto.FileInfo
err := dec.Decode(&fi)
if err == io.EOF {
break
}
if err != nil {
return out, err
}
out = append(out, &fi)
}
return out, nil
}