    (addr-from-req req) req opts
    (fn [client-dn]
      (fn [evt val]
-       (debug {:msg "Client event"
-               :event [evt val]})
-       (try
-         (cond
-          (= :response evt)
-          (do
-            ;; Because, I think that there might be some crazy race
-            ;; condition where the response gets sent before :connected
-            ;; TODO: Make sure that this isn't the case.
-            (locking req
-              (when (= :pending (@state :upstream))
-                (downstream :resume nil))
-              (swap! state #(assoc % :upstream client-dn :responded? true)))
-            (downstream evt val))
+       (debug {:msg "Client event" :event [evt val]})
+       (cond
+        ;; connected, resume if we're paused
+        (= :connected evt)
+        (locking req
+          (let [pending (= :pending (@state :upstream))]
+            (swap! state #(assoc % :upstream client-dn))
+            (when pending (downstream :resume nil))))
 
-          (= :body evt)
-          (downstream evt val)
+        ;; response, resume if we're paused
+        (= :response evt)
+        (do
+          ;; Because, I think that there might be some crazy race
+          ;; condition where the response gets sent before :connected
+          ;; TODO: Make sure that this isn't the case.
+          ;; TODO: the real issue here is that the client doesn't
+          ;; always send :connected
+          (locking req
+            (let [pending (= :pending (@state :upstream))]
+              (swap! state #(assoc % :upstream client-dn :responded? true))
+              (when pending (downstream :resume nil))))
 
-          (= :connected evt)
-          (locking req
-            (when (= :pending (@state :upstream))
-              (downstream :resume nil))
-            (swap! state #(assoc % :upstream client-dn)))
+          ;; send the response back to the server socket
+          (downstream evt val))
 
-          (= :abort evt)
-          (do
-            (swap! state #(dissoc % :upstream))
-            (let [current-state @state]
-              (cond
-               (bad-gateway? current-state val)
-               (downstream :response bad-gateway)
+        ;; body, send downstream
+        (= :body evt)
+        (downstream evt val)
 
-               (service-unavailable? current-state val)
-               (downstream :response service-unavailable)
+        ;; abort
+        (= :abort evt)
+        (do
+          (swap! state #(dissoc % :upstream))
+          (let [current-state @state]
+            (cond
+             (bad-gateway? current-state val)
+             (downstream :response bad-gateway)
 
-               (gateway-timeout? current-state val)
-               (downstream :response gateway-timeout)
+             (service-unavailable? current-state val)
+             (downstream :response service-unavailable)
 
-               :else
-               (downstream evt val))))
+             (gateway-timeout? current-state val)
+             (downstream :response gateway-timeout)
 
-          (not= :done evt)
-          (downstream evt val))
-         (catch Exception e
-           (.printStackTrace e))))))
+             :else
+             (downstream evt val))))
 
+        ;; done (don't send)
+        (= :done evt)
+        nil
+
+        ;; all other events send downstream
+        :else
+        (downstream evt val)))))
+
+  ;; when the request is chunked, note that we're pending
+  ;; connection and pause the server while we wait for the client
+  ;; to connect
   (when (chunked? req)
     (locking req
       (when-not (@state :upstream)

       (fn [downstream]
         (let [state (atom {})]
           (defstream
             ;; Handling the initial request
             (request [req]
               (debug {:msg   "Receiving request"
                       :event [:request req]})
               (if (proxy-loop? req opts)
                 (do
                   (debug {:msg   "In proxy loop"
                           :event [:request req]})
                   (downstream :response bad-gateway))
                 (initiate-request
                  state opts
                  (process-request req opts)
                  downstream)))
             (done []) ;; We don't care about this
             ;; Handling all other events
             (else [evt val]
               (when-let [upstream (@state :upstream)]
                 (upstream evt val)))))))))

  [[hdrs body] opts]
  [(-> hdrs
       add-xff-header
       (set-scheme opts))
   body])

(defn- proxy-loop?
  [[{[remote-ip] :remote-addr xff-header "x-forwarded-for"}] {cycles :cycles}]
