Merge remote-tracking branch 'upstream/master' into Error-handling
This commit is contained in:
commit
9c7eb426ff
10
build.sbt
10
build.sbt
|
|
@ -15,7 +15,7 @@ lazy val root = (project in file(".")).settings(
|
|||
libraryDependencies += "org.json4s" % "json4s-jackson_2.13" % "3.6.11"
|
||||
)
|
||||
|
||||
unmanagedResourceDirectories in Compile += { baseDirectory.value / "lib" }
|
||||
Compile / unmanagedResourceDirectories += { baseDirectory.value / "lib" }
|
||||
scalacOptions ++= List(
|
||||
"-Yrangepos",
|
||||
"-Ywarn-unused",
|
||||
|
|
@ -23,8 +23,8 @@ scalacOptions ++= List(
|
|||
)
|
||||
javacOptions += "-g:none"
|
||||
compileOrder := CompileOrder.JavaThenScala
|
||||
mainClass in assembly := Some("lc.LCFramework")
|
||||
mainClass in (Compile, run) := Some("lc.LCFramework")
|
||||
assemblyJarName in assembly := "LibreCaptcha.jar"
|
||||
assembly / mainClass := Some("lc.LCFramework")
|
||||
Compile / run / mainClass := Some("lc.LCFramework")
|
||||
assembly / assemblyJarName := "LibreCaptcha.jar"
|
||||
|
||||
fork in run := true
|
||||
run / fork := true
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
sbt.version=1.4.9
|
||||
sbt.version=1.5.0
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ object Captcha {
|
|||
val token = if (rs.next()) {
|
||||
rs.getInt("token")
|
||||
}
|
||||
println("Added new challenge: " + token.toString)
|
||||
// println("Added new challenge: " + token.toString)
|
||||
token.asInstanceOf[Int]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import lc.database.DBConn
|
|||
import java.sql.Statement
|
||||
import java.sql.PreparedStatement
|
||||
|
||||
class Statements(dbConn: DBConn) {
|
||||
class Statements(dbConn: DBConn, maxAttempts: Int) {
|
||||
|
||||
private val stmt = dbConn.getStatement()
|
||||
|
||||
|
|
@ -71,13 +71,14 @@ class Statements(dbConn: DBConn) {
|
|||
)
|
||||
|
||||
val tokenPstmt: PreparedStatement = dbConn.con.prepareStatement(
|
||||
"SELECT token " +
|
||||
"FROM challenge " +
|
||||
"WHERE attempted < 10 AND " +
|
||||
"contentLevel = ? AND " +
|
||||
"contentType = ? AND " +
|
||||
"contentInput = ? " +
|
||||
"ORDER BY RAND() LIMIT 1"
|
||||
s"""
|
||||
SELECT token
|
||||
FROM challenge
|
||||
WHERE attempted < $maxAttempts AND
|
||||
contentLevel = ? AND
|
||||
contentType = ? AND
|
||||
contentInput = ?
|
||||
ORDER BY RAND() LIMIT 1"""
|
||||
)
|
||||
|
||||
val deleteAnswerPstmt: PreparedStatement = dbConn.con.prepareStatement(
|
||||
|
|
@ -85,9 +86,9 @@ class Statements(dbConn: DBConn) {
|
|||
)
|
||||
|
||||
val challengeGCPstmt: PreparedStatement = dbConn.con.prepareStatement(
|
||||
"DELETE FROM challenge " +
|
||||
"WHERE attempted >= 10 AND " +
|
||||
"token NOT IN (SELECT token FROM mapId)"
|
||||
s"""DELETE FROM challenge
|
||||
WHERE attempted >= $maxAttempts AND
|
||||
token NOT IN (SELECT token FROM mapId)"""
|
||||
)
|
||||
|
||||
val mapIdGCPstmt: PreparedStatement = dbConn.con.prepareStatement(
|
||||
|
|
@ -109,6 +110,14 @@ class Statements(dbConn: DBConn) {
|
|||
}
|
||||
|
||||
object Statements {
|
||||
/* Note: h2 documentation recommends using a separate DB connection per thread
|
||||
But in practice, as of version 1.4.200, multiple connections occassionally shows error on the console of the form
|
||||
```
|
||||
org.h2.jdbc.JdbcSQLNonTransientException: General error: "java.lang.NullPointerException"; SQL statement:
|
||||
SELECT image FROM challenge c, mapId m WHERE c.token=m.token AND m.uuid = ? [50000-200]
|
||||
```
|
||||
*/
|
||||
private val dbConn: DBConn = new DBConn()
|
||||
val tlStmts: ThreadLocal[Statements] = ThreadLocal.withInitial(() => new Statements(dbConn))
|
||||
private val maxAttempts = 10
|
||||
val tlStmts: ThreadLocal[Statements] = ThreadLocal.withInitial(() => new Statements(dbConn, maxAttempts))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,20 +14,21 @@ class Server(port: Int) {
|
|||
|
||||
implicit val formats: DefaultFormats.type = DefaultFormats
|
||||
val server: HttpServer = HttpServer.create(new InetSocketAddress(port), 32)
|
||||
server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool())
|
||||
|
||||
private def getRequestJson(ex: HttpExchange): JValue = {
|
||||
val requestBody = ex.getRequestBody
|
||||
val bytes = requestBody.readAllBytes
|
||||
val string = bytes.map(_.toChar).mkString
|
||||
val string = new String(bytes)
|
||||
parse(string)
|
||||
}
|
||||
|
||||
private val eqPattern = java.util.regex.Pattern.compile("=")
|
||||
private def getPathParameter(ex: HttpExchange): Either[String, Error] = {
|
||||
try {
|
||||
val uri = ex.getRequestURI.toString
|
||||
val pathParam = uri.split("\\?")(1)
|
||||
val param = pathParam.split("=")
|
||||
if (param(0) == "id") {
|
||||
val query = ex.getRequestURI.getQuery
|
||||
val param = eqPattern.split(query)
|
||||
if(param(0) == "id"){
|
||||
Left(param(1))
|
||||
} else {
|
||||
Right(Error(ErrorMessageEnum.INVALID_PARAM.toString + "=> id"))
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ def _(environment, **kw):
|
|||
environment.process_exit_code = 0
|
||||
|
||||
class QuickStartUser(SequentialTaskSet):
|
||||
wait_time = between(0.1,1)
|
||||
wait_time = between(0.1,0.2)
|
||||
|
||||
@task
|
||||
def captcha(self):
|
||||
|
|
@ -52,6 +52,6 @@ class QuickStartUser(SequentialTaskSet):
|
|||
|
||||
|
||||
class User(FastHttpUser):
|
||||
wait_time = between(0.1,1)
|
||||
wait_time = between(0.1,0.2)
|
||||
tasks = [QuickStartUser]
|
||||
host = "http://localhost:8888"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ java -jar target/scala-2.13/LibreCaptcha.jar &
|
|||
JAVA_PID=$!
|
||||
sleep 4
|
||||
|
||||
locust --headless -u 1000 -r 100 --run-time 4m --stop-timeout 30 -f tests/locustfile.py
|
||||
locust --headless -u 300 -r 100 --run-time 4m --stop-timeout 30 -f tests/locustfile.py
|
||||
status=$?
|
||||
|
||||
kill $JAVA_PID
|
||||
|
|
|
|||
Loading…
Reference in New Issue