Move SSD stream close guards to typed Kotlin

ober

3ad8568e1f391df9a05446c71c66573b36b95886

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 6d559e2..bb7ab30 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -6053,7 +6053,8 @@
         (export normalizeRemoteEndpointValue normalizeRemoteEndpoint urlEncode
                 contentEncodingIsGzip responseInputStream
                 connectionContentLengthExceedsLimit
-                inputStreamPresent outputStreamPresent localTruthHttpAllowed)
+                inputStreamPresent outputStreamPresent closeInputStreamIfPresent
+                localTruthHttpAllowed)
         (type InputStream)
         (type OutputStream)
         (type URLConnection)
@@ -6061,6 +6062,8 @@
           (kotlin-call java io BufferedInputStream))
         (extern (gzipInputStream (input : InputStream)) : InputStream
           (kotlin-call java util zip GZIPInputStream))
+        (extern (inputStreamClose (input : InputStream)) : Unit
+          (kotlin-member-call close))
         (extern (connectionContentLength (connection : URLConnection)) : Int
           (kotlin-member-get contentLengthLong))
         (def (normalizeRemoteEndpointValue (value : String) (defaultEndpoint : String)) : String
@@ -6094,6 +6097,10 @@
           (not (nullable-null? input)))
         (def (outputStreamPresent (output : (Nullable OutputStream))) : Bool
           (not (nullable-null? output)))
+        (def (closeInputStreamIfPresent (input : (Nullable InputStream))) : Unit
+          (if (nullable-null? input)
+            (begin)
+            (inputStreamClose (nullable-get input))))
         (def (connectionContentLengthExceedsLimit (connection : URLConnection)
                                                   (limit : Int)) : Bool
           (> (connectionContentLength connection) limit))
@@ -8920,7 +8927,7 @@
        "            try {"
        "            val code = connection.responseCode"
        "            if (httpStatusFailed(code)) {"
-       "                connection.errorStream?.close()"
+       "                closeInputStreamIfPresent(connection.errorStream)"
        "                return 0"
        "            }"
        "            val response = readResponseText(connection)"
@@ -9153,7 +9160,7 @@
        "        try {"
        "            val code = connection.responseCode"
        "            if (httpStatusFailed(code)) {"
-       "                connection.errorStream?.close()"
+       "                closeInputStreamIfPresent(connection.errorStream)"
        "                throw IllegalStateException(httpStatusMessage(code))"
        "            }"
        "            if (connectionContentLengthExceedsLimit(connection, MAX_REMOTE_ZIP_BYTES)) {"
@@ -9182,7 +9189,7 @@
        "                }"
        "            val code = connection.responseCode"
        "            if (httpStatusFailed(code)) {"
-       "                connection.errorStream?.close()"
+       "                closeInputStreamIfPresent(connection.errorStream)"
        "                throw IllegalStateException(httpStatusMessage(code))"
        "            }"
        "                val response = readResponseText(connection)"
@@ -9416,9 +9423,9 @@
        "                    connection.outputStream.use { it.write(bytes) }"
        "                    val code = connection.responseCode"
        "                    if (httpStatusFailed(code)) {"
-       "                        connection.errorStream?.close()"
+       "                        closeInputStreamIfPresent(connection.errorStream)"
        "                    } else {"
-       "                        connection.inputStream?.close()"
+       "                        closeInputStreamIfPresent(connection.inputStream)"
        "                    }"
        "                } finally {"
        "                    connection.disconnect()"