溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么向s3cmd服務(wù)上傳數(shù)據(jù)

發(fā)布時間:2021-12-30 16:32:56 來源:億速云 閱讀:155 作者:iii 欄目:云計算

本篇內(nèi)容主要講解“怎么向s3cmd服務(wù)上傳數(shù)據(jù)”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“怎么向s3cmd服務(wù)上傳數(shù)據(jù)”吧!

1. 基本原理

怎么向s3cmd服務(wù)上傳數(shù)據(jù)

操作流程:
1.客戶端向presign server提交上傳操作請求,生成對應(yīng)的presign URL
2.使用生成的presign URL構(gòu)造HTTP請求,向S3服務(wù)上傳數(shù)據(jù)。

2. 優(yōu)缺點

優(yōu)點:
1. accesskey和secretkey不會存儲在客戶端,避免key泄露
2. 每個presignURL對應(yīng)一個keyname,在有效時間內(nèi)可以任意上傳和覆蓋已有文件,比較靈活。
3. 服務(wù)端可以結(jié)合各種Auth系統(tǒng)完成客戶端的認(rèn)證和授權(quán),方便集成現(xiàn)有業(yè)務(wù)。
4. 客戶端上傳下載方式靈活,拿到presignURL以后,可以通過任意支持HTTP協(xié)議的客戶端進(jìn)行上傳下載操作。

缺點:
1. 上傳和下載的交互比普通上傳要多出一個步驟。
2. 文中的presign是以單次PUT方式上傳,大文件不適用這個方法。

3.具體實現(xiàn)

安裝服務(wù)端依賴

pip install boto
pip install flask-restful

服務(wù)端demo代碼如下:

# -*- coding: utf-8 -*-
import boto
import boto.s3.connection
from flask import Flask, request
from flask_restful import Resource, Api
import re

s3enpoint = 's3.ceph.work' #S3服務(wù)的endpoint
access_key = '' #access_key
secret_key = '' #secret_key
bucket = 'multi-upload' #上傳數(shù)據(jù)存放的bucket名稱

class Presign_Upload(Resource):
    def __init__(self):
        self.s3enpoint = s3enpoint
        self.access_key = access_key
        self.secret_key = secret_key
        self.bucket = bucket
        # super(Presign_Upload,self).__init__()
        self.headers = {}

    def presign(self,key_name,expires_in):
        conn = boto.connect_s3(
                aws_access_key_id = self.access_key,
                aws_secret_access_key = self.secret_key,
                host = self.s3enpoint,
                port = 80 ,
                is_secure = False,               # uncommmnt if you are not using ssl
                # calling_format = boto.s3.connection.OrdinaryCallingFormat(), #use path-style
                calling_format = boto.s3.connection.SubdomainCallingFormat(), #use virtual-hosted-style
                )
        presigened_url = conn.generate_url(expires_in, "PUT", self.bucket, key_name,headers=self.headers)
        return presigened_url

    def get(self):
        if not request.args.get("keyname"):
            return "no keyname", 404
        else:
            keyname = request.args.get("keyname")
        if not request.args.get("expires"):
            return "no expires", 404
        else:
            expires = int(request.args.get("expires"))
        if request.args.get("contentype"):
            contentype = request.args.get("contentype")
            self.headers['Content-Type'] = contentype
        if request.args.get("policy"):
            policy = request.args.get("policy")
            self.headers['x-amz-acl'] = policy
        meatadata_rule = 'x-amz-meta-'
        for parm in request.args:
            if re.match(meatadata_rule, parm):
                self.headers[parm] = request.args.get(parm)
        return {"PresignURL": self.presign(keyname, expires)}

class Presign_Download(Resource):
    def __init__(self):
        Resource.__init__(self)
        self.s3enpoint = s3enpoint
        self.access_key = access_key
        self.secret_key = secret_key
        self.bucket = bucket
        self.headers = {}

    def presign(self,key_name,expires_in):
        conn = boto.connect_s3(
                aws_access_key_id = self.access_key,
                aws_secret_access_key = self.secret_key,
                host = self.s3enpoint,
                port = 80 ,
                is_secure = False,               # uncommmnt if you are not using ssl
                # calling_format = boto.s3.connection.OrdinaryCallingFormat(), #use path-style
                calling_format = boto.s3.connection.SubdomainCallingFormat(), #use virtual-hosted-style
                )
        presigened_url = conn.generate_url(expires_in, "GET", self.bucket, key_name)
        return presigened_url

    def get(self):
        if not request.args.get("keyname"):
            return "no keyname", 400
        else:
            keyname = request.args.get("keyname")
        if not request.args.get("expires"):
            return "no expires", 400
        else:
            expires = int(request.args.get("expires"))
        return {"PresignURL": self.presign(keyname, expires)}

app = Flask(__name__)
api = Api(app)
api.add_resource(Presign_Upload, '/upload')
api.add_resource(Presign_Download, '/download')

if __name__ == '__main__':
    app.run(debug=True)

安裝客戶端依賴

pip install requests

客戶端demo代碼如下:

# -*- coding: utf-8 -*-
import requests
import json

class Presign_client():
    def __init__(self, server_url):
        self.server_url = server_url
        self.headers = {}

    def get_upload_presignURL(self, keyname, expires, policy=None, contentype=None, metadata=None):
        base_url_ = "{server_url}/upload?keyname={keyname}&expires={expires}".format(server_url=server_url,keyname=keyname,expires=expires)
        if contentype:
            self.headers['Content-Type'] = contentype
            base_url_ = "{base_url_}&contentype={contentype}".format(base_url_=base_url_,contentype=contentype)
        if policy:
            self.headers['x-amz-acl'] = policy
            base_url_ = "{base_url_}&policy={policy}".format(base_url_=base_url_,policy=policy)
        if metadata:
            for k in metadata:
                metadata_key = k
                metadata_value = metadata[k]
                self.headers[metadata_key] = str(metadata_value)
                base_url_ = "{base_url_}&{metadata_key}={metadata_value}".format(base_url_=base_url_,metadata_key=str(metadata_key),metadata_value=metadata_value)
        res = requests.get(base_url_)
        return json.loads(res.content)['PresignURL']

    def upload_file(self,SignURL,filepath):
        with open(filepath) as fh:
            mydata = fh.read()
            response = requests.put(SignURL,data=mydata,headers=self.headers)
            if response.status_code == 200:
                print "Upload {} Successful!".format(filepath)
            else:
                print "Failed! status_code={}".format(response.status_code)

    def get_download_presignURL(self, keyname, expires):
        base_url_ = "{server_url}/download?keyname={keyname}&expires={expires}".format(server_url=server_url,keyname=keyname,expires=expires)
        response = requests.get(base_url_)
        return json.loads(response.content)['PresignURL']

    def download_file(self,SignURL,filepath):
        response = requests.get(SignURL)
        if response.status_code == 200:
            with open(filepath,'wb') as fh:
                fh.write(response.content)
            print "Download {} Successful!".format(filepath)
        else:
            print "Failed! status_code={}".format(response.status_code)


server_url = 'http://localhost:5000' #填服務(wù)端地址
metadata ={'x-amz-meta-abc':333,'x-amz-meta-key':'value'} #上傳文件的自定義metadata
contentype = 'abc/pdf' #設(shè)置上傳文件的Content-Type
policy = 'public-read' #設(shè)置上傳文件的ACL
expires = 300 #設(shè)置presignURL有效時長,單位秒
file_path = '/Users/demouser/Downloads/1.pdf' #上傳文件路徑
save_path = '/tmp/download.pdf' #下載文件存儲路徑
keyname = 'upload.pdf' #上傳文件的名稱,對應(yīng)object的keyname


client = Presign_client(server_url)
#生成上傳presignURL,并上傳文件
Upload_SignURL = client.get_upload_presignURL(keyname=keyname, expires=expires, policy=policy, contentype=contentype, metadata=metadata)
client.upload_file(Upload_SignURL,file_path)
#下載presignURL,并下載文件
Download_SignURL = client.get_download_presignURL(keyname=keyname, expires=expires)
client.download_file(Download_SignURL,save_path)

到此,相信大家對“怎么向s3cmd服務(wù)上傳數(shù)據(jù)”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI