Refactor the existing memory bio tests a bit; add a new test which exercises the short-write case; change the error handling code in bio_read and bio_write to *not* use SSL_get_error, as these functions do nothing with SSL_* APIs
diff --git a/src/ssl/connection.c b/src/ssl/connection.c
index 8708e80..9abb736 100755
--- a/src/ssl/connection.c
+++ b/src/ssl/connection.c
@@ -125,6 +125,50 @@
 }
 
 /*
+ * Handle errors raised by BIO functions.
+ *
+ * Arguments: bio - The BIO object
+ *            ret - The return value of the BIO_ function.
+ * Returns: None, the calling function should return NULL;
+ */
+static void
+handle_bio_errors(BIO* bio, int ret)
+{
+    if (BIO_should_retry(bio)) {
+        if (BIO_should_read(bio)) {
+            PyErr_SetNone(ssl_WantReadError);
+        } else if (BIO_should_write(bio)) {
+            PyErr_SetNone(ssl_WantWriteError);
+        } else if (BIO_should_io_special(bio)) {
+            /*
+             * It's somewhat unclear what this means.  From the OpenSSL source,
+             * it seems like it should not be triggered by the memory BIO, so
+             * for the time being, this case shouldn't come up.  The SSL BIO
+             * (which I think should be named the socket BIO) may trigger this
+             * case if its socket is not yet connected or it is busy doing
+             * something related to x509.
+             */
+            PyErr_SetString(PyExc_ValueError, "BIO_should_io_special");
+        } else {
+            /*
+             * I hope this is dead code.  The BIO documentation suggests that
+             * one of the above three checks should always be true.
+             */
+            PyErr_SetString(PyExc_ValueError, "unknown bio failure");
+        }
+    } else {
+        /*
+         * If we aren't to retry, it's really an error, so fall back to the
+         * normal error reporting code.  However, the BIO interface does not
+         * specify a uniform error reporting mechanism.  We can only hope that
+         * the code which triggered the error also kindly pushed something onto
+         * the error stack.
+         */
+        exception_from_error_queue();
+    }
+}
+
+/*
  * Handle errors raised by SSL I/O functions. NOTE: Not SSL_shutdown ;)
  *
  * Arguments: ssl - The SSL object
@@ -252,7 +296,7 @@
 ssl_Connection_bio_write(ssl_ConnectionObj *self, PyObject *args)
 {
     char *buf;
-    int len, ret, err;
+    int len, ret;
 
     if(self->into_ssl == NULL) 
     {
@@ -271,16 +315,15 @@
         return NULL;
     }
 
-    err = SSL_get_error(self->ssl, ret);
-    if (err == SSL_ERROR_NONE)
-    {
-        return PyInt_FromLong((long)ret);
-    }
-    else
-    {
-        handle_ssl_errors(self->ssl, err, ret);
+    if (ret <= 0) {
+        /*
+         * There was a problem with the BIO_write of some sort.
+         */
+        handle_bio_errors(self->from_ssl, ret);
         return NULL;
     }
+
+    return PyInt_FromLong((long)ret);
 }
 
 static char ssl_Connection_send_doc[] = "\n\
@@ -440,7 +483,7 @@
 static PyObject *
 ssl_Connection_bio_read(ssl_ConnectionObj *self, PyObject *args)
 {
-    int bufsiz, ret, err;
+    int bufsiz, ret;
     PyObject *buf;
 
     if(self->from_ssl == NULL) 
@@ -465,19 +508,24 @@
         return NULL;
     }
 
-    err = SSL_get_error(self->ssl, ret);
-    if (err == SSL_ERROR_NONE)
-    {
-        if (ret != bufsiz && _PyString_Resize(&buf, ret) < 0)
-            return NULL;
-        return buf;
-    }
-    else
-    {
-        handle_ssl_errors(self->ssl, err, ret);
+    if (ret <= 0) {
+        /*
+         * There was a problem with the BIO_read of some sort.
+         */
+        handle_bio_errors(self->from_ssl, ret);
         Py_DECREF(buf);
         return NULL;
     }
+
+    /*
+     * Shrink the string to match the number of bytes we actually read.
+     */
+    if (ret != bufsiz && _PyString_Resize(&buf, ret) < 0)
+    {
+        Py_DECREF(buf);
+        return NULL;
+    }
+    return buf;
 }
 
 static char ssl_Connection_renegotiate_doc[] = "\n\