My Resque Job can't connect to localhost to POST request...
When I try UserCreatorJob.perform_now(options) it runs ok.
When I use UserCreatorJob.perform_later(options) it goes to the resque queue and than, when performing, it fails with Connection refused - connect(2) for "fe80::1%lo0" port 3000
user_creator_job.rb
class UserCreatorJob < Jobs::ApplicationJob
queue_as :user
def perform(*args)
conn :post, 'api/v1/users', args
end
def conn
Faraday.new(url: 'http://localhost:3000') do |faraday|
faraday.request :url_encoded # form-encode POST params
faraday.response :logger # log requests to STDOUT
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
faraday.token_auth('')
end
end
end
If I perform the post with CURL everything goes as expected.
I think resque may not like posting to localhost.
Try adding this line to your /etc/hosts file:
127.0.0.1 my.api.dev
Then, in your code, replace http://localhost:3000 with http://my.api.dev:3000
Related
Using Rails 4.2.3, Rspec 3
I want to pass post params to a fake Rack app to respond accordingly in my tests.
My Fake app:
# spec/support/fake_mangopay.rb
class FakeMangopay < Sinatra::Base
attr_accessor :user
post '/:version/oauth/token' do
json_response :post, 200, 'token.json'
end
...
private
def json_response(method, response_code, file_name)
content_type :json
status response_code
File.open("#{File.dirname(__FILE__)}/fixtures/mangopay/#{method}/#{file_name}", 'rb').read
end
end
How I stub the requests:
# spec/spec_helper
config.before(:each) do
stub_request(:any, /api.sandbox.mangopay.com/).to_rack(FakeMangopay)
...
end
I currently have simple (and static) JSON files, and I would like to make them json.erb files.
But I don't know how to get those post parameters..
Help?
Found out that I can access request.body to get what I want.
params = JSON.parse request.body.read
I'm working on setting up a webhook from Stripe. Essentially because it's a subscription model and I need to know if I shall keep on renewing the month or not. I'd like to do that through the event 'invoice.payment_succeeded'.
When I test my webhook url in stripe I get this:
host localhost:3000 resolves to illegal IP 127.0.0.1
my full endpoint is:
localhost:3000/hooks/receiver
route:
get 'hooks/receiver' => "hooks#receiver"
and the hooks controller looks like this:
class HooksController < ApplicationController
require 'json'
Stripe.api_key
def receiver
data_json = JSON.parse request.body.read
p data_json['data']['object']['customer']
if data_json[:type] == 'invoice.payment_succeded'
make_active(data_event)
end
if data_json[:type] == 'invoice.payment_failed'
# something make_inactive(data_event)
end
end
def make_active(data_event)
#user = User.find_by_customer_token(data['data']['object']['customer'])
#status = #user.statuses.pluck(:list_id).presence || -1
Resque.enqueue(ScheduleTweets, #user.token, #user.id, #status)
end
def make_inactive(data_event)
end
end
Does anybody know how to fix this?
You cannot use 127.0.0.1 or localhost as a webhook in Stripe. A webhook involves Stripe sending data from their serves to yours, but your 127.0.0.1 isn't available to Stripe since only you can access localhost.
You could use something like ngrok to open your localhost to the interwebs
https://ngrok.com/
I have here a model helper named GmailGcalendar
I have multiple actions in 2 models namely gmail.rb and pivotaltracker.rb
They do the same functions, but the only difference is the connection url.
In my lib helper:
def connection_url
if API::Pivotaltracker
'https://www.pivotaltracker.com'
else
'https://accounts.google.com'
end
end
def my_connections
connection_name ||= Faraday.new(:url => "#{connection_url}" , ssl: {verify: false}) do |faraday|
faraday.request :url_encoded # form-encode POST params
faraday.response :logger # log requests to STDOUT
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
end
puts "####"
puts connection_url
end
And in my gmail.rb
def connection
my_connections
end
As well as my pivotaltracker.rb
def connection
my_connections
end
Now they have different connection url.
Pivotal goes to https://www.pivotaltracker.com
Gmail goes to https://accounts.google.com
But I seem to can't make the condition work in connection_url action.
Any workarounds will be appreciated.
EDIT:
I am using the connection_url here: ( in the Faraday block )
def my_connections
connection_name ||= Faraday.new(:url => "#{connection_url}" , ssl: {verify: false}) do |faraday|
faraday.request :url_encoded # form-encode POST params
faraday.response :logger # log requests to STDOUT
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
end
puts "####"
puts connection_url
end
Your can rewrite your lib helper as class:
class Connection
def initialize(url)
#url = url
end
def setup
connection_name ||= Faraday.new(:url => "#url" , ssl: {verify: false}) do |faraday|
faraday.request :url_encoded # form-encode POST params
faraday.response :logger # log requests to STDOUT
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
end
end
end
Now in the model you can initialize this class with the url you want, for example:
def connection
Connection.new("https://accounts.google.com").setup
end
I didn't test this code, but it should work.
I am coding in Ruby-on-Rails
I would like to send a http request to another service but not wait for a response.
Pseudocode:
def notification
require 'net/http'
...
# send net/http request
Net::HTTP.post_form(url, params)
render :text => "Rendered quickly as did not wait for response from POST"
end
Is there any way to send the POST request and not wait for a response and just to quickly render the page?
You can try delayed_job. It is mainly used to run processes in background. Once you install delayed_job you can do like this.
require 'net/http'
def notification
...
your_http_request #calling method
render :text => "Rendered quickly as did not wait for response from POST"
end
def your_http_request
# send net/http request
Net::HTTP.post_form(url, params)
#do your stuff like where to save response
end
handle_asynchronously :your_http_request
So currently I am manually directing from a naked domain due to restrictions with my hosting provider (Heroku). Everything works just fine. The problem is that if a users visits mydomain.com/route, a redirect will be issued back to www.mydomain.com without the /route. How would I go about re-appending the route, but still redirecting to www. ?
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :ensure_domain
APP_DOMAIN = 'www.domain.com'
def index
end
def ensure_domain
if Rails.env.production?
if request.env['HTTP_HOST'] != APP_DOMAIN
redirect_to "http://#{APP_DOMAIN}", :status => 301
end
end
end
end
EDIT
I removed my code above from my ApplicationController, and opted for using the refraction gem as suggested by hurikhan77, which solved my problem.
Here is refraction_rules.rb I used.
Refraction.configure do |req|
if req.host == "domain.com"
req.permanent! :host => "www.domain.com"
end
end
I suggest using the refraction gem for this: http://rubygems.org/gems/refraction
Ideally, you would set up rules like that in your web server configuration. Requests would become faster, because they would not even reach the rails stack. There would be no need to add any code to your app either.
However, if you are running in some restricted environment, like heroku, I'd advise adding a rack middleware. (Just for guidelines, can't guarantee if this particular code is bug free)
class Redirector
SUBDOMAIN = 'www'
def initialize(app)
#app = app
end
def call(env)
#env = env
if redirect?
redirect
else
#app.call(env)
end
end
private
def redirect?
# do some regex to figure out if you want to redirect
end
def redirect
headers = {
"location" => redirect_url
}
[302, headers, ["You are being redirected..."]] # 302 for temp, 301 for permanent
end
def redirect_url
scheme = #env["rack.url_scheme"]
if #env['SERVER_PORT'] == '80'
port = ''
else
port = ":#{#env['SERVER_PORT']}"
end
path = #env["PATH_INFO"]
query_string = ""
if !#env["QUERY_STRING"].empty?
query_string = "?" + #env["QUERY_STRING"]
end
host = "://#{SUBDOMAIN}." + domain # this is where we add the subdomain
"#{scheme}#{host}#{path}#{query_string}"
end
def domain
# extract domain from request or get it from an environment variable etc.
end
end
You can also test the whole thing in isolation
describe Redirector do
include Rack::Test::Methods
def default_app
lambda { |env|
headers = {'Content-Type' => "text/html"}
headers['Set-Cookie'] = "id=1; path=/\ntoken=abc; path=/; secure; HttpOnly"
[200, headers, ["default body"]]
}
end
def app()
#app ||= Rack::Lint.new(Redirector.new(default_app))
end
it "redirects unsupported subdomains" do
get "http://example.com/zomg?a=1"
last_response.status.should eq 301
last_response.header['location'].should eq "http://www.example.com/zomg?a=1"
end
# and so on
end
Then you can add it to production (or any preferred environments) only
# production.rb
# ...
config.middleware.insert_after 'ActionDispatch::Static', 'Redirector'
If you want to test it in development, add the same line to development.rb and add a record to your hosts file (usually /etc/hosts) to treat yoursubdomain.localhost as 127.0.0.1
Not sure if this is the best solution but you could regex the request.referrer and pull out anything after .com and append it to the APP_DOMAIN
Or I guess you could just take out everything before the first . in request.env['HTTP_HOST'] add replace with http://www. assuming you don't plan on using subdomains.