package service import ( "bytes" "encoding/json" "errors" "fmt" "io" "io/ioutil" "mime/multipart" "net/http" "strings" ) type FileService struct{} type innerFileMeta struct { Count int `json:"count"` Fid string `json:"fid"` Url string `json:"url"` PublicUrl string `json:"publicUrl"` } const FILE_SERVER_URL = "http://localhost:9333" func (fsrv *FileService) Upload(fileReader io.Reader) (interface{}, error) { res, err := http.Post(FILE_SERVER_URL+"/dir/assign", "application/x-www-form-urlencoded", nil) if err != nil { return "", err } defer res.Body.Close() buf, err := ioutil.ReadAll(res.Body) if err != nil { return "", err } var metaf = &innerFileMeta{} err = json.Unmarshal(buf, metaf) if err != nil { return "", err } var purl = "http://" + metaf.PublicUrl + "/" + metaf.Fid request, err := newfileUploadRequest(purl, nil, "file", "test.jpg", fileReader) //rbytes, _ := httputil.DumpRequest(request, true) if err != nil { return "", err } client := &http.Client{} resp, err := client.Do(request) if err != nil { return "", err } else { //body := &bytes.Buffer{} //_, err := body.ReadFrom(resp.Body) resp.Body.Close() return metaf, nil } } type fileLocation struct { PublicUrl string `json:"publicUrl"` Url string `json:"url"` } type fileLookupResponse struct { Locations []fileLocation `json:"locations"` } func (fsrv *FileService) GetImage(fid string) (interface{}, error) { fidParts := strings.Split(fid, ",") if len(fidParts) != 2 { return nil, errors.New("wrong file id") } resp, err := http.Get(fmt.Sprintf("%s/dir/lookup?volumeId=%s", FILE_SERVER_URL, fidParts[0])) if err != nil { return nil, err } je := json.NewDecoder(resp.Body) fr := fileLookupResponse{} err = je.Decode(&fr) resp.Body.Close() if err != nil { return nil, err } return fmt.Sprintf("http://%s/%s", fr.Locations[0].PublicUrl, fid), nil //fr.Locations[0].PublicUrl } // Creates a new file upload http request with optional extra params func newfileUploadRequest(uri string, params map[string]string, paramName, fileName string, fileReader io.Reader) (*http.Request, error) { body := &bytes.Buffer{} writer := multipart.NewWriter(body) part, err := writer.CreateFormFile(paramName, fileName) if err != nil { return nil, err } _, err = io.Copy(part, fileReader) if err != nil { return nil, err } if params != nil { for key, val := range params { _ = writer.WriteField(key, val) } } err = writer.Close() if err != nil { return nil, err } req, err := http.NewRequest("POST", uri, body) if err != nil { return nil, err } req.Header.Set("Content-Type", writer.FormDataContentType()) return req, nil }