Shrine: S3 get presigned_post url - undefined method 'rindex' for nil:NilClass

Created on 18 Feb 2019  路  1Comment  路  Source: shrinerb/shrine

Brief Description

Followed Official tutorial.

When trying to get a presigned url from the mounted params endpoint, the aws-sdk-s3/presigned_post.rb with function is telling me that there is an undefined method 'rindex' for nil class, with nil being the variable $filename.

Expected behavior

I expected to get params returned from the presigned endpoint when, from Insomnia rest client, I call GET localhost:3000/api/s3/params

Actual behavior

It, unfortunately, crashes when it gets to that line in the SDK.

Simplest self-contained example code to demonstrate issue

just two files, really:

Initializer:

require 'shrine'
require 'shrine/storage/s3'

# All keys seem accurate
s3_options = {
  access_key_id: Rails.application.credentials[:aws_image_s3_access_key_id],
  secret_access_key: Rails.application.credentials[:aws_image_s3_secret_access_key],
  bucket: Rails.application.credentials[:aws_image_s3_bucket],
  region: Rails.application.credentials[:aws_image_s3_region]
}

Shrine.storages = {
  cache: Shrine::Storage::S3.new(prefix: 'cache', **s3_options),
  store: Shrine::Storage::S3.new(**s3_options)
}

Shrine.plugin :activerecord
Shrine.plugin :restore_cached_data # refresh metadata when attaching the cached file
Shrine.plugin :presign_endpoint, presign_options: -> (request) {
  filename = request.params["filename"]
  type     = request.params["type"]
  {
      content_disposition:    ContentDisposition.inline(filename), # set download filename
      content_type:           type,                                # set content type (required if using DigitalOcean Spaces)
      content_length_range:   0..(1*1024*1024),                   # limit upload size to 1 MB
  }
}

Routes:

Rails.application.routes.draw do
  mount GraphiQL::Rails::Engine, at: '/graphiql', graphql_path: '/graphql' if Rails.env.development?
  mount Shrine.presign_endpoint(:cache) => '/api/s3/params'
  post '/graphql', to: 'graphql#execute'
  get 'passwords/confirm_reset'
  mount_devise_token_auth_for 'User', at: 'auth'

  root to: 'static_pages#landing'
  ...
end

Stack Trace -

Code Block:

      def with(field_name, value)
        fvar = '${filename}'
        if index = value.rindex(fvar)
          if index + fvar.size == value.size
            @fields[field_name] = value
            starts_with(field_name, value[0,index])

Trace:

aws-sdk-s3 (1.30.1) lib/aws-sdk-s3/presigned_post.rb:552:in `with'
aws-sdk-s3 (1.30.1) lib/aws-sdk-s3/presigned_post.rb:261:in `block in define_field'
aws-sdk-s3 (1.30.1) lib/aws-sdk-s3/presigned_post.rb:224:in `block in initialize'
aws-sdk-s3 (1.30.1) lib/aws-sdk-s3/presigned_post.rb:220:in `each'
aws-sdk-s3 (1.30.1) lib/aws-sdk-s3/presigned_post.rb:220:in `initialize'
aws-sdk-s3 (1.30.1) lib/aws-sdk-s3/customizations/object.rb:128:in `new'
aws-sdk-s3 (1.30.1) lib/aws-sdk-s3/customizations/object.rb:128:in `presigned_post'
shrine (2.15.0) lib/shrine/storage/s3.rb:220:in `presign'
shrine (2.15.0) lib/shrine/plugins/presign_endpoint.rb:112:in `generate_presign'
shrine (2.15.0) lib/shrine/plugins/presign_endpoint.rb:81:in `handle_request'
shrine (2.15.0) lib/shrine/plugins/presign_endpoint.rb:65:in `block in call'
shrine (2.15.0) lib/shrine/plugins/presign_endpoint.rb:61:in `catch'
shrine (2.15.0) lib/shrine/plugins/presign_endpoint.rb:61:in `call'
actionpack (5.2.2) lib/action_dispatch/routing/mapper.rb:19:in `block in <class:Constraints>'
actionpack (5.2.2) lib/action_dispatch/routing/mapper.rb:48:in `serve'
actionpack (5.2.2) lib/action_dispatch/journey/router.rb:52:in `block in serve'
actionpack (5.2.2) lib/action_dispatch/journey/router.rb:35:in `each'
actionpack (5.2.2) lib/action_dispatch/journey/router.rb:35:in `serve'
actionpack (5.2.2) lib/action_dispatch/routing/route_set.rb:840:in `call'
bullet (5.9.0) lib/bullet/rack.rb:15:in `call'
rack (2.0.6) lib/rack/deflater.rb:34:in `call'
warden (1.2.8) lib/warden/manager.rb:36:in `block in call'
warden (1.2.8) lib/warden/manager.rb:34:in `catch'
warden (1.2.8) lib/warden/manager.rb:34:in `call'
rack (2.0.6) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.0.6) lib/rack/etag.rb:25:in `call'
rack (2.0.6) lib/rack/conditional_get.rb:25:in `call'
rack (2.0.6) lib/rack/head.rb:12:in `call'
actionpack (5.2.2) lib/action_dispatch/http/content_security_policy.rb:18:in `call'
rack (2.0.6) lib/rack/session/abstract/id.rb:232:in `context'
rack (2.0.6) lib/rack/session/abstract/id.rb:226:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/cookies.rb:670:in `call'
activerecord (5.2.2) lib/active_record/migration.rb:559:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
activesupport (5.2.2) lib/active_support/callbacks.rb:98:in `run_callbacks'
actionpack (5.2.2) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/debug_exceptions.rb:61:in `call'
web-console (3.7.0) lib/web_console/middleware.rb:135:in `call_app'
web-console (3.7.0) lib/web_console/middleware.rb:30:in `block in call'
web-console (3.7.0) lib/web_console/middleware.rb:20:in `catch'
web-console (3.7.0) lib/web_console/middleware.rb:20:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (5.2.2) lib/rails/rack/logger.rb:38:in `call_app'
railties (5.2.2) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (5.2.2) lib/active_support/tagged_logging.rb:71:in `block in tagged'
activesupport (5.2.2) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (5.2.2) lib/active_support/tagged_logging.rb:71:in `tagged'
railties (5.2.2) lib/rails/rack/logger.rb:26:in `call'
sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.0.6) lib/rack/method_override.rb:22:in `call'
rack (2.0.6) lib/rack/runtime.rb:22:in `call'
activesupport (5.2.2) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (5.2.2) lib/action_dispatch/middleware/static.rb:127:in `call'
rack (2.0.6) lib/rack/sendfile.rb:111:in `call'
railties (5.2.2) lib/rails/engine.rb:524:in `call'
puma (3.12.0) lib/puma/configuration.rb:225:in `call'
puma (3.12.0) lib/puma/server.rb:658:in `handle_request'
puma (3.12.0) lib/puma/server.rb:472:in `process_client'
puma (3.12.0) lib/puma/server.rb:332:in `block in run'
puma (3.12.0) lib/puma/thread_pool.rb:133:in `block in spawn_thread'

System configuration

Ruby version:
2.5.3
Shrine version:
2.15.0

Most helpful comment

This presign_endpoint configuration assumes that the presign request will include additional filename and type query params, containing the original filename and MIME type. When Uppy makes that presign request, it automatically includes those query parameters.

So, when you make the request with Insomnia, you need to include the filename and type parameters. Actually, just type is required, as filename being nil should be handled by the ContentDisposition gem.

>All comments

This presign_endpoint configuration assumes that the presign request will include additional filename and type query params, containing the original filename and MIME type. When Uppy makes that presign request, it automatically includes those query parameters.

So, when you make the request with Insomnia, you need to include the filename and type parameters. Actually, just type is required, as filename being nil should be handled by the ContentDisposition gem.

Was this page helpful?
0 / 5 - 0 ratings