hydra-core 6.0.0.rc4 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/hydra-head/version.rb +1 -1
- data/lib/hydra/controller.rb +1 -0
- data/lib/hydra/controller/download_behavior.rb +125 -0
- data/spec/controllers/downloads_controller_spec.rb +79 -0
- data/spec/spec_helper.rb +2 -2
- data/spec/support/app/controllers/downloads_controller.rb +3 -0
- data/spec/support/lib/generators/test_app_generator.rb +4 -0
- metadata +11 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be080a47162acf248ef80a141706589c8680144a
|
4
|
+
data.tar.gz: 9c6faddd32e384bf6dffb9d8ac6692fed158a1e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a924a89074145f546b9f50b243e043f89ad2ca3097904d9d6f3b3031795026371440d324b8af8b69c8ecb94706b7eac0a81d0df7fb8789dac4e01a1e18eceecb
|
7
|
+
data.tar.gz: 092db137d443fc66bd733f8209553b12cd9bef8c491ff5673683173a3a5ca4f26dced251f11fa31f5b1ec869ea5eafea6cdb7fd70f5eb261922cb4d47f8eeb70
|
data/lib/hydra-head/version.rb
CHANGED
data/lib/hydra/controller.rb
CHANGED
@@ -2,5 +2,6 @@ module Hydra::Controller
|
|
2
2
|
autoload :AssetsControllerBehavior, 'hydra/controller/assets_controller_behavior'
|
3
3
|
autoload :ControllerBehavior, 'hydra/controller/controller_behavior'
|
4
4
|
autoload :UploadBehavior, 'hydra/controller/upload_behavior'
|
5
|
+
autoload :DownloadBehavior, 'hydra/controller/download_behavior'
|
5
6
|
autoload :FileAssetsBehavior, 'hydra/controller/file_assets_behavior'
|
6
7
|
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Hydra
|
2
|
+
module Controller
|
3
|
+
module DownloadBehavior
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
before_filter :load_asset
|
8
|
+
before_filter :load_datastream
|
9
|
+
end
|
10
|
+
|
11
|
+
# Responds to http requests to show the datastream
|
12
|
+
def show
|
13
|
+
if can_download?
|
14
|
+
# we can now examine asset and determine if we should send_content, or some other action.
|
15
|
+
send_content (asset)
|
16
|
+
else
|
17
|
+
logger.info "Can not read #{params['id']}"
|
18
|
+
raise Hydra::AccessDenied.new("You do not have sufficient access privileges to read this document, which has been marked private.", :read, params[:id])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def load_asset
|
25
|
+
@asset = ActiveFedora::Base.find(params[:id], :cast=>true)
|
26
|
+
end
|
27
|
+
|
28
|
+
def load_datastream
|
29
|
+
@ds = datastream_to_show
|
30
|
+
end
|
31
|
+
|
32
|
+
def asset
|
33
|
+
@asset
|
34
|
+
end
|
35
|
+
|
36
|
+
def datastream
|
37
|
+
@ds
|
38
|
+
end
|
39
|
+
|
40
|
+
# Override this method to enforce access controls. By default it allows
|
41
|
+
# any datastream on an object the current user has read access to.
|
42
|
+
# @return [Boolean] can the curent user view this object/datastream
|
43
|
+
def can_download?
|
44
|
+
can? :read, datastream.pid
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# Override this method to change which datastream is shown.
|
49
|
+
# Loads the datastream specified by the HTTP parameter `:datastream_id`.
|
50
|
+
# If this object does not have a datastream by that name, return the default datastream
|
51
|
+
# as returned by {#default_content_ds}
|
52
|
+
# @return [ActiveFedora::Datastream] the datastr
|
53
|
+
def datastream_to_show
|
54
|
+
ds = asset.datastreams[params[:datastream_id]] if params.has_key?(:datastream_id)
|
55
|
+
ds = default_content_ds if ds.nil?
|
56
|
+
ds
|
57
|
+
end
|
58
|
+
|
59
|
+
# Handle the HTTP show request
|
60
|
+
def send_content(asset)
|
61
|
+
response.headers['Accept-Ranges'] = 'bytes'
|
62
|
+
|
63
|
+
if request.head?
|
64
|
+
content_head(datastream)
|
65
|
+
elsif request.headers["Range"]
|
66
|
+
send_range(datastream)
|
67
|
+
else
|
68
|
+
send_file_headers! content_options
|
69
|
+
self.response_body = datastream.stream
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Create some headers for the datastream
|
74
|
+
def content_options
|
75
|
+
{disposition: 'inline', type: datastream.mimeType, filename: datastream_name}
|
76
|
+
end
|
77
|
+
|
78
|
+
# Override this if you'd like a different filename
|
79
|
+
# @return [String] the filename
|
80
|
+
def datastream_name
|
81
|
+
params[:filename] || asset.label
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
# render an HTTP HEAD response
|
86
|
+
def content_head
|
87
|
+
response.headers['Content-Length'] = datastream.dsSize
|
88
|
+
response.headers['Content-Type'] = datastream.mimeType
|
89
|
+
head :ok
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# render an HTTP Range response
|
94
|
+
def send_range
|
95
|
+
_, range = request.headers["Range"].split('bytes=')
|
96
|
+
from, to = range.split('-').map(&:to_i)
|
97
|
+
to = datastream.dsSize - 1 unless to
|
98
|
+
length = to - from + 1
|
99
|
+
response.headers['Content-Range'] = "bytes #{from}-#{to}/#{datastream.dsSize}"
|
100
|
+
response.headers['Content-Length'] = "#{length}"
|
101
|
+
self.status = 206
|
102
|
+
send_file_headers! content_options
|
103
|
+
self.response_body = datastream.stream(from, length)
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def default_content_ds
|
109
|
+
ActiveFedora::ContentModel.known_models_for(asset).each do |model_class|
|
110
|
+
return model_class.default_content_ds if model_class.respond_to?(:default_content_ds)
|
111
|
+
end
|
112
|
+
if asset.datastreams.keys.include?(DownloadsController.default_content_dsid)
|
113
|
+
return asset.datastreams[DownloadsController.default_content_dsid]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
module ClassMethods
|
118
|
+
def default_content_dsid
|
119
|
+
"content"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DownloadsController do
|
4
|
+
before do
|
5
|
+
Rails.application.routes.draw do
|
6
|
+
resources :downloads
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "routing" do
|
11
|
+
it "should route" do
|
12
|
+
assert_recognizes( {:controller=>"downloads", :action=>"show", "id"=>"test1"}, "/downloads/test1?filename=my%20dog.jpg" )
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "with a file" do
|
17
|
+
before do
|
18
|
+
@user = User.create!(email: 'email@example.com', password: 'password')
|
19
|
+
@obj = ActiveFedora::Base.new
|
20
|
+
@obj = ModsAsset.new
|
21
|
+
@obj.label = "world.png"
|
22
|
+
@obj.add_file_datastream('foobarfoobarfoobar', :dsid=>'content', :mimeType => 'image/png')
|
23
|
+
@obj.add_file_datastream("It's a stream", :dsid=>'descMetadata', :mimeType => 'text/plain')
|
24
|
+
@obj.read_users = [@user.user_key]
|
25
|
+
@obj.save!
|
26
|
+
end
|
27
|
+
after do
|
28
|
+
@obj.destroy
|
29
|
+
end
|
30
|
+
describe "when logged in as reader" do
|
31
|
+
before do
|
32
|
+
sign_in @user
|
33
|
+
User.any_instance.stub(:groups).and_return([])
|
34
|
+
end
|
35
|
+
describe "show" do
|
36
|
+
it "should default to returning configured default download" do
|
37
|
+
DownloadsController.default_content_dsid.should == "content"
|
38
|
+
get "show", :id => @obj.pid
|
39
|
+
response.should be_success
|
40
|
+
response.headers['Content-Type'].should == "image/png"
|
41
|
+
response.headers["Content-Disposition"].should == "inline; filename=\"world.png\""
|
42
|
+
response.body.should == 'foobarfoobarfoobar'
|
43
|
+
end
|
44
|
+
it "should return requested datastreams" do
|
45
|
+
get "show", :id => @obj.pid, :datastream_id => "descMetadata"
|
46
|
+
response.should be_success
|
47
|
+
response.headers['Content-Type'].should == "text/plain"
|
48
|
+
response.headers["Content-Disposition"].should == "inline; filename=\"world.png\""
|
49
|
+
response.body.should == "It's a stream"
|
50
|
+
end
|
51
|
+
it "should support setting disposition to inline" do
|
52
|
+
get "show", :id => @obj.pid, :disposition => "inline"
|
53
|
+
response.should be_success
|
54
|
+
response.headers['Content-Type'].should == "image/png"
|
55
|
+
response.headers["Content-Disposition"].should == "inline; filename=\"world.png\""
|
56
|
+
response.body.should == 'foobarfoobarfoobar'
|
57
|
+
end
|
58
|
+
it "should allow you to specify filename for download" do
|
59
|
+
get "show", :id => @obj.pid, "filename" => "my%20dog.png"
|
60
|
+
response.should be_success
|
61
|
+
response.headers['Content-Type'].should == "image/png"
|
62
|
+
response.headers["Content-Disposition"].should == "inline; filename=\"my%20dog.png\""
|
63
|
+
response.body.should == 'foobarfoobarfoobar'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "when not logged in as reader" do
|
69
|
+
describe "show" do
|
70
|
+
before do
|
71
|
+
sign_in User.create!(email: 'email2@example.com', password: 'password')
|
72
|
+
end
|
73
|
+
it "should deny access" do
|
74
|
+
lambda { get "show", :id =>@obj.pid }.should raise_error Hydra::AccessDenied
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -13,6 +13,10 @@ class TestAppGenerator < Rails::Generators::Base
|
|
13
13
|
|
14
14
|
def copy_test_fixtures
|
15
15
|
copy_file "app/models/generic_content.rb"
|
16
|
+
|
17
|
+
# Download controller
|
18
|
+
copy_file "app/controllers/downloads_controller.rb"
|
19
|
+
|
16
20
|
copy_file "spec/fixtures/hydrangea_fixture_mods_article1.foxml.xml"
|
17
21
|
|
18
22
|
# For testing Hydra::SubmissionWorkflow
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hydra-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.0
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Zumwalt, Bess Sadler, Julie Meloni, Naomi Dushay, Jessie Keck, John Scofield,
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -87,14 +87,14 @@ dependencies:
|
|
87
87
|
requirements:
|
88
88
|
- - '='
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: 6.0.0
|
90
|
+
version: 6.0.0
|
91
91
|
type: :runtime
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
95
|
- - '='
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: 6.0.0
|
97
|
+
version: 6.0.0
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: jettywrapper
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -213,6 +213,7 @@ files:
|
|
213
213
|
- lib/hydra.rb
|
214
214
|
- lib/hydra/controller.rb
|
215
215
|
- lib/hydra/controller/controller_behavior.rb
|
216
|
+
- lib/hydra/controller/download_behavior.rb
|
216
217
|
- lib/hydra/controller/upload_behavior.rb
|
217
218
|
- lib/hydra/global_configurable.rb
|
218
219
|
- lib/hydra/model_methods.rb
|
@@ -227,6 +228,7 @@ files:
|
|
227
228
|
- spec/.gitignore
|
228
229
|
- spec/controllers/catalog_controller_spec.rb
|
229
230
|
- spec/controllers/catalog_valid_html_spec.rb
|
231
|
+
- spec/controllers/downloads_controller_spec.rb
|
230
232
|
- spec/factories.rb
|
231
233
|
- spec/helpers/blacklight_helper_spec.rb
|
232
234
|
- spec/helpers/facets_helper_spec.rb
|
@@ -243,6 +245,7 @@ files:
|
|
243
245
|
- spec/spec.opts
|
244
246
|
- spec/spec_helper.rb
|
245
247
|
- spec/support/Gemfile
|
248
|
+
- spec/support/app/controllers/downloads_controller.rb
|
246
249
|
- spec/support/app/models/generic_content.rb
|
247
250
|
- spec/support/app/models/sample.rb
|
248
251
|
- spec/support/app/models/solr_document.rb
|
@@ -272,9 +275,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
272
275
|
version: 1.9.3
|
273
276
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
274
277
|
requirements:
|
275
|
-
- - '
|
278
|
+
- - '>='
|
276
279
|
- !ruby/object:Gem::Version
|
277
|
-
version:
|
280
|
+
version: '0'
|
278
281
|
requirements: []
|
279
282
|
rubyforge_project:
|
280
283
|
rubygems_version: 2.0.0
|
@@ -285,6 +288,7 @@ test_files:
|
|
285
288
|
- spec/.gitignore
|
286
289
|
- spec/controllers/catalog_controller_spec.rb
|
287
290
|
- spec/controllers/catalog_valid_html_spec.rb
|
291
|
+
- spec/controllers/downloads_controller_spec.rb
|
288
292
|
- spec/factories.rb
|
289
293
|
- spec/helpers/blacklight_helper_spec.rb
|
290
294
|
- spec/helpers/facets_helper_spec.rb
|
@@ -301,6 +305,7 @@ test_files:
|
|
301
305
|
- spec/spec.opts
|
302
306
|
- spec/spec_helper.rb
|
303
307
|
- spec/support/Gemfile
|
308
|
+
- spec/support/app/controllers/downloads_controller.rb
|
304
309
|
- spec/support/app/models/generic_content.rb
|
305
310
|
- spec/support/app/models/sample.rb
|
306
311
|
- spec/support/app/models/solr_document.rb
|