Skip to content

Commit 063c70b

Browse files
committed
Allow public url
1 parent 6930c62 commit 063c70b

File tree

3 files changed

+76
-8
lines changed

3 files changed

+76
-8
lines changed

shard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ dependencies:
66
github: martenframework/marten
77
awscr-s3:
88
github: taylorfinnell/awscr-s3
9-
version: ~> 0.9.0
9+
branch: master # TODO: Change to next version after endpoint is added
1010

1111
development_dependencies:
1212
sqlite3:

spec/marten_s3/store_spec.cr

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,61 @@ describe MartenS3::Store do
149149
end
150150

151151
describe "#url" do
152-
it "returns a URL constructed from the base URL" do
153-
storage.url("css/app.css").should contain "awscr-s3-test-"
154-
storage.url("css/app.css").should contain "css/app.css"
152+
it "returns a private URL constructed from the base URL" do
153+
uri = URI.parse(storage.url("css/app.css"))
154+
155+
uri.host.should eq URI.parse(ENV.fetch("S3_ENDPOINT", "http://127.0.0.1:9000")).host
156+
157+
uri.path.should contain "#{bucket_name}/css/app.css"
158+
159+
query = uri.query.not_nil!
160+
161+
query_params = URI::Params.parse(query)
162+
query_params.has_key?("X-Amz-Algorithm").should be_true
163+
query_params.has_key?("X-Amz-Credential").should be_true
164+
query_params.has_key?("X-Amz-Date").should be_true
165+
query_params["X-Amz-Expires"].should eq "86400"
166+
query_params.has_key?("X-Amz-SignedHeaders").should be_true
167+
query_params.has_key?("X-Amz-Signature").should be_true
168+
end
169+
170+
it "returns a path-style public URL when `use_public_url` is true and `force_path_style` is enabled" do
171+
storage = MartenS3::Store.new(
172+
region: "unused",
173+
bucket: bucket_name,
174+
access_key: ENV.fetch("S3_KEY", "admin"),
175+
secret_key: ENV.fetch("S3_SECRET", "password"),
176+
endpoint: ENV.fetch("S3_ENDPOINT", "http://127.0.0.1:9000"),
177+
force_path_style: true,
178+
use_public_url: true,
179+
)
180+
uri = URI.parse(storage.url("css/app.css"))
181+
182+
uri.host.should eq URI.parse(ENV.fetch("S3_ENDPOINT", "http://127.0.0.1:9000")).host
183+
184+
uri.path.should eq "/#{bucket_name}/css/app.css"
185+
186+
uri.query.should be_nil
187+
end
188+
189+
it "returns a virtual-host–style public URL when `use_public_url` is true and `force_path_style` is disabled" do
190+
storage = MartenS3::Store.new(
191+
region: "unused",
192+
bucket: bucket_name,
193+
access_key: ENV.fetch("S3_KEY", "admin"),
194+
secret_key: ENV.fetch("S3_SECRET", "password"),
195+
endpoint: ENV.fetch("S3_ENDPOINT", "http://127.0.0.1:9000"),
196+
use_public_url: true,
197+
)
198+
uri = URI.parse(storage.url("css/app.css"))
199+
200+
test_host = URI.parse(ENV.fetch("S3_ENDPOINT", "http://127.0.0.1:9000")).host
201+
202+
uri.host.should eq "#{bucket_name}.#{test_host}"
203+
204+
uri.path.should eq "/css/app.css"
205+
206+
uri.query.should be_nil
155207
end
156208
end
157209

src/marten_s3/store.cr

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module MartenS3
1010
@endpoint : String? = nil,
1111
@force_path_style : Bool = false,
1212
@expires_in = 86_400,
13+
@use_public_url : Bool = false,
1314
)
1415
@client = Awscr::S3::Client.new(
1516
@region,
@@ -72,19 +73,34 @@ module MartenS3
7273
end
7374

7475
def url(filepath : String) : String
75-
generate_presigned_url(filepath)
76+
filepath = URI.encode_path(filepath)
77+
78+
if @use_public_url
79+
public_url(filepath)
80+
else
81+
generate_presigned_url(filepath)
82+
end
7683
end
7784

7885
private def public_url(filepath)
79-
File.join(@endpoint.not_nil!, @bucket, URI.encode_path(filepath))
86+
if @force_path_style
87+
uri = @client.endpoint.dup
88+
uri.path = "/#{@bucket}/#{filepath}"
89+
else
90+
uri = @client.endpoint.dup
91+
uri.host = "#{@bucket}.#{@client.endpoint.host}"
92+
uri.path = "/#{filepath}"
93+
end
94+
95+
uri.to_s
8096
end
8197

8298
private def generate_presigned_url(filepath : String)
8399
options = Awscr::S3::Presigned::Url::Options.new(
84100
aws_access_key: @access_key,
85101
aws_secret_key: @secret_key,
86-
region: @region,
87-
endpoint: @endpoint,
102+
region: @client.region,
103+
endpoint: @client.endpoint.to_s,
88104
bucket: @bucket,
89105
force_path_style: @force_path_style,
90106
object: filepath,

0 commit comments

Comments
 (0)