1
0
mirror of https://github.com/haiwen/seafile-server.git synced 2025-07-16 08:15:51 +00:00
seafile-server/tests/test_upload/test_upload.go
feiniks 8c9043d2c6
Retry upload when detecting concurrent uploads (#564)
* Retry upload when detecting concurrent uploads

* Check conflict when update branch and set concurrent upload error

Co-authored-by: 杨赫然 <heran.yang@seafile.com>
2022-07-15 14:45:36 +08:00

174 lines
4.3 KiB
Go

package main
import "fmt"
import "io"
import "sync"
import "flag"
import "log"
import "encoding/json"
import "bytes"
import "net/http"
import "mime/multipart"
import "path/filepath"
import "gopkg.in/ini.v1"
import "github.com/haiwen/seafile-server/fileserver/searpc"
type Options struct {
server string
username string
password string
repoID string
threadNum int
}
var confPath string
var rpcPipePath string
var options Options
var rpcclient *searpc.Client
func init() {
flag.StringVar(&confPath, "c", "", "config file path")
flag.StringVar(&rpcPipePath, "p", "", "rpc pipe path")
}
func main() {
flag.Parse()
pipePath := filepath.Join(rpcPipePath, "seafile.sock")
rpcclient = searpc.Init(pipePath, "seafserv-threaded-rpcserver")
config, err := ini.Load(confPath)
if err != nil {
log.Fatalf("Failed to load config file: %v", err)
}
section, err := config.GetSection("account")
if err != nil {
log.Fatal("No account section in config file.")
}
key, err := section.GetKey("server")
if err == nil {
options.server = key.String()
}
key, err = section.GetKey("username")
if err == nil {
options.username = key.String()
}
key, err = section.GetKey("password")
if err == nil {
options.password = key.String()
}
key, err = section.GetKey("repoid")
if err == nil {
options.repoID = key.String()
}
key, err = section.GetKey("thread_num")
if err == nil {
options.threadNum, _ = key.Int()
}
objID := "{\"parent_dir\":\"/\"}"
token, err := rpcclient.Call("seafile_web_get_access_token", options.repoID, objID, "upload", options.username, false)
if err != nil {
log.Fatal("Failed to get web access token\n")
}
accessToken, _ := token.(string)
url := fmt.Sprintf("%s:8082/upload-api/%s", options.server, accessToken)
content := []byte("123456")
var group sync.WaitGroup
for i := 0; i < options.threadNum; i++ {
group.Add(1)
go func(i int) {
values := make(map[string]io.Reader)
values["file"] = bytes.NewReader(content)
values["parent_dir"] = bytes.NewBuffer([]byte("/"))
// values["relative_path"] = bytes.NewBuffer([]byte(relativePath))
values["replace"] = bytes.NewBuffer([]byte("0"))
form, contentType, err := createForm(values, "111.md")
if err != nil {
log.Fatal("Failed to create multipart form: %v", err)
}
headers := make(map[string][]string)
headers["Content-Type"] = []string{contentType}
// headers["Authorization"] = []string{"Token " + accessToken.(string)}
status, body, err := HttpCommon("POST", url, headers, form)
log.Printf("[%d]upload status: %d return body: %s error: %v\n", i, status, string(body), err)
group.Done()
}(i)
}
group.Wait()
}
func createForm(values map[string]io.Reader, name string) (io.Reader, string, error) {
buf := new(bytes.Buffer)
w := multipart.NewWriter(buf)
defer w.Close()
for k, v := range values {
var fw io.Writer
var err error
if k == "file" {
if fw, err = w.CreateFormFile(k, name); err != nil {
return nil, "", err
}
} else {
if fw, err = w.CreateFormField(k); err != nil {
return nil, "", err
}
}
if _, err = io.Copy(fw, v); err != nil {
return nil, "", err
}
}
return buf, w.FormDataContentType(), nil
}
func HttpCommon(method, url string, header map[string][]string, reader io.Reader) (int, []byte, error) {
req, err := http.NewRequest(method, url, reader)
if err != nil {
return -1, nil, err
}
req.Header = header
rsp, err := http.DefaultClient.Do(req)
if err != nil {
return -1, nil, err
}
defer rsp.Body.Close()
if rsp.StatusCode == http.StatusNotFound {
return rsp.StatusCode, nil, fmt.Errorf("url %s not found", url)
}
body, err := io.ReadAll(rsp.Body)
if err != nil {
return rsp.StatusCode, nil, err
}
return rsp.StatusCode, body, nil
}
func getToken() string {
url := fmt.Sprintf("%s:8000/api2/auth-token/", options.server)
header := make(map[string][]string)
header["Content-Type"] = []string{"application/x-www-form-urlencoded"}
data := []byte(fmt.Sprintf("username=%s&password=%s", options.username, options.password))
_, body, err := HttpCommon("POST", url, header, bytes.NewReader(data))
if err != nil {
return ""
}
tokenMap := make(map[string]interface{})
err = json.Unmarshal(body, &tokenMap)
if err != nil {
return ""
}
token, _ := tokenMap["token"].(string)
return token
}