Routing Error with Post/Put requests (Passenger Headers)

ぃ、小莉子 提交于 2019-11-30 21:34:32

Create passenger_extension.rb in the lib folder with this code:

Passenger 3

module PhusionPassenger
  module Utils

    protected

    NULL = "\0".freeze

    def split_by_null_into_hash(data)
      args = data.split(NULL, -1)
      args.pop
      headers_hash = Hash.new
      args.each_slice(2).to_a.each do |pair|
        headers_hash[pair.first] = pair.last unless headers_hash.keys.include? pair.first
      end
      return headers_hash
    end

  end
end

Passenger 5

module PhusionPassenger
  module Utils

    # Utility functions that can potentially be accelerated by native_support functions.
    module NativeSupportUtils
      extend self

      NULL = "\0".freeze

      class ProcessTimes < Struct.new(:utime, :stime)
      end

      def split_by_null_into_hash(data)
        args = data.split(NULL, -1)
        args.pop
        headers_hash = Hash.new
        args.each_slice(2).to_a.each do |pair|
          headers_hash[pair.first] = pair.last unless headers_hash.keys.include? pair.first
        end
        return headers_hash
      end

      def process_times
        times = Process.times
        return ProcessTimes.new((times.utime * 1_000_000).to_i,
          (times.stime * 1_000_000).to_i)
      end
    end

  end # module Utils
end # module PhusionPassenger

And then in 'config/application.rb' do:

class Application < Rails::Application
  ...
  config.autoload_paths += %W(#{config.root}/lib)
  require 'passenger_extension'
end

And then restart a webserver.

NOTICE: I'm not sure that this doesn't break any other functionality so use it on your own risk and please let me know if you find any harm from this approach.

One issue here is you're not specifying whether the route is defined on the collection or a member. Which one of these is the correct route?

programs/:id/add_file

programs/add_file

You should construct your routes like this:

resources :programs do
  post 'add_file', :on => :member
end

or

resources :programs do
  member do
    post 'add_file'
  end
end

The above will take post requests at programs/:id/add_file and send them to ProgramsController.add_file with the params[:id] as the program id.

If you want this on the collection, you could do:

resources :programs do
  post 'add_file', :on => :collection
end

or

resources :programs do
  collection do
    post 'add_file'
  end
end

This would take post requests at programs/add_file and send them to ProgramsController.add_file, but no params[:id] would be set.

In general you should always specify whether routes are on the collection or member, and you should specify which verb a route should accept (ie use 'get' or 'post' etc. instead of 'match').

Try the above and see if that solves your problem, if not please let me know and I'll take another look.

I think you may need to add

:via => [:post]

to your route specification. It seems odd that it'd work on development and not on production, but as I understand rails routing, the matcher that you've added is only going to respond to get.

Try changing your match to

match "add_file" => "programs#add_file", :via => [:post]

Also, based on the answer just submitted by Andrew, you're probably better off using the member specifier to be explicit about the fact that the operation is happening on a particular Program with a particular id, and not the collection. It also should save some code in your add_file method which is probably working hard to get the id parameter from the url.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!