Ajax request sent via GET even if method is POST - ruby-on-rails

I have ran in to this strange bug in my production environment. I had several AJAX requests in my Ruby on Rails application with GET methods, now I decided to change this security error holes. I changed most of the requests to POST. Everything works just fine in local environment and in demo environment, which is almost the same as the production environment.
Request: (CoffeeScript)
$(".vehicle_make_dropdown").on "change", ->
$.ajax(
url: "/get_maker_models"
data:
maker: $("#entry_vehicle_make").val()
method: "POST" // this was "GET" before!
dataType: "JSON"
).success( (json) ->
i = 0
$(".vehicle_model_dropdown").html("")
$(".vehicle_model_dropdown").prop("disabled", false)
while(i < json.length)
$(".vehicle_model_dropdown").append("<option value='#{json[i]["title"]}'>#{json[i]['title']}</option>")
i++
).error( (resp) ->
console.log("error")
)
Reciever: (Ruby (RoR))
def get_maker_models
#models = VehicleMaker.find_by(title: params[:maker]).vehicle_models.order("title ASC")
render json: #models
end
Route:
post "get_maker_models" => 'credit_form#get_maker_models'
but in logs i still se this:
I, [2014-09-18T14:08:47.852487 #28300] INFO -- : Started GET "/get_maker_models/" for 80.232.253.212 at 2014-09-18 14:08:47 +0400
I, [2014-09-18T14:08:47.856224 #28300] INFO -- : Processing by ApplicationController#routing_error as JSON
I, [2014-09-18T14:08:47.856329 #28300] INFO -- : Parameters: {"path"=>"get_maker_models"}
I, [2014-09-18T14:08:47.863482 #28300] INFO -- : Rendered error/404.html.erb within layouts/application (1.1ms)
I, [2014-09-18T14:08:47.868535 #28300] INFO -- : Rendered layouts/shared/_audit_start.html.haml (1.1ms)
I, [2014-09-18T14:08:47.882499 #28300] INFO -- : Rendered layouts/shared/_main_menu.html.haml (1.5ms)
I, [2014-09-18T14:08:47.882696 #28300] INFO -- : Rendered layouts/shared/_header.html.haml (11.7ms)
I, [2014-09-18T14:08:47.902478 #28300] INFO -- : Rendered layouts/shared/_mini_faq.html.haml (8.9ms)
I, [2014-09-18T14:08:47.907767 #28300] INFO -- : Rendered layouts/shared/_main_menu.html.haml (0.4ms)
I, [2014-09-18T14:08:47.914008 #28300] INFO -- : Rendered layouts/shared/_scripts.html.erb (1.1ms)
I, [2014-09-18T14:08:47.914220 #28300] INFO -- : Rendered layouts/shared/_footer.html.haml (29.0ms)
I, [2014-09-18T14:08:47.917616 #28300] INFO -- : Rendered layouts/shared/_audit_end.html.haml (0.9ms)
I, [2014-09-18T14:08:47.917902 #28300] INFO -- : Completed 404 Not Found in 61ms (Views: 55.6ms | ActiveRecord: 3.3ms)
I have tried:
Deploying older version and than again the current one
Restarting unicorn few times. Nothing seems to work,
Tried Incognito mode in Chrome.
Recompiled assets with production environmtt.
EDIT:
In ajax request i changed method to type

When rebuilding assets, did you specify environment? As rake assets:precompile RAILS_ENV=production?
EDIT:
$.ajax Should have type for specifying type of the request instead of method.
The default is GET, so probably that is the issue here.
http://api.jquery.com/jquery.ajax/

Related

When a user logs into my Ruby app on Heroku, it seems to get stuck in a loop. This does not happen for guest users. Can anyone advise?

So, long story short - I'm comfortable with HTML, CSS, SQL a bit of Javascript etc as a hobby, but am far from a 'proper' developer. Recently a friend paid a developer to build a web app for them (the friend have no IT skills at all). The developer (who is no longer on the scene) left them with a working demo in Heroku and a GitHub repo which I have now cloned. My friend wanted some of the cosmetic bits changing, which I offered to help with, but in order to do this, I had to create my own version of the app on Heroku from my forked repo.
I couldn't get this to work, kept getting an error message when trying to deploy the app, despite the code being completely unchanged from the parent. I should mention now that the app has been written in Ruby, with which I have zero experience. But I thought I'd have a go anyway...
After much Googling, I managed to get the app to successfully deploy by changing the version of #rails/webpacker in the package.json file. I then changed any references to originalApp.herokuapps.com to myNewVersion.herokuapps.com.
After this, I had to set some Config Vars in Heroku (relating to gmail and stripe) to get things up and running. This all seemed to work ok...
So I'm now at the point where a user can sign up on the app and subscribe to the service using Stripe (test) and is successfully sent a confirmation email.
However, once a user is logged in, anytime they try to go to any other page, for example the 'About Us' or 'Contact Us' page, it immediately redirects (or stays) on the same page. There's no other pages the logged-in user can access. However, if I log out, then the 'guest' user can navigate to the other pages freely.
Example:
If I'm logged in, the URL shows https://myproject.herokuapp.com/start and the contents of the page are what the user was presented with after signing up and paying the Stripe fee.
If they then click on, for example, the 'About Us' link, the log shows this (I've edited the URLs to show myproject instead of the real project name):
2022-01-05T22:16:29.805824+00:00 app[web.1]: I, [2022-01-05T22:16:29.805699 #4] INFO -- : [0efc978f-35cf-4d11-ae66-edbdb5b26ec4] Started GET "/about-us" for 90.197.167.151 at 2022-01-05 22:16:29 +0000
2022-01-05T22:16:29.806538+00:00 app[web.1]: I, [2022-01-05T22:16:29.806485 #4] INFO -- : [0efc978f-35cf-4d11-ae66-edbdb5b26ec4] Processing by PagesController#about_us as HTML
2022-01-05T22:16:29.809496+00:00 app[web.1]: D, [2022-01-05T22:16:29.809430 #4] DEBUG -- : [0efc978f-35cf-4d11-ae66-edbdb5b26ec4] [1m[36mUser Load (0.7ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2[0m [["id", 1], ["LIMIT", 1]]
2022-01-05T22:16:29.810151+00:00 app[web.1]: I, [2022-01-05T22:16:29.810102 #4] INFO -- : [0efc978f-35cf-4d11-ae66-edbdb5b26ec4] Redirected to https://myproject.herokuapp.com/start
2022-01-05T22:16:29.810227+00:00 app[web.1]: I, [2022-01-05T22:16:29.810201 #4] INFO -- : [0efc978f-35cf-4d11-ae66-edbdb5b26ec4] Filter chain halted as :check_subscription rendered or redirected
2022-01-05T22:16:29.810322+00:00 app[web.1]: I, [2022-01-05T22:16:29.810300 #4] INFO -- : [0efc978f-35cf-4d11-ae66-edbdb5b26ec4] Completed 302 Found in 4ms (ActiveRecord: 0.7ms | Allocations: 964)
2022-01-05T22:16:29.835064+00:00 app[web.1]: I, [2022-01-05T22:16:29.834991 #4] INFO -- : [a7c07664-645b-449c-a9a8-a50a2c060f3b] Started GET "/start" for 90.197.167.151 at 2022-01-05 22:16:29 +0000
2022-01-05T22:16:29.835712+00:00 app[web.1]: I, [2022-01-05T22:16:29.835663 #4] INFO -- : [a7c07664-645b-449c-a9a8-a50a2c060f3b] Processing by CheckoutsController#start as HTML
2022-01-05T22:16:29.836943+00:00 app[web.1]: I, [2022-01-05T22:16:29.836887 #4] INFO -- : [a7c07664-645b-449c-a9a8-a50a2c060f3b] Rendering checkouts/start.html.erb within layouts/application
2022-01-05T22:16:29.839055+00:00 app[web.1]: D, [2022-01-05T22:16:29.838940 #4] DEBUG -- : [a7c07664-645b-449c-a9a8-a50a2c060f3b] [1m[36mUser Load (0.7ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2[0m [["id", 1], ["LIMIT", 1]]
2022-01-05T22:16:29.839685+00:00 app[web.1]: I, [2022-01-05T22:16:29.839609 #4] INFO -- : [a7c07664-645b-449c-a9a8-a50a2c060f3b] Rendered checkouts/start.html.erb within layouts/application (Duration: 2.6ms | Allocations: 401)
2022-01-05T22:16:29.841324+00:00 app[web.1]: I, [2022-01-05T22:16:29.841270 #4] INFO -- : [a7c07664-645b-449c-a9a8-a50a2c060f3b] Rendered shared/_navbar.html.erb (Duration: 0.9ms | Allocations: 905)
2022-01-05T22:16:29.841552+00:00 app[web.1]: I, [2022-01-05T22:16:29.841516 #4] INFO -- : [a7c07664-645b-449c-a9a8-a50a2c060f3b] Completed 200 OK in 6ms (Views: 4.1ms | ActiveRecord: 0.7ms | Allocations: 2433)
2022-01-05T22:16:29.816017+00:00 heroku[router]: at=info method=GET path="/about-us" host=myproject.herokuapp.com request_id=0efc978f-35cf-4d11-ae66-edbdb5b26ec4 fwd="90.197.167.151" dyno=web.1 connect=0ms service=6ms status=302 bytes=1393 protocol=https
As said, I'm not familiar with Ruby at all, but I suspect it's something to do with the lines that mention:
Redirected to https://myproject.herokuapp.com/start
Filter chain halted as :check_subscription rendered or redirected
You can see it's trying to go to the /about-us page but it remains on /start.
I believe the app uses something called 'Devise' for the user registration process.
Given the code is the same as the parent repo that I forked from, I'm guessing the issue is either a setting within Heroku or some kind of variable that I'm missing or have not updated. If anyone can advise me on next steps with regards to research or a solution, I'd be very grateful. I appreciate I'm no expert, but I'm just trying to do a friend a favour after they've been left hanging by another dev. Many Thanks.
Update:
application_controller.rb
before_action :authenticate_user!, :halt_if_mobile
before_action :check_subscription, except: %i[ home start ]
def halt_if_mobile
if browser.device.mobile?
render inline: "Mobile access is currently disabled"
return
end
end
def check_subscription
return unless current_user
return if controller_path =~ /devise/ || controller_path =~ /registrations/
if !current_user.active
redirect_to start_path, notice: 'Please update your payment settings'
return
end
end
end

Rails - Server Blocking on Action Cable

I have a Rails app that works perfectly in development. I have deployed to the server and the app loads and correctly shows its landing and about pages. However, when I go to a page with Action Cable, the server blocks. The last request out from the web page is Action Cable related, and further page actions (form submission, and even reloads) and not responded to.
I have isolated it to the server as attempting to load the site's main page from another browser does not work. Closing the tab where the request to Action Cable was first made results in the other page loading immediately (and all of the pending requests from the first page suddenly being processed).
I do not see any errors in production.log, but here is the part leading up to the hang:
I, [2018-01-24T21:12:38.601260 #9840] INFO -- : [86b3fcc1-cebd-4d70-99ff-b6f9f147bc00] Rendered collection of skill_checks/_skill_check.html.erb [5 times] (16.7ms)
I, [2018-01-24T21:12:38.601352 #9840] INFO -- : [86b3fcc1-cebd-4d70-99ff-b6f9f147bc00] Rendered rooms/show.html.erb within layouts/application (26.6ms)
I, [2018-01-24T21:12:38.602314 #9840] INFO -- : [86b3fcc1-cebd-4d70-99ff-b6f9f147bc00] Completed 200 OK in 32ms (Views: 26.7ms | ActiveRecord: 1.8ms)
I, [2018-01-24T21:12:38.740061 #9840] INFO -- : [5a06a7d8-a4a5-4ab4-8287-377dfa3447fe] Started GET "/cable" for 65.99.102.74 at 2018-01-24 21:12:38 +0000
I, [2018-01-24T21:12:38.740860 #9840] INFO -- : [5a06a7d8-a4a5-4ab4-8287-377dfa3447fe] Started GET "/cable/" [WebSocket] for 65.99.102.74 at 2018-01-24 21:12:38 +0000
I, [2018-01-24T21:12:38.740970 #9840] INFO -- : [5a06a7d8-a4a5-4ab4-8287-377dfa3447fe] Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket)
I, [2018-01-24T21:12:38.794498 #9840] INFO -- : RoomsChannel is transmitting the subscription confirmation
I, [2018-01-24T21:12:38.795245 #9840] INFO -- : RoomsChannel is streaming from room_helloworld
Once I close the offending tab, load continues (in this case, of a javascript request that was triggered on page reload) as follows:
I, [2018-01-24T21:15:55.109087 #9840] INFO -- : Finished "/cable/" [WebSocket] for 65.99.102.74 at 2018-01-24 21:15:55 +0000
I, [2018-01-24T21:15:55.109342 #9840] INFO -- : RoomsChannel stopped streaming from room_helloworld
I, [2018-01-24T21:15:55.110922 #9840] INFO -- : [2cf5cc53-2f44-42a9-be30-496bb80646a0] Started GET "/rooms/helloworld?update=true" for 65.99.102.74 at 2018-01-24 21:15:55 +0000
I, [2018-01-24T21:15:55.112841 #9840] INFO -- : [2cf5cc53-2f44-42a9-be30-496bb80646a0] Processing by RoomsController#show as HTML
I've truncated the remainder; there were no failures or anything else of interest in there.
I do have a redis server running on the same server and have put its port information into config/cable.yml under the production: section.
I believe that Rails can see it as I haven't seen any errors. Additionally, to verify this I connected to redis through redis-cli and subscribed to a channel, and then through the Rails console sent a broadcast message to that channel and verified receipt.
Update: I've tried a few different builds to isolate the issue. Here's what I now know:
I removed my only call to ActionCable.server.broadcast, so that isn't the source of the block.
I added javascript console logs to connected, disconnected, and received. The client does successfully subscribe.
I tried a build where I removed the App.cable.subscriptions.create from the client. While there is no websocket connection in this case (as you would expect), the server does not block/hang.
Given the above, I am certain this has to do with ActionCable, though I'm not sure if it has anything to do with my redis configuration.
This turned out the be the behaviour you get if you haven't set the following lines inside of your nginx conf file (inside of the server section):
location /cable {
passenger_app_group_name your_app_websocket;
passenger_force_max_concurrent_requests_per_process 0;
}
where, if your app name is "chat", the first line would read:
passenger_app_group_name chat_action_cable
Which, frankly, I'm not sure where is defined, but it may be part of the Rails magic.

Rails flash is missing eventually. Isn`t it thread-safe?

I have Rails application running on Thin with multithreading. There is a bunch of polling requests and sometimes, when running integration tests concurrent I have about 1-2% of missing flash failures. In my production.log I have something like the following in case of failure:
I, [2017-08-21T23:31:51.280455 #2146] INFO -- : Redirected to http://192.168.102.1/projects/599bcfd4875aa40862863a5b
I, [2017-08-21T23:31:51.282501 #2146] INFO -- : Rendered text template (0.1ms)
I, [2017-08-21T23:31:51.283151 #2146] INFO -- : Completed 200 OK in 3062ms (Views: 1.4ms)
I, [2017-08-21T23:31:51.309004 #23906] INFO -- : Rendered projects/_tests_block.html.haml (24.0ms)
I, [2017-08-21T23:31:51.309392 #23906] INFO -- : Rendered projects/show.js.haml within layouts/application (29.9ms)
I, [2017-08-21T23:31:51.318025 #23906] INFO -- : Completed 200 OK in 124ms (Views: 48.4ms)
I, [2017-08-21T23:31:51.318956 #2146] INFO -- : Started GET "/projects/599bcfd4875aa40862863a5b" for 192.168.102.2 at 2017-08-21 23:31:51 -0700
I, [2017-08-21T23:31:51.321849 #2146] INFO -- : Processing by ProjectsController#show as HTML
I, [2017-08-21T23:31:51.321994 #2146] INFO -- : Parameters: {"id"=>"599bcfd4875aa40862863a5b"}
My redirect call looks like redirect_to #project, notice: success_message
Between redirect and start of getting show page I have the finish of polling request from another page. In this case when show page is rendered, there is no flash[:notice].
I tried to keep and clear flash explicitly, so there is before_filter { flash.keep } in ApplicationController and flash.clear in my notification partial.
I also tried to log flashes before every action and in this concurrent case no another action steals flash, it's just missing.
Is this a multithreading problem? Or maybe I should use or implement flash with kind of "destination"? So that should be thread-safe too anyway.
PS Ruby 2.3.4, Rails 4.2.7, Thin 1.5.1

Frequent unexpected requests logged by Rails app in EC2 - from Amazon public IP addresses - Why?

I'm running a rails app that writes files to Amazon S3. Now I have uniqorn running as server and see all lots of request coming in from different amazon AWS IP-addresses.
Here is a part of my log file:
Started GET "/" for 54.245.168.11 at 2016-10-02 18:30:50 +0000
Processing by StaticPagesController#home as */*
Rendered static_pages/home.html.erb within layouts/application (0.2ms)
Rendered layouts/_shim.html.erb (0.1ms)
Rendered layouts/_header.html.erb (0.3ms)
Completed 200 OK in 3ms (Views: 3.0ms | ActiveRecord: 0.0ms)
Started GET "/" for 54.252.254.235 at 2016-10-02 18:30:51 +0000
Processing by StaticPagesController#home as */*
Rendered static_pages/home.html.erb within layouts/application (0.2ms)
Rendered layouts/_shim.html.erb (0.0ms)
Rendered layouts/_header.html.erb (0.3ms)
Completed 200 OK in 3ms (Views: 3.0ms | ActiveRecord: 0.0ms)
Started GET "/" for 54.232.40.107 at 2016-10-02 18:30:52 +0000
Processing by StaticPagesController#home as */*
Rendered static_pages/home.html.erb within layouts/application (0.7ms)
Rendered layouts/_shim.html.erb (0.2ms)
Rendered layouts/_header.html.erb (1.8ms)
Completed 200 OK in 12ms (Views: 10.6ms | ActiveRecord: 0.0ms)
Started GET "/" for 54.252.79.139 at 2016-10-02 18:30:52 +0000
Processing by StaticPagesController#home as */*
Rendered static_pages/home.html.erb within layouts/application (0.7ms)
Rendered layouts/_shim.html.erb (0.3ms)
Rendered layouts/_header.html.erb (1.5ms)
Completed 200 OK in 13ms (Views: 11.6ms | ActiveRecord: 0.0ms)
Started GET "/" for 54.250.253.203 at 2016-10-02 18:30:52 +0000
Processing by StaticPagesController#home as */*
Rendered static_pages/home.html.erb within layouts/application (0.5ms)
Rendered layouts/_shim.html.erb (0.1ms)
Rendered layouts/_header.html.erb (0.3ms)
Completed 200 OK in 4ms (Views: 3.2ms | ActiveRecord: 0.0ms)
Started GET "/" for 54.243.31.203 at 2016-10-02 18:30:54 +0000
Processing by StaticPagesController#home as */*
Rendered static_pages/home.html.erb within layouts/application (0.5ms)
Rendered layouts/_shim.html.erb (0.0ms)
Rendered layouts/_header.html.erb (0.3ms)
Completed 200 OK in 4ms (Views: 3.5ms | ActiveRecord: 0.0ms)
I can't find any info on this online. My application isn't live yet, so nobody looks at it. Why is AWS doing this?
These are Route 53 Health Checks, which are a different type of health check than the health checks configured in Elastic Load Balancer (ELB), and different from the EC2 instance health and reachability checks that EC2 automatically performs on every EC2 instance.
Take a look at the published AWS IP Address Ranges, and you'll find that these match up to the address blocks specifically assigned to Route 53 Health Checks, quite nicely.
For example, this request...
Started GET "/" for 54.232.40.107 at 2016-10-02 18:30:52 +0000
...matches this entry...
{
"ip_prefix": "54.232.40.64/26",
"region": "sa-east-1",
"service": "ROUTE53_HEALTHCHECKS"
},
...because 54.232.40.64/26 is the CIDR spec for the IP address block from 54.232.40.64 through 54.232.40.127.
If you configured a Route 53 health check against your stack, then you probably have your answer, at this point.
Route 53 Health Checks are often used to drive the logic of complex DNS configurations, such as in cases where there are multiple candidate servers geographically distributed, and you want to control the answer returned by DNS based on the health of the servers... but they can also be used for monitoring latency and application performance (measuring TCP connect time and time-to-first-byte, as well as availability), tied into CloudWatch alarms, and used to drive scaling and other logic. If you configured anything like this, the question may be solved.
But if you didn't, this could be a case of another AWS user who has configured health checks against an IP address they were formerly using, or has configured the checks against your IP address or hostname by simple mistake.
If that is the case, you'll need to inspect the request headers from the incoming request. You'll find something like this:
User-Agent: Amazon Route 53 Health Check Service; ref:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; report http://amzn.to/zzzzzzz
With these values in hand, along with the other headers and any relevant log entries, you can visit the "report" URL provided in the headers you captured, (it's similar to the one I've shown above, captured from my logs, but sanitized since it seems to be generic, but I'm not certain -- the link in my logs redirects me here) and submit a request for AWS to work with you to to eliminate the unwanted health checks.
But first, try this...
Take the value immediately after "ref:" and create a URL from it, using this template:
https://console.aws.amazon.com/route53/healthchecks/home#/details/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
(Replace xxxx with your ref:, excluding the actual string ref:).
If the health check is from your own AWS account, and you're logged into the console, and have permission to view it, then this crafted link should bring the health check right up for you to view. If you get an error that you are "not authorized to access this resource," then the health check is not from your AWS account, or you aren't a privileged user on the AWS account and thus may lack the ability to view it.

Any way to keep each request separate in the Rails log?

I'd like to have the logs from each request be grouped together and easy to tell apart from another request's logs, eg
**********************
Started GET "/" for 67.205.67.76 at 2013-09-15 00:05:15 -0700
Processing by RootController#index as HTML
Rendered root/_index.html.erb within layouts/application (7.0ms)
Rendered layouts/_fonts_hack.html.erb (0.0ms)
Rendered layouts/_ie_version_vars.html.erb (0.0ms)
Rendered topbars/_logged_out_topbar.html.erb (2.0ms)
Rendered layouts/_old_browser_warnings.html.erb (0.0ms)
Completed 200 OK in 27ms (Views: 26.0ms | ActiveRecord: 0.0ms)
**********************
Started GET "/" for 67.205.67.76 at 2013-09-15 00:05:15 -0700
Processing by RootController#index as HTML
Rendered root/_index.html.erb within layouts/application (7.0ms)
Rendered layouts/_fonts_hack.html.erb (0.0ms)
Rendered layouts/_ie_version_vars.html.erb (0.0ms)
Rendered topbars/_logged_out_topbar.html.erb (2.0ms)
Rendered layouts/_old_browser_warnings.html.erb (0.0ms)
Completed 200 OK in 27ms (Views: 26.0ms | ActiveRecord: 0.0ms)
***********************
Is something like this possible? sometimes in my logs currently its kind of hard to visually see where one request begins and another ends, and sometimes logs from different requests get interspersed.
A better option would be to use the request uuid
config.log_tags = [:uuid]
Doesnt seem like it from what I can tell, but next best thing: add Pid and Thread object_id tags to each log, then search for and highlight a particular tag once you get to the start of a request, and then all the highlighted lines will be the ones in your request.
config.log_tags = [ lambda {|r| "#{Process.pid}##{Thread.current.object_id}" } ]

Resources