Df2106ce87ede93244372837b7d36700
I am the creator of the site you are currently looking at. I love copying and pasting code from stack overflow .
3 posts 0 following 0 followers

Tags
Writing my own rails middleware
June 24, 2017 17:45

Disclaimer: This is neither the most efficient nor the standard (or the correct) way of solving the following problem.

I had a very strange requirement for this project. Each user has a unique subdomain for his/her blog.But I am using let's encrypt's free SSL certificate. Let's encrypt doesn't provide wildcard SSL certificates yet. The thing is that I can't afford 50$+ wildcard certificate right now (I am a student and my monthly expenses are less than 100$ :D ). So I did one thing. I divided all routes into two categories. One's that require an encrypted connection (authentication, settings, post editing /writing) and the ones that don't (post, profile page).So my encrypted routes are under www.hakrlog.com or simply hakrlog.com. It was okay with people coming from https://. But I wanted to redirect users from http:// to https:// having host www or "".

This is a very strange requirement. I tried modifying routes.rb but had no success. So I wrote a middleware which redirected users to https:// URL if the host was www or "".

    def call (env)
      req = Rack::Request.new(env)
      # Get request enviroment hash into a request object.
      if req.host.split(".").first=="www" or req.host.split(".").first=="hakrlog"
      # check if the host is "www" or empty
        if !req.ssl?
        #check if the request non-ssl request
          location = "https://#{req.host}#{req.fullpath}"
          #make the new https:// url from old url
          headers = { 'Content-Type' => 'text/html', 'Location' => location }
          [301, headers, []]
          #return the Rack array with redirect url
        else
          @status, @headers, @response = @app.call(env)
          [@status, @headers, @response]
          #do the normal thing for non-ssl requests
        end
      else
        @status, @headers, @response = @app.call(env)
        [@status, @headers, @response]
        #do the normal thing for the requests with subdomains
      end 
        #call it a day

This code is inefficient. I had a very particular requirement. I googled, searched, copied code (from rack-ssl-enforcer gem).I spent an entire day on this And got it working. And I feel really good :D


Comments