Move SSD transport messages to typed Kotlin
ober
f1fc65296e3333de116bd40f30b94ad915c3c286
--- a/templates/ssd-review.ss +++ b/templates/ssd-review.ss @@ -1302,7 +1302,10 @@ storageSummaryText compressionRatioBudget boundedTreeReadLimit boundedReadInitialCapacity mergedJsonLinesText truthFileName reviewFileName eventsFileName - inputLimitExceededMessage outputLimitExceededMessage) + inputLimitExceededMessage outputLimitExceededMessage + clientLogHttpStatusMessage bearerAuthorizationHeader + zipEntryCountLimitExceededMessage httpStatusMessage + unableToCreateSyncFolderMessage unableToCreateFileMessage) (type Int32) (record ImportBudget ((mut entries : Int32) @@ -1349,6 +1352,25 @@ (string-append "Output exceeds " (string-append (int->string limit) " bytes"))) + (def (clientLogHttpStatusMessage (code : Int32)) : String + (string-append + "client log HTTP " + (int32->string code))) + (def (bearerAuthorizationHeader (token : String)) : String + (string-append "Bearer " token)) + (def (zipEntryCountLimitExceededMessage (entries : Int32) + (limit : Int32)) : String + (string-append + "ZIP entry-count limit exceeded: " + (string-append + (int32->string entries) + (string-append "/" (int32->string limit))))) + (def (httpStatusMessage (code : Int32)) : String + (string-append "HTTP " (int32->string code))) + (def (unableToCreateSyncFolderMessage (name : String)) : String + (string-append "Unable to create sync folder " name)) + (def (unableToCreateFileMessage (fileName : String)) : String + (string-append "Unable to create " fileName)) (def (mergedJsonLinesText (lines : (Set String))) : String (joinStringSet lines @@ -6648,7 +6670,7 @@ " try {" " connection.outputStream.use { it.write(bytes) }" " val code = connection.responseCode" - " if (code !in 200..299) throw IllegalStateException(\"client log HTTP $code\")" + " if (code !in 200..299) throw IllegalStateException(clientLogHttpStatusMessage(code))" " connection.inputStream.close()" " } finally {" " connection.disconnect()" @@ -7775,7 +7797,7 @@ " connectTimeout = 5000" " readTimeout = 30000" " instanceFollowRedirects = false" - " if (config.bearerToken.isNotBlank()) setRequestProperty(\"Authorization\", \"Bearer ${config.bearerToken}\")" + " if (config.bearerToken.isNotBlank()) setRequestProperty(\"Authorization\", bearerAuthorizationHeader(config.bearerToken))" " setRequestProperty(\"Accept\", \"application/json\")" " if (acceptGzip) setRequestProperty(\"Accept-Encoding\", \"gzip\")" " if (contentType != null) setRequestProperty(\"Content-Type\", contentType)" @@ -7954,7 +7976,7 @@ " while (true) {" " val entry = zip.nextEntry ?: break" " budget.entries += 1" - " if (budget.entries > MAX_ZIP_ENTRIES) throw IllegalStateException(\"ZIP entry-count limit exceeded: ${budget.entries}/$MAX_ZIP_ENTRIES\")" + " if (budget.entries > MAX_ZIP_ENTRIES) throw IllegalStateException(zipEntryCountLimitExceededMessage(budget.entries, MAX_ZIP_ENTRIES))" " val name = entry.name" " if (!safeZipEntryName(name)) {" " throw IllegalStateException(\"Unsafe ZIP entry\")" @@ -8063,7 +8085,7 @@ " val code = connection.responseCode" " if (code !in 200..299) {" " connection.errorStream?.close()" - " throw IllegalStateException(\"HTTP $code\")" + " throw IllegalStateException(httpStatusMessage(code))" " }" " if (connection.contentLengthLong > MAX_REMOTE_ZIP_BYTES) {" " throw IllegalStateException(\"Remote ZIP exceeds compressed-byte limit\")" @@ -8092,7 +8114,7 @@ " val code = connection.responseCode" " if (code !in 200..299) {" " connection.errorStream?.close()" - " throw IllegalStateException(\"HTTP $code\")" + " throw IllegalStateException(httpStatusMessage(code))" " }" " val response = readResponseText(connection)" " return remoteDumpImportedCount(jsonObjectFromText(response))" @@ -8221,7 +8243,7 @@ " private fun ensureTreeDir(parent: DocumentFile, name: String): DocumentFile =" " parent.findFile(name.takeIf { safePathComponent(it) }" " ?: throw IllegalArgumentException(\"Unsafe tree directory\"))?.takeIf { it.isDirectory } ?: parent.createDirectory(name)" - " ?: throw IllegalStateException(\"Unable to create sync folder $name\")" + " ?: throw IllegalStateException(unableToCreateSyncFolderMessage(name))" "" " private fun writeTreeFile(parent: DocumentFile, relativeName: String, source: File) {" " require(source.isFile && !Files.isSymbolicLink(source.toPath()))" @@ -8234,7 +8256,7 @@ " dir.findFile(fileName)?.delete()" " val mime = treeFileMime(fileName)" " val doc = dir.createFile(mime, fileName)" - " ?: throw IllegalStateException(\"Unable to create $fileName\")" + " ?: throw IllegalStateException(unableToCreateFileMessage(fileName))" " context.contentResolver.openOutputStream(doc.uri)?.use { output ->" " source.inputStream().use { input ->" " LimitedInputStream(input, MAX_ZIP_ENTRY_BYTES).use { it.copyTo(output, 32 * 1024) }" --- a/tests/ssd-security-test.sh +++ b/tests/ssd-security-test.sh @@ -39,7 +39,7 @@ reject_text() { require_text 'HttpsURLConnection' require_text 'X509TrustManager' require_text 'MessageDigest.isEqual' -require_text 'setRequestProperty("Authorization", "Bearer ${config.bearerToken}")' +require_text 'setRequestProperty("Authorization", bearerAuthorizationHeader(config.bearerToken))' require_text 'context.getSharedPreferences("ssd_review_remote", Context.MODE_PRIVATE)' require_text 'Remote SSD service is not locally configured' require_text 'validatedSourceKey'