Compare commits

...

6 Commits

Author SHA1 Message Date
Robinson 7572d4f407
Cleaned up logging 2024-02-13 20:23:40 +01:00
Robinson f1c97a983c
renamed TrieFileResourceManager, added better logging 2024-02-13 20:22:44 +01:00
Robinson a72efb6ed1
added safe toString/hash, as URL.toString() can cause DNS lookups! 2024-02-13 20:22:20 +01:00
Robinson 947947ea2e
comments and cleaned up logging 2024-02-13 20:21:27 +01:00
Robinson 6703932dd8
Updated logger (removed KotlinLogging) 2024-02-13 11:04:40 +01:00
Robinson 3cb5a8fb20
Added comments 2024-02-13 10:59:54 +01:00
10 changed files with 183 additions and 62 deletions

View File

@ -18,6 +18,7 @@
package dorkbox.vaadin.undertow
import dorkbox.vaadin.util.logger
import io.undertow.UndertowLogger
import io.undertow.io.IoCallback
import io.undertow.predicate.Predicate
@ -31,12 +32,12 @@ import io.undertow.server.handlers.cache.ResponseCache
import io.undertow.server.handlers.encoding.ContentEncodedResourceManager
import io.undertow.server.handlers.resource.*
import io.undertow.util.*
import org.slf4j.Logger
import java.io.File
import java.io.IOException
import java.nio.file.Paths
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.TimeUnit
import java.util.concurrent.*
@Suppress("unused")
/**
@ -49,6 +50,7 @@ import java.util.concurrent.TimeUnit
*/
class DirectResourceHandler(@Volatile private var resourceManager: ResourceManager?,
@Volatile private var resourceSupplier: ResourceSupplier = DefaultResourceSupplier(resourceManager),
val logger: Logger,
private val next: HttpHandler = ResponseCodeHandler.HANDLE_404) : HttpHandler {
private val welcomeFiles = CopyOnWriteArrayList(arrayOf("index.html", "index.htm", "default.html", "default.htm"))
@ -451,12 +453,13 @@ class DirectResourceHandler(@Volatile private var resourceManager: ResourceManag
}
private class Wrapper internal constructor(private val location: String,
private val allowDirectoryListing: Boolean) : HandlerWrapper {
private class Wrapper(private val location: String,
private val allowDirectoryListing: Boolean) : HandlerWrapper {
override fun wrap(handler: HttpHandler): HttpHandler {
val rm = PathResourceManager(Paths.get(location), 1024)
val resourceHandler = DirectResourceHandler(rm)
val resourceManager = PathResourceManager(Paths.get(location), 1024)
// use a default logger
val resourceHandler = DirectResourceHandler(resourceManager, DefaultResourceSupplier(resourceManager), logger())
resourceHandler.setDirectoryListingEnabled(allowDirectoryListing)
return resourceHandler
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023 dorkbox, llc
* Copyright 2024 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -37,7 +37,7 @@ import io.undertow.server.handlers.resource.Resource
import io.undertow.server.handlers.resource.ResourceChangeListener
import io.undertow.server.handlers.resource.ResourceManager
import io.undertow.server.handlers.resource.URLResource
import mu.KLogger
import org.slf4j.Logger
import java.io.IOException
import java.net.URL
@ -48,20 +48,25 @@ import java.net.URL
* @author Andy Wilkinson
* @author Dorkbox LLC
*/
internal class JarResourceManager(val name: String, val trie: DoubleArrayStringTrie<URL>, val logger: KLogger) : ResourceManager {
internal class JarResourceManager(val name: String,
private val trie: DoubleArrayStringTrie<URL>,
private val logger: Logger) : ResourceManager {
@Throws(IOException::class)
override fun getResource(path: String): Resource? {
logger.trace { "REQUEST jar: $path" }
val url = trie[path] ?: return null
logger.trace { "TRIE: $url" }
val resource = URLResource(url, path)
if (path.isNotBlank() && path != "/" && resource.contentLength < 0) {
val url = trie[path]
if (url === null) {
logger.trace("REQUEST not found for PATH: {}", path)
return null
}
val resource = URLResource(url, path)
if (path.isNotBlank() && path != "/" && resource.contentLength < 0) {
logger.trace("REQUEST file not found for PATH: {}, {}", path, url)
return null
}
logger.debug("REQUEST found: {}, {}", path, url)
return resource
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020 Dorkbox LLC
* Copyright 2024 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,14 +16,14 @@
package dorkbox.vaadin.undertow
import dorkbox.vaadin.util.logger
import io.undertow.UndertowMessages
import io.undertow.server.handlers.resource.Resource
import io.undertow.server.handlers.resource.ResourceChangeListener
import io.undertow.server.handlers.resource.ResourceManager
import mu.KotlinLogging
class ResourceCollectionManager(private val resources: List<ResourceManager>) : ResourceManager {
private val logger = KotlinLogging.logger {}
private val logger = logger()
private val changeListenerSupported : Boolean by lazy {
var supported = true
@ -77,7 +77,7 @@ class ResourceCollectionManager(private val resources: List<ResourceManager>) :
try {
it.close()
} catch (e: Exception) {
logger.error(e) { "Error closing resourceManager" }
logger.error("Error closing resourceManager", e)
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023 dorkbox, llc
* Copyright 2024 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -33,11 +33,8 @@ package dorkbox.vaadin.undertow
import dorkbox.fsm.DoubleArrayStringTrie
import io.undertow.UndertowMessages
import io.undertow.server.handlers.resource.FileResource
import io.undertow.server.handlers.resource.Resource
import io.undertow.server.handlers.resource.ResourceChangeListener
import io.undertow.server.handlers.resource.ResourceManager
import mu.KLogger
import io.undertow.server.handlers.resource.*
import org.slf4j.Logger
import java.io.File
import java.io.IOException
import java.net.URL
@ -47,21 +44,53 @@ import java.net.URL
*
* @author Dorkbox LLC
*/
internal class StrictFileResourceManager(val name: String, val trie: DoubleArrayStringTrie<URL>, val logger: KLogger) : io.undertow.server.handlers.resource.FileResourceManager(File(".")) {
internal class TrieFileResourceManager(val name: String,
private val trie: DoubleArrayStringTrie<URL>,
private val logger: Logger,
base: File = File("").absoluteFile,
/**
* Size to use direct FS to network transfer (if supported by OS/JDK) instead of read/write
*/
transferMinSize: Long = 1024,
/**
* Check to validate caseSensitive issues for specific case-insensitive FS.
* @see io.undertow.server.handlers.resource.PathResourceManager#isFileSameCase(java.nio.file.Path, String)
*/
caseSensitive: Boolean = false,
/**
* Check to allow follow symbolic links
*/
followLinks: Boolean = false,
/**
* Used if followLinks == true. Set of paths valid to follow symbolic links. If this is empty and followLinks
* it true then all links will be followed
*/
vararg safePaths: String)
: FileResourceManager(base, transferMinSize, caseSensitive, followLinks, *safePaths) {
@Throws(IOException::class)
override fun getResource(path: String): Resource? {
logger.trace { "REQUEST static: $path" }
val url = trie[path] ?: return null
logger.trace { "TRIE: $url" }
val resource = FileResource(File(url.file), this, path)
if (path.isNotBlank() && path != "/" && resource.contentLength < 0) {
val url = trie[path]
if (url === null) {
logger.trace("REQUEST not found for PATH: {}", path)
return null
}
val file = File(url.file)
val resource = FileResource(file, this, path)
if (path.isNotBlank() && path != "/" && resource.contentLength < 0) {
logger.trace("REQUEST file not found for PATH: {}, {}", path, file)
return null
}
logger.debug("REQUEST found: {}, {}", path, file)
return resource
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021 dorkbox, llc
* Copyright 2024 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,4 +17,22 @@ package dorkbox.vaadin.undertow
import java.net.URL
data class WebResource(val requestPath: String, val resourcePath: URL)
// stored in a set, and URL.toString() can cause a DNS lookup!
data class WebResource(val requestPath: String, val resourcePath: URL) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is WebResource) return false
if (requestPath != other.requestPath) return false
return true
}
override fun hashCode(): Int {
return requestPath.hashCode()
}
override fun toString(): String {
return "WebResource(requestPath='$requestPath')"
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021 dorkbox, llc
* Copyright 2024 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,4 +17,25 @@ package dorkbox.vaadin.undertow
import java.net.URL
data class WebResourceString(val requestPath: String, val resourcePath: URL, val relativeResourcePath: String, val resourceDir: URL)
// stored in a set, and URL.toString() can cause a DNS lookup!
data class WebResourceString(val requestPath: String, val resourcePath: URL, val relativeResourcePath: String, val resourceDir: URL) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is WebResourceString) return false
if (requestPath != other.requestPath) return false
if (relativeResourcePath != other.relativeResourcePath) return false
return true
}
override fun hashCode(): Int {
var result = requestPath.hashCode()
result = 31 * result + relativeResourcePath.hashCode()
return result
}
override fun toString(): String {
return "WebResourceString(requestPath='$requestPath', relativeResourcePath='$relativeResourcePath')"
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021 dorkbox, llc
* Copyright 2024 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,7 +16,7 @@
package dorkbox.vaadin.util
/**
*
* This class is overridden by the multi-source compile for java 9+
*/
object CallingClass {
fun get(): Class<*> {

View File

@ -1,3 +1,19 @@
/*
* Copyright 2023 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright 2017 Pronghorn Technology LLC
*
@ -16,16 +32,20 @@
package dorkbox.vaadin.util
import mu.KLogger
import mu.KotlinLogging
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.io.PrintWriter
import java.io.StringWriter
inline fun <reified T> T.logger(): KLogger {
inline fun <reified T> T.logger(): Logger {
if (T::class.isCompanion) {
return KotlinLogging.logger(T::class.java.enclosingClass.name)
return LoggerFactory.getLogger(T::class.java.enclosingClass.name)
}
return KotlinLogging.logger(T::class.java.name)
return LoggerFactory.getLogger(T::class.java.name)
}
inline fun <reified T> T.logger(name: String): Logger {
return LoggerFactory.getLogger(name)
}

View File

@ -1,3 +1,19 @@
/*
* Copyright 2023 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright 2017 Pronghorn Technology LLC
*
@ -16,7 +32,7 @@
package dorkbox.vaadin.util
import mu.KotlinLogging
import org.slf4j.LoggerFactory
private const val MAX_POW2 = 1 shl 30
@ -27,10 +43,13 @@ inline fun <reified T : Any> validatePowerOfTwoCapacity(caller: T,
value
}
else -> {
val logger = KotlinLogging.logger(caller.javaClass.name)
logger.warn {
"${caller.javaClass.simpleName} capacity should be a power of two, but ($value) requested. Using the next available: ${roundToNextPowerOfTwo(value)}."
val logger = if (T::class.isCompanion) {
LoggerFactory.getLogger(caller::class.java.enclosingClass.name)
} else {
LoggerFactory.getLogger(caller.javaClass.name)
}
logger.warn("${caller.javaClass.simpleName} capacity should be a power of two, but ($value) requested. Using the next available: ${roundToNextPowerOfTwo(value)}.")
roundToNextPowerOfTwo(value)
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023 dorkbox, llc
* Copyright 2024 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,32 +16,38 @@
package dorkbox.vaadin.util
import dorkbox.fsm.DoubleArrayStringTrie
import mu.KLogger
import org.slf4j.Logger
import java.net.URL
import java.net.URLClassLoader
/**
*
* Used to get classloader data, but using a trie to store the lookups
*/
class TrieClassLoader(
private val urlTrie: DoubleArrayStringTrie<URL>,
private val stringTrie: DoubleArrayStringTrie<String>,
urls: Array<URL>, parent: ClassLoader,
private val logger: KLogger): URLClassLoader(urls, parent) {
private val diskTrie: DoubleArrayStringTrie<URL>,
private val jarTrie: DoubleArrayStringTrie<String>,
jarResourceDirs: Array<URL>, parentClassloader: ClassLoader,
private val logger: Logger,
private val loggerDisk: Logger,
private val loggerJar: Logger,
): URLClassLoader(jarResourceDirs, parentClassloader) {
override fun getResource(name: String): URL? {
logger.trace { "URL Classloader: $name" }
logger.trace(name)
// check disk first
val diskResourcePath: URL? = urlTrie[name]
val diskResourcePath: URL? = diskTrie[name]
if (diskResourcePath != null) {
logger.trace { "TRIE: $diskResourcePath" }
loggerDisk.trace(diskResourcePath.file)
return diskResourcePath
}
val jarResourcePath: String? = stringTrie[name]
val jarResourcePath: String? = jarTrie[name]
if (jarResourcePath != null) {
logger.trace { "TRIE: $jarResourcePath" }
loggerJar.trace(jarResourcePath)
return super.getResource(jarResourcePath)
}