<commit_before>package azadev.backt.webserver.utils

import azadev.backt.webserver.http.CallReferences
import java.io.File
import java.util.concurrent.ConcurrentHashMap


// ETag format: ([wW]/)?"([^"]|\\")*"
fun geterateETag(value: String, isWeak: Boolean = true)
		= "${if (isWeak) "W/" else ""}\"$value\""

var eTagCache: ConcurrentHashMap<String, String>? = null
const val MUTEX: Byte = 1

inline fun handleETagCache(callReferences: CallReferences, eTagCacheKey: String? = null, eTagCreator: ()->String): Boolean {
	val incomingETag = callReferences.request.headers["If-None-Match"]

	var eTag: String
	if (eTagCacheKey != null) {
		val cache = eTagCache ?: synchronized(MUTEX) {
			eTagCache = eTagCache ?: ConcurrentHashMap<String, String>(10)
			eTagCache!!
		}

		eTag = cache[eTagCacheKey] ?: ""
		if (eTag.isNullOrEmpty()) {
			eTag = geterateETag(eTagCreator())
			cache[eTagCacheKey] = eTag
			callReferences.logVerbose { "ETag cached: $eTag" }
		}
	}
	else eTag = geterateETag(eTagCreator())

	if (eTag.equals(incomingETag, ignoreCase = true)) {
		callReferences.logVerbose { "Asset is not modified (ETag) // eTag=$eTag" }
		return true
	}

	callReferences.response.headers["ETag"] = eTag
	return false
}

fun handleETagCache(callReferences: CallReferences, file: File)
		= handleETagCache(callReferences, file.path, { file.readText().hashCode().toString() })


fun handleLastModCache(callReferences: CallReferences, file: File): Boolean {
	val ifModifiedSince = parseHttpDate(callReferences.request.headers["If-Modified-Since"])?.run { (time / 1000L).toInt() }

	val lastModified = (file.lastModified() / 1000L).toInt()
	if (ifModifiedSince == lastModified) {
		callReferences.logVerbose { "Asset is not modified (Last-Modified)" }
		return true
	}

	callReferences.response.headers["Last-Modified"] = lastModified
	return false
}
<commit_msg>[BKT_WebServer] Cache, Fix: Headers are nullable<commit_after>package azadev.backt.webserver.utils

import azadev.backt.webserver.http.CallReferences
import java.io.File
import java.util.concurrent.ConcurrentHashMap


// ETag format: ([wW]/)?"([^"]|\\")*"
fun geterateETag(value: String, isWeak: Boolean = true)
		= "${if (isWeak) "W/" else ""}\"$value\""

var eTagCache: ConcurrentHashMap<String, String>? = null
const val MUTEX: Byte = 1

inline fun handleETagCache(callReferences: CallReferences, eTagCacheKey: String? = null, eTagCreator: ()->String): Boolean {
	val incomingETag = callReferences.request.headers["If-None-Match"]

	var eTag: String
	if (eTagCacheKey != null) {
		val cache = eTagCache ?: synchronized(MUTEX) {
			eTagCache = eTagCache ?: ConcurrentHashMap<String, String>(10)
			eTagCache!!
		}

		eTag = cache[eTagCacheKey] ?: ""
		if (eTag.isNullOrEmpty()) {
			eTag = geterateETag(eTagCreator())
			cache[eTagCacheKey] = eTag
			callReferences.logVerbose { "ETag cached: $eTag" }
		}
	}
	else eTag = geterateETag(eTagCreator())

	if (incomingETag != null && eTag.equals(incomingETag, ignoreCase = true)) {
		callReferences.logVerbose { "Asset is not modified (ETag) // eTag=$eTag" }
		return true
	}

	callReferences.response.headers["ETag"] = eTag
	return false
}

fun handleETagCache(callReferences: CallReferences, file: File)
		= handleETagCache(callReferences, file.path, { file.readText().hashCode().toString() })


fun handleLastModCache(callReferences: CallReferences, file: File): Boolean {
	val ifModifiedSince = parseHttpDate(callReferences.request.headers["If-Modified-Since"] ?: "")?.run { (time / 1000L).toInt() }

	val lastModified = (file.lastModified() / 1000L).toInt()
	if (ifModifiedSince == lastModified) {
		callReferences.logVerbose { "Asset is not modified (Last-Modified)" }
		return true
	}

	callReferences.response.headers["Last-Modified"] = lastModified
	return false
}

{'fraction_non_alphanumeric': 0.14183646467319397, 'fraction_numerical': 0.005821645938078857, 'mean_word_length': 5.176470588235294, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3310261', 'n_tokens_mistral': 1383, 'n_tokens_neox': 1268, 'n_words': 268}