From 52f2ac0f4ed2546df51af0239fab7587660df5e2 Mon Sep 17 00:00:00 2001
From: Noah Levitt <nlevitt@archive.org>
Date: Fri, 26 Oct 2018 15:26:27 -0700
Subject: [PATCH] send nice 503s and avoid scary stack traces...

... at shutdown
---
 setup.py               |  2 +-
 warcprox/controller.py |  6 +++---
 warcprox/mitmproxy.py  | 16 ++++++++++++----
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/setup.py b/setup.py
index 36a136d..9e3dfee 100755
--- a/setup.py
+++ b/setup.py
@@ -40,7 +40,7 @@ except:
 
 setuptools.setup(
         name='warcprox',
-        version='2.4b3.dev187',
+        version='2.4b3.dev188',
         description='WARC writing MITM HTTP/S proxy',
         url='https://github.com/internetarchive/warcprox',
         author='Noah Levitt',
diff --git a/warcprox/controller.py b/warcprox/controller.py
index 9ec369d..ed43bb6 100644
--- a/warcprox/controller.py
+++ b/warcprox/controller.py
@@ -326,9 +326,9 @@ class WarcproxController(object):
         to finish processing.
 
         1. stop accepting new connections
-        2. shut down active connections to remote servers (resulting in sending
-           http 502 to the proxy clients)
-        3. shut down the postfetch processors one by one, in order, letting
+        2. shut down active connections to remote servers
+        3. send "503 warcprox shutting down" response to active requests
+        4. shut down the postfetch processors one by one, in order, letting
            them finish process their queues
         '''
         with self._start_stop_lock:
diff --git a/warcprox/mitmproxy.py b/warcprox/mitmproxy.py
index ea94f71..83c3ea1 100644
--- a/warcprox/mitmproxy.py
+++ b/warcprox/mitmproxy.py
@@ -384,10 +384,16 @@ class MitmProxyHandler(http_server.BaseHTTPRequestHandler):
         try:
             return self._proxy_request()
         except Exception as e:
-            self.logger.error(
-                    'error from remote server(?) %r: %r',
-                    self.requestline, e, exc_info=True)
-            self.send_error(502, str(e))
+            if self.server.shutting_down:
+                self.logger.warn(
+                        'sending 503 warcprox shutting down %r: %r',
+                        self.requestline, e)
+                self.send_error(503, 'warcprox shutting down')
+            else:
+                self.logger.error(
+                        'error from remote server(?) %r: %r',
+                        self.requestline, e, exc_info=True)
+                self.send_error(502, str(e))
             return
 
     def send_error(self, code, message=None, explain=None):
@@ -616,6 +622,7 @@ class PooledMitmProxy(PooledMixIn, MitmProxy):
         PooledMixIn.__init__(self, options.max_threads)
         MitmProxy.__init__(self)
         self.profilers = collections.defaultdict(cProfile.Profile)
+        self.shutting_down = False
 
         if options.profile:
             self.process_request_thread = self._profile_process_request_thread
@@ -648,6 +655,7 @@ class PooledMitmProxy(PooledMixIn, MitmProxy):
         '''
         Abort active connections to remote servers to achieve prompt shutdown.
         '''
+        self.shutting_down = True
         for sock in self.remote_server_socks:
             self.shutdown_request(sock)