예제 #1
0
파일: client.go 프로젝트: 5Sigma/Conduit
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
}
예제 #2
0
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)
}