2020
2121import json
2222import logging
23- import random
2423import time
2524from concurrent .futures import Future , ThreadPoolExecutor
2625
@@ -59,7 +58,6 @@ def submit(self, fn, /, *args, **kwargs):
5958
6059class S3Staging_boto3 (staging .Staging ):
6160 def __init__ (self , config ):
62-
6361 self .bucket = config .get ("bucket" , "default" )
6462 self .url = config .get ("url" , None )
6563
@@ -76,17 +74,9 @@ def __init__(self, config):
7674 for name in ["boto" , "urllib3" , "s3transfer" , "boto3" , "botocore" , "nose" ]:
7775 logging .getLogger (name ).setLevel (logging .WARNING )
7876
79- prefix = "https" if self .use_ssl else "http"
80-
81- if config .get ("random_host" , False ):
82- self .host = config .get ("random_host" , {}).get ("host" , self .host )
83- index = random .randint (0 , config .get ("random_host" , {}).get ("max" , 1 ) - 1 )
84- # replace %%ID%% in the host with the index
85- self .host = self .host .replace ("%%ID%%" , str (index ))
86- self .url = self .url + "/" + str (index )
87- logging .info (f"Using random host: { self .host } " )
77+ self .prefix = "https" if self .use_ssl else "http"
8878
89- self ._internal_url = f"{ prefix } ://{ self .host } :{ self .port } "
79+ self ._internal_url = f"http ://{ self .host } :{ self .port } "
9080
9181 # Setup Boto3 client
9282 self .s3_client = boto3 .client (
@@ -125,7 +115,10 @@ def create(self, name, data, content_type):
125115 # else using content-disposition header
126116 try :
127117 multipart_upload = self .s3_client .create_multipart_upload (
128- Bucket = self .bucket , Key = name , ContentType = content_type , ContentDisposition = "attachment"
118+ Bucket = self .bucket ,
119+ Key = name ,
120+ ContentType = content_type ,
121+ ContentDisposition = "attachment" ,
129122 )
130123 upload_id = multipart_upload ["UploadId" ]
131124
@@ -140,7 +133,15 @@ def create(self, name, data, content_type):
140133 else :
141134 for part_data in self .iterator_buffer (data , self .buffer_size ):
142135 if part_data :
143- futures .append (executor .submit (self .upload_part , name , part_number , part_data , upload_id ))
136+ futures .append (
137+ executor .submit (
138+ self .upload_part ,
139+ name ,
140+ part_number ,
141+ part_data ,
142+ upload_id ,
143+ )
144+ )
144145 part_number += 1
145146
146147 for future in futures :
@@ -153,7 +154,10 @@ def create(self, name, data, content_type):
153154 raise ValueError ("No data retrieved" )
154155
155156 self .s3_client .complete_multipart_upload (
156- Bucket = self .bucket , Key = name , UploadId = upload_id , MultipartUpload = {"Parts" : parts }
157+ Bucket = self .bucket ,
158+ Key = name ,
159+ UploadId = upload_id ,
160+ MultipartUpload = {"Parts" : parts },
157161 )
158162
159163 logging .info (f"Successfully uploaded { name } in { len (parts )} parts." )
@@ -168,7 +172,11 @@ def create(self, name, data, content_type):
168172 def upload_part (self , name , part_number , data , upload_id ):
169173 logging .debug (f"Uploading part { part_number } of { name } , { len (data )} bytes" )
170174 response = self .s3_client .upload_part (
171- Bucket = self .bucket , Key = name , PartNumber = part_number , UploadId = upload_id , Body = data
175+ Bucket = self .bucket ,
176+ Key = name ,
177+ PartNumber = part_number ,
178+ UploadId = upload_id ,
179+ Body = data ,
172180 )
173181 return {"PartNumber" : part_number , "ETag" : response ["ETag" ]}
174182
@@ -190,14 +198,14 @@ def set_bucket_policy(self):
190198 },
191199 {
192200 "Sid" : "AllowListBucket" ,
193- "Effect" : "Allow " ,
201+ "Effect" : "Deny " ,
194202 "Principal" : "*" ,
195203 "Action" : "s3:ListBucket" ,
196204 "Resource" : f"arn:aws:s3:::{ self .bucket } " ,
197205 },
198206 {
199207 "Sid" : "AllowGetBucketLocation" ,
200- "Effect" : "Allow " ,
208+ "Effect" : "Deny " ,
201209 "Principal" : "*" ,
202210 "Action" : "s3:GetBucketLocation" ,
203211 "Resource" : f"arn:aws:s3:::{ self .bucket } " ,
@@ -239,7 +247,11 @@ def stat(self, name):
239247
240248 def get_url (self , name ):
241249 if self .url :
242- return f"{ self .url } /{ self .bucket } /{ name } "
250+ if self .url .startswith ("http" ):
251+ # This covers both http and https
252+ return f"{ self .url } /{ self .bucket } /{ name } "
253+ else :
254+ return f"{ self .prefix } ://{ self .url } /{ self .bucket } /{ name } "
243255 return None
244256
245257 def get_internal_url (self , name ):
0 commit comments