[racket] Redirecting inbound HTTP-schemed urls to HTTPS-schemed urls in #lang web-server with SSL

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Thu Apr 19 11:41:52 EDT 2012

On Thu, Apr 19, 2012 at 9:28 AM, Galler <lzgaller at optonline.net> wrote:
>
> When using stateless web servlets in #lang webserver with serve/servlet:
>
> Q: Is there a method for identifying the uri-scheme of the inbound request
> and redirecting HTTP schemed uris to HTTPS scheme for SSL?
>
> Issue 1)
>
> Examining the (url-scheme (request-uri  request))  of the request start
> passed to the servlet's start function returns #f.

HTTP requests don't contain the scheme in the URL, so it is #f when
the Web server parses & constructs them.

> Issue 2)
>
> start function is never called if an HTTP-schemed URI reached a servlet
> configured with:
>
> #:ssl? #t
> #:ssl-cert (build-path "my-cert.crt")
> #:ssl-key (build-path "myprivatekey.key")
>
> instead, a
>
> Connection error: ssl-accept/enable-break: accept failed (error:1407609C:SSL
> routines:SSL23_GET_CLIENT_HELLO:http request)
>
> is raised on the connection thread.

The client is trying to use HTTP but the server is configured to use
HTTPS on that port, so it fails because the client doesn't answer the
server's handshake.

The solution is to open two ports and redirect traffic from one to the
other. Here's a little example:

#lang racket/base
(require net/url
         web-server/servlet-env
         web-server/http)

;; Server 1
(define s1
  (thread
   (λ ()
     (serve/servlet
      (λ (req)
        (redirect-to
         (url->string
          (struct-copy url (request-uri req)
                       [scheme "http"]
                       [host "localhost"]
                       [port 8001]))))
      #:port 8000
      #:command-line? #t
      #:servlet-regexp #rx""))))

;; Server 2
(define s2
  (thread
   (λ ()
     (serve/servlet
      (λ (req)
        (response/xexpr "Hallo"))
      #:port 8001
      #:command-line? #t
      #:servlet-regexp #rx""))))

(thread-wait s1)
(thread-wait s2)

-----------------------------------------------------------

I get the impression that you do *not* want to serve the same content
under HTTPS and HTTP, which is easier.

Jay

>
> [note that servlet works as expected with HTTPS-schemed URI. this is
> absolutely not a PKI, certificate, or OpenSSL problem]
>
> Thanks very much.
>
>
> Here's an example demonstrating the #f value for url-scheme:
>
>>>>>>>>>>>>>>>>>>>>
>
> #lang web-server
>
> (provide/contract (start (request? . -> . response?)))
>
> (define (start request)
>  (printf "url-scheme is ~A\n" (url-scheme (request-uri request)))
>  (response/xexpr
>   `(html (head (title "Hello world!"))
>          (body (p "Hi Jay")))))
>
>
> (require web-server/servlet-env)
> (serve/servlet start
>               #:stateless? #t
>               #:launch-browser? #f
>               #:connection-close? #t
>               #:quit? #f
>               #:listen-ip #f
>                #:servlet-path "/")
>
>
> +++++++++++++++++++++++++++++
>
>>> url-scheme is #f
>
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users



-- 
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

"The glory of God is Intelligence" - D&C 93


Posted on the users mailing list.