diff --git a/bin/proxy b/bin/proxy
index ad22ac2450b0bfebfab666f68a04daa79dc8be77..02b2da157cdbf29799957d5d764aec5cdf2e45ce 100755
--- a/bin/proxy
+++ b/bin/proxy
@@ -14,7 +14,7 @@ config = require('../lib/configuration.js');
 var port = config.has('bind_to.port') ? config.get('bind_to.port') : 0;
 var addy = config.has('bind_to.host') ? config.get('bind_to.host') : "127.0.0.1";
 
-const allowed = /^https:\/\/[a-zA-Z\.\-_]+\/\.well-known\/browserid$/;
+const allowed = /^https:\/\/[a-zA-Z0-9\.\-_]+\/\.well-known\/browserid$/;
 
 var server = http.createServer(function (req, res) {
   var url = req.url;
diff --git a/config/l10n-all.json b/config/l10n-all.json
index 2d2b46ec5f8ebc49c92c1d1a0e3296cafc3cb7be..dc413675a53f47760def32e8618743e44c3f2188 100644
--- a/config/l10n-all.json
+++ b/config/l10n-all.json
@@ -6,4 +6,4 @@
     "pt-BR", "rm", "ro", "ru", "sk", "sl", "son", "sq", "sr", "sv", "tr",
     "uk", "zh-CN", "zh-TW"
   ]
-}
\ No newline at end of file
+}
diff --git a/config/l10n-prod.json b/config/l10n-prod.json
index 8b68b526088d0337a040c9e0bcf8e1d69dedf95e..427e37680dd99ebdfac07a865045b0290d865f83 100644
--- a/config/l10n-prod.json
+++ b/config/l10n-prod.json
@@ -1,7 +1,7 @@
 {
 "supported_languages": [
-    "ca", "cs", "da", "de", "el", "en-US", "es", "et", "eu", "fi", "fr",
+    "bg", "ca", "cs", "da", "de", "el", "en-US", "es", "et", "eu", "fi", "fr",
     "ga", "hr", "it", "lij", "lt", "nl", "pa", "pl", "pt-BR", "rm",
     "ru", "sk", "sl", "sq", "sr", "sv", "tr", "uk", "zh-CN", "zh-TW"
   ]
-}
\ No newline at end of file
+}
diff --git a/lib/db/mysql_wrapper.js b/lib/db/mysql_wrapper.js
index 91c4634827d590ed31bc007ad03decbd4fcbec8b..45edfd7de9411ad1fbb41618544d635cb62ee1f1 100644
--- a/lib/db/mysql_wrapper.js
+++ b/lib/db/mysql_wrapper.js
@@ -40,7 +40,13 @@ exports.createClient = function(options) {
       });
     },
     ping: function(cb) {
-      this.realClient.ping(cb);
+      if (stalled) {
+        process.nextTick(function() {
+          cb("database is intentionally stalled");
+        });
+      } else {
+        this.realClient.ping(cb);
+      }
     },
     _runNextQuery: function() {
       var self = this;
diff --git a/lib/wsapi.js b/lib/wsapi.js
index 78f43c548f2eff771de3cdda5c5f012d1df7f489..c76c7e3e23bf501492316c40eb4dcf1b3a4c4c0a 100644
--- a/lib/wsapi.js
+++ b/lib/wsapi.js
@@ -254,8 +254,10 @@ exports.setup = function(options, app) {
     try {
       var api = require(path.join(__dirname, 'wsapi', f));
 
-      // don't register read apis if we are configured as a writer
-      if (options.only_write_apis && !api.writes_db) return;
+      // don't register read apis if we are configured as a writer,
+      // with the exception of ping which tests database connection health.
+      if (options.only_write_apis && !api.writes_db &&
+          operation != 'ping') return;
 
       wsapis[operation] = api;
 
diff --git a/lib/wsapi/ping.js b/lib/wsapi/ping.js
new file mode 100644
index 0000000000000000000000000000000000000000..e1847ef09dc3a6b548364186b08d10b850642621
--- /dev/null
+++ b/lib/wsapi/ping.js
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const db = require('../db.js');
+
+exports.method = 'get';
+exports.writes_db = false;
+exports.i18n = false;
+
+exports.process = function(req, res) {
+  db.ping(function(err) {
+    if (err) res.send("fail", 500);
+    else res.send("ok",200);
+  });
+};
diff --git a/scripts/cleanup_compress.sh b/scripts/cleanup_compress.sh
deleted file mode 100755
index d698fe725f77db45aa8e65fa63d7e248ef901cd6..0000000000000000000000000000000000000000
--- a/scripts/cleanup_compress.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-cd ../resources/static
-git checkout -- include.js shared/templates.js
-
-if [ -e communication_iframe/production.js ] ; then
-  rm communication_iframe/production.*
-fi
-
-if [ -e dialog/production.js ] ; then
-  rm dialog/production.*
-fi
-
diff --git a/tests/stalled-mysql-test.js b/tests/stalled-mysql-test.js
index c4b1e18399de2253cb12e56eb3c1684f928f83e5..53160c7cc7e8ca43608a9aa0dabe9a40badc5422 100755
--- a/tests/stalled-mysql-test.js
+++ b/tests/stalled-mysql-test.js
@@ -77,6 +77,13 @@ suite.addBatch({
 
 // now try all apis that can be excercised without further setup
 suite.addBatch({
+  "ping": {
+    topic: wsapi.get('/wsapi/ping', {}),
+    "fails with 500 when db is stalled": function(err, r) {
+      // address info with a primary address doesn't need db access.
+      assert.strictEqual(r.code, 500);
+    }
+  },
   "address_info": {
     topic: wsapi.get('/wsapi/address_info', {
       email: 'test@example.domain'
@@ -155,6 +162,16 @@ addStallDriverBatch(false);
 
 var token = undefined;
 
+suite.addBatch({
+  "ping": {
+    topic: wsapi.get('/wsapi/ping', {}),
+    "works when database is unstalled": function(err, r) {
+      // address info with a primary address doesn't need db access.
+      assert.strictEqual(r.code, 200);
+    }
+  }
+});
+
 suite.addBatch({
   "account staging": {
     topic: wsapi.post('/wsapi/stage_user', {
@@ -195,6 +212,13 @@ addStallDriverBatch(true);
 // test remaining wsapis
 
 suite.addBatch({
+  "ping": {
+    topic: wsapi.get('/wsapi/ping', { }),
+    "fails": function(err, r) {
+      assert.strictEqual(r.code, 500);
+    }
+  },
+
   "account_cancel": {
     topic: wsapi.post('/wsapi/account_cancel', { }),
     "fails with 503": function(err, r) {