forked from woggioni/rbcs
temporary commit
This commit is contained in:
10
src/main/kotlin/net/woggioni/gbcs/Configuration.kt
Normal file
10
src/main/kotlin/net/woggioni/gbcs/Configuration.kt
Normal file
@@ -0,0 +1,10 @@
|
||||
package net.woggioni.gbcs
|
||||
|
||||
import java.nio.file.Path
|
||||
|
||||
data class Configuration(
|
||||
val cacheFolder : Path,
|
||||
val host : String,
|
||||
val port : Int,
|
||||
val users : Map<String, Set<Role>>
|
||||
)
|
||||
@@ -34,10 +34,12 @@ import io.netty.handler.stream.ChunkedNioFile
|
||||
import io.netty.handler.stream.ChunkedWriteHandler
|
||||
import io.netty.util.concurrent.DefaultEventExecutorGroup
|
||||
import io.netty.util.concurrent.EventExecutorGroup
|
||||
import net.woggioni.jwo.JWO
|
||||
import java.nio.channels.FileChannel
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.nio.file.StandardCopyOption
|
||||
import java.nio.file.StandardOpenOption
|
||||
import java.security.MessageDigest
|
||||
import java.util.AbstractMap.SimpleEntry
|
||||
@@ -208,8 +210,15 @@ class GradleBuildCacheServer {
|
||||
}
|
||||
val content = msg.content()
|
||||
val file = cacheDir.resolve(digestString(key.toByteArray()))
|
||||
Files.newOutputStream(file).use {
|
||||
content.readBytes(it, content.readableBytes())
|
||||
val tmpFile = Files.createTempFile(cacheDir, null, ".tmp")
|
||||
try {
|
||||
Files.newOutputStream(tmpFile).use {
|
||||
content.readBytes(it, content.readableBytes())
|
||||
}
|
||||
Files.move(tmpFile, file, StandardCopyOption.ATOMIC_MOVE)
|
||||
} catch (t : Throwable) {
|
||||
Files.delete(tmpFile)
|
||||
throw t
|
||||
}
|
||||
val response = DefaultFullHttpResponse(msg.protocolVersion(), HttpResponseStatus.CREATED,
|
||||
Unpooled.copiedBuffer(key.toByteArray()))
|
||||
@@ -268,18 +277,6 @@ class GradleBuildCacheServer {
|
||||
GradleBuildCacheServer().run()
|
||||
}
|
||||
|
||||
private val hexArray = "0123456789ABCDEF".toCharArray()
|
||||
|
||||
fun bytesToHex(bytes: ByteArray): String {
|
||||
val hexChars = CharArray(bytes.size * 2)
|
||||
for (j in bytes.indices) {
|
||||
val v: Int = bytes[j].toInt().and(0xFF)
|
||||
hexChars[j * 2] = hexArray[v ushr 4]
|
||||
hexChars[j * 2 + 1] = hexArray[v and 0x0F]
|
||||
}
|
||||
return String(hexChars)
|
||||
}
|
||||
|
||||
fun digest(data : ByteArray,
|
||||
md : MessageDigest = MessageDigest.getInstance("MD5")) : ByteArray {
|
||||
md.update(data)
|
||||
@@ -288,7 +285,7 @@ class GradleBuildCacheServer {
|
||||
|
||||
fun digestString(data : ByteArray,
|
||||
md : MessageDigest = MessageDigest.getInstance("MD5")) : String {
|
||||
return bytesToHex(digest(data, md))
|
||||
return JWO.bytesToHex(digest(data, md))
|
||||
}
|
||||
}
|
||||
}
|
||||
5
src/main/kotlin/net/woggioni/gbcs/Role.kt
Normal file
5
src/main/kotlin/net/woggioni/gbcs/Role.kt
Normal file
@@ -0,0 +1,5 @@
|
||||
package net.woggioni.gbcs
|
||||
|
||||
enum class Role {
|
||||
Reader, Writer
|
||||
}
|
||||
118
src/main/kotlin/net/woggioni/gbcs/Xml.kt
Normal file
118
src/main/kotlin/net/woggioni/gbcs/Xml.kt
Normal file
@@ -0,0 +1,118 @@
|
||||
package net.woggioni.gbcs
|
||||
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.w3c.dom.Document
|
||||
import org.xml.sax.ErrorHandler
|
||||
import org.xml.sax.SAXNotRecognizedException
|
||||
import org.xml.sax.SAXNotSupportedException
|
||||
import org.xml.sax.SAXParseException
|
||||
import java.net.URL
|
||||
import javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD
|
||||
import javax.xml.XMLConstants.ACCESS_EXTERNAL_SCHEMA
|
||||
import javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING
|
||||
import javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI
|
||||
import javax.xml.parsers.DocumentBuilder
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import javax.xml.validation.Schema
|
||||
import javax.xml.validation.SchemaFactory
|
||||
|
||||
|
||||
object Xml {
|
||||
|
||||
private class XmlErrorHandler(private val fileURL: URL) : ErrorHandler {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(XmlErrorHandler::class.java)
|
||||
}
|
||||
|
||||
override fun warning(ex: SAXParseException) {
|
||||
log.warn(
|
||||
"Problem at {}:{}:{} parsing deployment configuration: {}",
|
||||
fileURL, ex.lineNumber, ex.columnNumber, ex.message
|
||||
)
|
||||
}
|
||||
|
||||
override fun error(ex: SAXParseException) {
|
||||
log.error(
|
||||
"Problem at {}:{}:{} parsing deployment configuration: {}",
|
||||
fileURL, ex.lineNumber, ex.columnNumber, ex.message
|
||||
)
|
||||
throw ex
|
||||
}
|
||||
|
||||
override fun fatalError(ex: SAXParseException) {
|
||||
log.error(
|
||||
"Problem at {}:{}:{} parsing deployment configuration: {}",
|
||||
fileURL, ex.lineNumber, ex.columnNumber, ex.message
|
||||
)
|
||||
throw ex
|
||||
}
|
||||
}
|
||||
|
||||
private fun disableProperty(dbf: DocumentBuilderFactory, propertyName: String) {
|
||||
try {
|
||||
dbf.setAttribute(propertyName, "")
|
||||
} catch (iae: IllegalArgumentException) {
|
||||
// Property not supported.
|
||||
}
|
||||
}
|
||||
|
||||
private fun disableProperty(sf: SchemaFactory, propertyName: String) {
|
||||
try {
|
||||
sf.setProperty(propertyName, "")
|
||||
} catch (ex: SAXNotRecognizedException) {
|
||||
// Property not supported.
|
||||
} catch (ex: SAXNotSupportedException) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSchema(schemaResourceURL: String): Schema {
|
||||
val sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI)
|
||||
sf.setFeature(FEATURE_SECURE_PROCESSING, true)
|
||||
disableProperty(sf, ACCESS_EXTERNAL_SCHEMA)
|
||||
disableProperty(sf, ACCESS_EXTERNAL_DTD)
|
||||
val schemaUrl: URL = Xml::class.java.classLoader.getResource(schemaResourceURL)
|
||||
?: throw IllegalStateException(String.format("Missing configuration schema '%s'", schemaResourceURL))
|
||||
return sf.newSchema(schemaUrl)
|
||||
}
|
||||
|
||||
private fun newDocumentBuilderFactory(schemaResourceURL: String?): DocumentBuilderFactory {
|
||||
val dbf = DocumentBuilderFactory.newInstance()
|
||||
dbf.setFeature(FEATURE_SECURE_PROCESSING, true)
|
||||
disableProperty(dbf, ACCESS_EXTERNAL_SCHEMA)
|
||||
disableProperty(dbf, ACCESS_EXTERNAL_DTD)
|
||||
dbf.isExpandEntityReferences = false
|
||||
dbf.isIgnoringComments = true
|
||||
dbf.isNamespaceAware = true
|
||||
val sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI)
|
||||
sf.setFeature(FEATURE_SECURE_PROCESSING, true)
|
||||
disableProperty(sf, ACCESS_EXTERNAL_SCHEMA)
|
||||
disableProperty(sf, ACCESS_EXTERNAL_DTD)
|
||||
if (schemaResourceURL != null) {
|
||||
dbf.schema = getSchema(schemaResourceURL)
|
||||
}
|
||||
return dbf
|
||||
}
|
||||
|
||||
fun newDocumentBuilder(resource: URL, schemaResourceURL: String?): DocumentBuilder {
|
||||
val db = newDocumentBuilderFactory(schemaResourceURL).newDocumentBuilder()
|
||||
db.setErrorHandler(XmlErrorHandler(resource))
|
||||
return db
|
||||
}
|
||||
|
||||
fun parseXmlResource(resource: URL, schemaResourceURL: String?): Document {
|
||||
val db = newDocumentBuilder(resource, schemaResourceURL)
|
||||
return resource.openStream().use(db::parse)
|
||||
}
|
||||
|
||||
fun newDocumentBuilder(resource: URL): DocumentBuilder {
|
||||
val db = newDocumentBuilderFactory(null).newDocumentBuilder()
|
||||
db.setErrorHandler(XmlErrorHandler(resource))
|
||||
return db
|
||||
}
|
||||
|
||||
fun parseXmlResource(resource: URL): Document {
|
||||
val db = newDocumentBuilder(resource, null)
|
||||
return resource.openStream().use(db::parse)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user