How to do proxy in `figwheel` dev server?

345 views Asked by At

In grunt/webpack/express, I can proxy some APIs from other domain/hostname to the current server on which the html page is served and solve the CORS problem.

I found the figwheel use ring to start a http server, then I think I can use https://github.com/tailrecursion/ring-proxy to add a proxy path to the figwheel server. But I don't know how can I do this outside the figwheel project.

Thank you!

1

There are 1 answers

0
cmal On

I use the Luminus framework and added this to Luminus framework's middleware.clj:

(defn create-proxy [handler fns]
  ;; TODO check whether cookies are sent
  (let [identifier-fn (get fns :identifier-fn identity)
        host-fn (get fns :host-fn {})
        path-fn (get fns :path-fn identity)]
    (fn [request]
      (let [request-key (identifier-fn request)
            host (host-fn request-key)
            stripped-headers (dissoc (:headers request) "content-length" "host")
            path (path-fn (:uri request))]
        (if host
          (->
           {:url              (build-url host (path-fn (:uri request)) (:query-string request))
            :method           (:request-method request)
            :body             (if-let [len (get-in request [:headers "content-length"])]
                                (slurp-binary
                                 (:body request)
                                 (Integer/parseInt len)))
            :headers          stripped-headers
            :follow-redirects true
            :throw-exceptions false
            :as               :stream
            :insecure?        true
            }
           clj-http.client/request
           (update-in [:headers] dissoc "Transfer-Encoding")
           )
          (handler request))
        ))))


(defn wrap-proxy [handler]
  (-> handler
      (create-proxy
       {:identifier-fn :uri
        :host-fn (proxy-map-2-host-fn proxy-map)
        :path-fn (fn [^String uri]
                   (subs uri (inc (.indexOf (rest uri) \/))))})))

and change app-routes in handler.clj to this:

(def app-routes
 (routes
    (-> #'home-routes
        (wrap-routes middleware/wrap-csrf)
        (wrap-routes middleware/wrap-formats))
    (middleware/wrap-proxy
     (route/not-found
      (:body
       (error-page {:status 404
                    :title "page not found"}))))))

the proxy-map may be like this:

(def proxy-map "proxy map"
  {"/www" "https://www.example.com"
   "/test" "http://test.example.com"
   }
  )

and it works. However, when using this framework, I do not need to cider-jack-in-clojurescript any more and the web page are reloaded whenever I save my .cljs files. So just add any cross site route to proxy-map and using the corresponding key to access.

For example, using (GET "/www/some-path'") will works as if you are requesting (GET "https://www.example.com").

Btw, most of these code are stolen from https://github.com/tailrecursion/ring-proxy and some other similar repos.