Using Thin Web Server with HTTP and HTTPS - ruby-on-rails

I'm using the Thin web server to serve my Rails app.
Starting the server with thin start serves http requests.
Starting the server with thin start --ssl serves https requests.
Is there a way to have thin serve both http and https requests concurrently?
The reason I ask is because when I use redirect_to some_path in my controllers, they redirect to http. Since thin is serving https requests, nothing is rendered.
Note: I'm using Rack::SSL in Rails 3.0.7.

(Comment converted to answer as requested.)
Simplest option is probably to run two separate instances of thin: one accepting SSL requests and one accepting plaintext requests. Any reason you don't want to do this? (Alternatively, if thin is running behind another web server, like Apache or Nginx, you only need one instance of thin: the frontend server can report whether the request came in over SSL.)
You can't accept both HTTP and HTTPS connections on the same port. (This is why, by default convention, HTTP runs on port 80 whereas HTTPS runs on port 443.)

you can use foreman (https://github.com/ddollar/foreman);
You create a Procfile with 2 process then start both with forman start command.
put this on a file called Procfile:
web: thin start
ssl: thin start --ssl
Then use foreman start and he start the 2 process.
This is how i am using... hope this helps you!

Related

Why do I need Nginx with Puma?

I'm deploying a Rails app to production. It seems that Puma is fast and handles many of the things I want in a web server.
I'm wondering if I even need to bother with Nginx, and what I'd be missing out on if just used Puma?
Nginx is a web server and puma is an application server.
Both have their advantages, and you need both.
Some examples:
Static redirects- you could setup your nginx to redirect all http traffic to the same url with https. This way such trivial requests will never hit your app server.
Multipart upload- Nginx is better suited to handle multipart uploads. Nginx will combine all the requests and send it as a single file to puma.
Serving static assets- It is recommended to serve static assets (those in /public/ endpoint in rails) via a webserver without loading your app server.
There are some basic DDoS protections built-in in nginx.
There's a significant difference between a web server and an application server.
Nginx (Web Server) and Puma (App Server) will handle requests in your application simultaneously.
Whenever there's a request coming from a client, it will be received by the nginx and then it will be forwarded to the application server which is Puma over here.
Having nginx as a web server will help you in handling multiple requests much more efficiently. Being a multi threaded server it will distribute requests into multiple threads making your application more faster.
As mentioned by vendant you can serve static pages using a web server as it will be a better approach.
If you're going to include a certification to your web application then you can provide redirects from http to https over here which will hit the app server only after redirecting to https.
If you're going to use Puma then you've to make sure that server is using resources efficiently but if you'll use nginx then it's going to take care of it by itself.
you can get more info here.

Separate port for some URLs in Rails app

My Rails app listens on single port for API calls and browser requests. To increase security I would like to open another port for API and make web page URLs unabailable for this port.
How to do this in Rails? (Possibly without losing current app integrity).
I use WEBrick or Puma during development and Apache+Passenger in production.
P.S.
Currently I'm thinking about making HTTP proxy which will forward API calls.
Unicorn will bind to all interfaces on TCP port 8080 by default. You may use the -l switch to bind to a different address:port. Each worker process can also bind to a private port via the after_fork hook. But I think it is not useful if you have nginx on top layer.

Start Unicorn using ssl in development

I'm migrating my rails app (still in development) from Thin to Unicorn. My app uses config.force_ssl = true.
When using Thin I could just write:
thin start --ssl
My question is: What is the equivalent way to start Unicorn with ssl in development?
If I correctly understood your question, you're trying to run unicorn on port 443.
This is a bad idea.
Instead, to achieve the same goal, I would suggest, run unicorn on an unprivileged port (above 1024), or better on a unix socket, and switch Nginx before, passing all static stuff directly trough nginx, and the rails stuff, trough unicorn.
I know this doesn't answer your question, but for the user, it will work exactly the same, with some benefits when your app server (unicorn) crashes, for example a nice rendered 502 error page served via nginx instead of a plain network error message seen in the browser of your users.
You can with this solution run X different applications on the same port, with different subdomains. a must have for a development machine with many projects.

Development Rails server that's compatible with both HTTP and HTTPS

My application isn't quite ready to go full SSL so in the meantime, I am allowing SSL but not requiring it. I do require SSL for certain controllers and force redirects to HTTPS for actions in such controllers.
I can start a thin server using SSL via thin start --ssl. This works great for SSL testing. However, I cannot have HTTP and HTTPS running simultaneously on the same port. Obviously, this makes testing redirects from HTTP to HTTPS quite frustrating. I can run an Apache or nginx server on top but I don't really want to go through the trouble of doing that in my development environment.
To start two servers, one for SSL and without, I use foreman like so:
web: rails server
ssl: thin start --ssl -p 3001
This starts the HTTP server on port 3000 and HTTPS server on 3001. Now my question is. How do I create a "smart redirect" policy only on my development environment only such that redirects from HTTP to HTTPS intelligently changes the port from 3000 to 3001? Thanks!

No data received when running "thin start"

I am using ruby 1.9.3 and rvm. I would like to run a thin server with --ssl option. I read in some answers that running "thin start --ssl" should do the trick.
But in my development environment when I run thin start --ssl the terminal runs:
Using rack adapter
Thin web server (v1.5.1 codename Straight Razor)
Maximum connections set to 1024
Listening on 0.0.0.0:3000, CTRL+C to stop
And in my web-browser in localhost:3000:
No data received
Unable to load the webpage because the server sent no data.
Here are some suggestions:
Reload this webpage later.
Error 324 (net::ERR_EMPTY_RESPONSE): The server closed the connection without sending any data.
When I run the same command with "rails s thin" it work though, with a different message:
Booting Thin
Rails 3.2.11 application starting in development on http:// 0. 0. 0 .0 :3000
Call with -d to detach
Ctrl-C to shutdown server
I don't know why this happens (maybe because of rvm) but thin is working propely. I wanted to run the first vertion "thin start --ssl" because I couldn't set this ssl option in the "rails s" command.
I found the reason why I had "No data received". If anyone has the same error:
I ran "thin start --ssl" so my server would only respond to https requets. All the http requests were not answered, so that's why there was no data (stupid). By default http requests goes to port 80 while https requests goes to port 443.
"thin start --ssl" works fine for debugging ssl locally and you can test your whole application by forcing ssl in the application controller (so you don't find yourself in the same situation, with no data received).
A much easier (and more real world) solution is to run a web server (like nginx) in front of your rails app. This web server would listen for both http and https traffic, and then just pass everything over to port 3000 to the Rails (thin) server.

Resources