invalid %-encoding with file upload

Trying to upload an image and attach to relation using shrine. When I submit the form I get an invalid %-encoding error from Rack::QueryParser::InvalidParameterError. Can create an entity when I skip the file upload input and just use the other inputs.
Trying to use the Rack::UTF8Sanitizer but I can’t get it to run before the Query Parser. Config.middleware use makes it run after the QueryParser. I tried using prepend which the docs claim would make it run first but I get an undefined method “prepend” error when I try it.

Hi @joeradtke, I’d be happy to take a look into this, but it would be useful if you could provide a reproduction of the issue. Can you make a small sample app, or at bare minimum, share some of the relevant code? That would include things like your form markup, the action, plus any relevant action or app config.

APP>RB

frozen_string_literal: true

require “hanami”
require “warden”

module H22
class App < Hanami::App
require_relative ‘…/app/middlewares/handle_bad_encoding_middleware.rb’
require “rack/utf8_sanitizer”
config.actions.sessions = :cookie, {
key: “libus.session”,
secret: settings.session_secret,
expire_after: 606024*365
}
config.middleware.use Rack::UTF8Sanitizer,strategy: :replace_string
config.middleware.use Warden::Manager do |manager|
manager.default_strategies :password
manager.failure_app =
lambda do |env|
H22::Actions::AuthFailure::Show.new.call(env)
end
end

end
end

FORM

new page

<%= form_for :page, routes.path(:pages_create) do |f| %>
<%= f.label "Name", for: :name %> <%= f.text_field :name %>
<%= f.label "Title", for: :title %> <%= f.text_field :title %>
<%= f.label "Body", for: :body %> <%= f.text_area :body %>
<%= f.label "Image", for: :image %> <%= f.file_field :image %>
<%= f.submit "SAVE PAGE" %>
<%end%>

CREATE ACTION

frozen_string_literal: true

module H22
module Actions
module AdminPages
class Create < H22::AdminAction
include Deps[pages_repo: “repositories.pages”]

    params do
      required(:page).hash do
        required(:name).filled(:string)
        required(:title).filled(:string)
        required(:body).filled(:string)
        optional(:file)
      end
    end
    
    def handle(request, response)
      if pages_repo.name_taken?(request.params[:page][:name])
        halt 422, { errors: "This name is already taken" }.to_json
      end
      
      if request.params.valid?
        pages_repo.create(
          name: request.params[:page][:name],
          title: request.params[:page][:title],
          body: request.params[:page][:body],

        )
        
        response.flash[:notice]="Page saved!"
        response.redirect_to("/admin/pages") 
      else
        errors=request.params.errors
        halt 422
      end
    end
  end
end

end
end

I haven’t hooked up much of the Shrine stuff yet as I can’t even get the app to accept my file input.
I’ve been trying to use the Rack::UTF8Sanitizer to run first in the middleware stack but have been unable to do so.If I add the before: to get it first in the stack I get an uninitialized constant error for DRY::MONITOR which is the first item in the stack.

I don’t think many people are using files with Hanami as I was only able to find one article about it and its pretty specialized.

Thanks @joeradtke. I’ll take a look when I can. In the meantime, could you please use the Discourse formatting syntax so your posts are more readable? It’s very hard to understand things in the current state.

I’m not aware of the Discourse formatting syntax. I’ll try to figure out what it is.

Sorry

Thanks for this, @joeradtke. Some pointers:

If you’re familiar with the kind of Markdown you would write into GitHub issues/comments, it’s basically just that.

I’m not familar with Markdown.

I think I know what the problem is… It appears that the Rack Parser is only loaded if you have json output on an action. I used some article to make some of this stuff and have json outputs for some of the error handling. I guess the Parser is parsing my file. If I didn’t have the Rack Parser I’d probably be ok. Do you know if removing the json stuff would make the Rack Parser go away or do I have to start over?

I’ve isolated the problem. If I use the helper form_for with a file_input I get the error. If I just make a html form without the helper I can submit a file with no parsing error. I guess the solution for now is to not use the form helper.

Incidentally, when you create a hanami app now it uses hanami 2.2beta with sqllite. If you try to use mysql2 as the database you get an error that there is no sequel adapter for mysql2.