func (client *Client) Upload(fpath string) (*api.SimpleResponse, error) { var ( body = &bytes.Buffer{} writer = multipart.NewWriter(body) req = api.UploadFileRequest{Filename: filepath.Base(fpath)} err error ) defer writer.Close() req.MD5, err = client.hashFile(fpath) if err != nil { return nil, err } log.Infof("Uploading file %s", fpath) hClient, err := client.getHttpClient() if err != nil { return nil, err } url := fmt.Sprintf("http://%s/%s", client.Host, "upload") // Write JSON data as post param req.Sign(client.AccessKeyName, client.AccessKey) requestBytes, err := json.Marshal(req) err = writer.WriteField("data", string(requestBytes)) if err != nil { return nil, err } // Write file to request file, err := os.Open(fpath) if file != nil { defer file.Close() } if err != nil { return nil, err } part, err := writer.CreateFormFile("file", fpath) if err != nil { return nil, err } _, err = io.Copy(part, file) writer.Close() // Make the request hReq, err := http.NewRequest("POST", url, body) hReq.Header.Set("Content-Type", writer.FormDataContentType()) resp, err := hClient.Do(hReq) if resp != nil { defer resp.Body.Close() } if err != nil { return nil, err } // Read the response responseData, _ := ioutil.ReadAll(resp.Body) if resp.StatusCode != 200 { var errorResponse api.ApiError json.Unmarshal(responseData, &errorResponse) return nil, errors.New(errorResponse.Error) } res := &api.SimpleResponse{} json.Unmarshal(responseData, res) return res, err }
func acceptFile(w http.ResponseWriter, r *http.Request) { var ( request = api.UploadFileRequest{} ) defer r.Body.Close() // parse form post data err := r.ParseMultipartForm(1000000) if err != nil { sendError(w, err.Error()) return } // Get reuqest data and unmarshal reqData := r.FormValue("data") err = json.Unmarshal([]byte(reqData), &request) if err != nil { sendError(w, "Could not parse request!") return } accessKey, _ := mailbox.FindKeyByName(request.AccessKeyName) if accessKey == nil { sendError(w, "Invalid access key") return } if !accessKey.CanAdmin() { sendError(w, "Not allowed to upload files") return } if !request.Validate(accessKey.Secret) { sendError(w, "Invalid signature") return } // Save the posted file file, _, err := r.FormFile("file") if file != nil { defer file.Close() } if err != nil { sendError(w, err.Error()) return } path := filepath.Join(filesPath(), request.MD5) out, err := os.Create(path) if out != nil { defer out.Close() } if err != nil { sendError(w, err.Error()) return } _, err = io.Copy(out, file) if err != nil { sendError(w, err.Error()) return } fileHash, err := hashFile(path) if err != nil { sendError(w, err.Error()) return } if request.MD5 != fileHash { defer os.Remove(filepath.Join(filesPath(), request.MD5)) sendError(w, fmt.Sprintf("MD5 missmatch %s != %s", request.MD5, fileHash)) return } log.Infof("File uploaded %s", request.MD5) response := api.SimpleResponse{Success: true} response.Sign(accessKey.Name, accessKey.Secret) writeResponse(&w, response) }