hydra-core 6.0.0.rc4 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|