mirror of
https://github.com/KeymonSoft/jRDC-Multi.git
synced 2026-04-18 21:29:29 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 48dbd1f034 | |||
|
|
2f9569b585 |
@@ -5,10 +5,6 @@ Type=Class
|
|||||||
Version=10.3
|
Version=10.3
|
||||||
@EndOfDesignText@
|
@EndOfDesignText@
|
||||||
' Handler class for JSON requests from Web Clients (JavaScript/axios)
|
' Handler class for JSON requests from Web Clients (JavaScript/axios)
|
||||||
' VERSIÓN 16 (Comentarios y Mensajes en Español):
|
|
||||||
' - Se añaden comentarios detallados a la versión con mensajes de error en español.
|
|
||||||
' - Revisa que el 'query' exista en config.properties antes de continuar.
|
|
||||||
' - Asegura que la conexión a la BD se cierre en todos los 'Return' para evitar fugas.
|
|
||||||
Sub Class_Globals
|
Sub Class_Globals
|
||||||
' Declara una variable privada para mantener una instancia del conector RDC.
|
' Declara una variable privada para mantener una instancia del conector RDC.
|
||||||
' Este objeto maneja la comunicación con la base de datos.
|
' Este objeto maneja la comunicación con la base de datos.
|
||||||
@@ -62,9 +58,17 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
|
|||||||
|
|
||||||
' Extrae los datos necesarios del JSON.
|
' Extrae los datos necesarios del JSON.
|
||||||
Dim execType As String = RootMap.GetDefault("exec", "") ' Tipo de ejecución: "executeQuery" o "executeCommand".
|
Dim execType As String = RootMap.GetDefault("exec", "") ' Tipo de ejecución: "executeQuery" o "executeCommand".
|
||||||
Dim queryName As String = RootMap.Get("query") ' Nombre del comando SQL (definido en config.properties).
|
Dim queryName As String = RootMap.Get("query") ' Nombre del comando SQL (definido en config.properties).
|
||||||
Dim paramsMap As Map = RootMap.Get("params") ' Un mapa con los parámetros para la consulta.
|
|
||||||
' Log(RootMap)
|
' Se obtiene "params" como una Lista en lugar de un Mapa.
|
||||||
|
Dim paramsList As List = RootMap.Get("params")
|
||||||
|
|
||||||
|
' Si la lista de parámetros es nula (no se proporcionó en el JSON),
|
||||||
|
' la inicializamos como una lista vacía para evitar errores más adelante.
|
||||||
|
If paramsList = Null Or paramsList.IsInitialized = False Then
|
||||||
|
paramsList.Initialize
|
||||||
|
End If
|
||||||
|
|
||||||
' Verifica si en el JSON se especificó un nombre de base de datos diferente con la clave "dbx".
|
' Verifica si en el JSON se especificó un nombre de base de datos diferente con la clave "dbx".
|
||||||
If RootMap.Get("dbx") <> Null Then DB = RootMap.Get("dbx") ' Si se especifica, usamos la BD indicada, si no, se queda "DB1".
|
If RootMap.Get("dbx") <> Null Then DB = RootMap.Get("dbx") ' Si se especifica, usamos la BD indicada, si no, se queda "DB1".
|
||||||
|
|
||||||
@@ -75,35 +79,12 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
|
|||||||
Return
|
Return
|
||||||
End If
|
End If
|
||||||
|
|
||||||
' Prepara una lista para almacenar las claves de los parámetros.
|
|
||||||
Dim paramKeys As List
|
|
||||||
paramKeys.Initialize
|
|
||||||
' Si el mapa de parámetros existe y está inicializado...
|
|
||||||
If paramsMap <> Null And paramsMap.IsInitialized Then
|
|
||||||
' ...itera sobre todas las claves y las añade a la lista 'paramKeys'.
|
|
||||||
For Each key As String In paramsMap.Keys
|
|
||||||
paramKeys.Add(key)
|
|
||||||
Next
|
|
||||||
End If
|
|
||||||
' Ordena las claves alfabéticamente. Esto es crucial para asegurar que los parámetros
|
|
||||||
' se pasen a la consulta SQL en un orden consistente y predecible.
|
|
||||||
paramKeys.Sort(True)
|
|
||||||
|
|
||||||
' Prepara una lista para almacenar los valores de los parámetros en el orden correcto.
|
|
||||||
Dim orderedParams As List
|
|
||||||
orderedParams.Initialize
|
|
||||||
' Itera sobre la lista de claves ya ordenada.
|
|
||||||
For Each key As String In paramKeys
|
|
||||||
' Añade el valor correspondiente a cada clave a la lista 'orderedParams'.
|
|
||||||
orderedParams.Add(paramsMap.Get(key))
|
|
||||||
Next
|
|
||||||
|
|
||||||
' Obtiene una conexión a la base de datos del pool de conexiones.
|
' Obtiene una conexión a la base de datos del pool de conexiones.
|
||||||
con = Connector.GetConnection(DB)
|
con = Connector.GetConnection(DB)
|
||||||
' Obtiene la cadena SQL del archivo de configuración usando el nombre de la consulta (queryName).
|
' Obtiene la cadena SQL del archivo de configuración usando el nombre de la consulta (queryName).
|
||||||
Dim sqlCommand As String = Connector.GetCommand(DB, queryName)
|
Dim sqlCommand As String = Connector.GetCommand(DB, queryName)
|
||||||
|
|
||||||
' <<< INICIO NUEVA VALIDACIÓN: VERIFICAR SI EL COMANDO EXISTE >>>
|
' <<< INICIO VALIDACIÓN: VERIFICAR SI EL COMANDO EXISTE >>>
|
||||||
' Comprueba si el comando SQL (query) especificado en el JSON fue encontrado en el archivo de configuración.
|
' Comprueba si el comando SQL (query) especificado en el JSON fue encontrado en el archivo de configuración.
|
||||||
If sqlCommand = Null Or sqlCommand = "null" Or sqlCommand.Trim = "" Then
|
If sqlCommand = Null Or sqlCommand = "null" Or sqlCommand.Trim = "" Then
|
||||||
' Si no se encontró el comando, crea un mensaje de error claro.
|
' Si no se encontró el comando, crea un mensaje de error claro.
|
||||||
@@ -117,7 +98,7 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
|
|||||||
' Detiene la ejecución del método Handle para esta petición.
|
' Detiene la ejecución del método Handle para esta petición.
|
||||||
Return
|
Return
|
||||||
End If
|
End If
|
||||||
' <<< FIN NUEVA VALIDACIÓN >>>
|
' <<< FIN VALIDACIÓN >>>
|
||||||
|
|
||||||
' Comprueba el tipo de ejecución solicitado ("executeQuery" o "executeCommand").
|
' Comprueba el tipo de ejecución solicitado ("executeQuery" o "executeCommand").
|
||||||
If execType.ToLowerCase = "executequery" Then
|
If execType.ToLowerCase = "executequery" Then
|
||||||
@@ -125,15 +106,15 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
|
|||||||
Dim rs As ResultSet
|
Dim rs As ResultSet
|
||||||
|
|
||||||
' Si el comando SQL contiene placeholders ('?'), significa que espera parámetros.
|
' Si el comando SQL contiene placeholders ('?'), significa que espera parámetros.
|
||||||
If sqlCommand.Contains("?") or orderedParams.Size > 0 Then
|
' Se usa 'paramsList' directamente en lugar de 'orderedParams'.
|
||||||
|
If sqlCommand.Contains("?") Or paramsList.Size > 0 Then
|
||||||
' =================================================================
|
' =================================================================
|
||||||
' === VALIDACIÓN DE CONTEO DE PARÁMETROS ==========================
|
' === VALIDACIÓN DE CONTEO DE PARÁMETROS ==========================
|
||||||
' =================================================================
|
' =================================================================
|
||||||
' Calcula cuántos parámetros espera la consulta contando el número de '?'.
|
' Calcula cuántos parámetros espera la consulta contando el número de '?'.
|
||||||
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
|
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
|
||||||
' Obtiene cuántos parámetros se recibieron.
|
' Obtiene cuántos parámetros se recibieron de la lista.
|
||||||
Dim receivedParams As Int = orderedParams.Size
|
Dim receivedParams As Int = paramsList.Size
|
||||||
' Compara si la cantidad de parámetros esperados y recibidos es diferente.
|
|
||||||
|
|
||||||
Log($"expectedParams: ${expectedParams}, receivedParams: ${receivedParams}"$)
|
Log($"expectedParams: ${expectedParams}, receivedParams: ${receivedParams}"$)
|
||||||
|
|
||||||
@@ -146,8 +127,8 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
|
|||||||
Return
|
Return
|
||||||
End If
|
End If
|
||||||
' =================================================================
|
' =================================================================
|
||||||
' Ejecuta la consulta pasando el comando SQL y la lista ordenada de parámetros.
|
' Ejecuta la consulta pasando el comando SQL y la lista de parámetros.
|
||||||
rs = con.ExecQuery2(sqlCommand, orderedParams)
|
rs = con.ExecQuery2(sqlCommand, paramsList)
|
||||||
Else
|
Else
|
||||||
' Si no hay '?', ejecuta la consulta directamente sin parámetros.
|
' Si no hay '?', ejecuta la consulta directamente sin parámetros.
|
||||||
rs = con.ExecQuery(sqlCommand)
|
rs = con.ExecQuery(sqlCommand)
|
||||||
@@ -193,7 +174,7 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
|
|||||||
' === VALIDACIÓN DE CONTEO DE PARÁMETROS (para Comandos) ==========
|
' === VALIDACIÓN DE CONTEO DE PARÁMETROS (para Comandos) ==========
|
||||||
' =================================================================
|
' =================================================================
|
||||||
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
|
Dim expectedParams As Int = sqlCommand.Length - sqlCommand.Replace("?", "").Length
|
||||||
Dim receivedParams As Int = orderedParams.Size
|
Dim receivedParams As Int = paramsList.Size
|
||||||
If expectedParams <> receivedParams Then
|
If expectedParams <> receivedParams Then
|
||||||
SendErrorResponse(resp, 400, $"Número de parametros equivocado para '${queryName}'. Se esperaban ${expectedParams} y se recibieron ${receivedParams}."$)
|
SendErrorResponse(resp, 400, $"Número de parametros equivocado para '${queryName}'. Se esperaban ${expectedParams} y se recibieron ${receivedParams}."$)
|
||||||
' Cierra la conexión antes de salir.
|
' Cierra la conexión antes de salir.
|
||||||
@@ -205,7 +186,7 @@ Sub Handle(req As ServletRequest, resp As ServletResponse)
|
|||||||
End If
|
End If
|
||||||
|
|
||||||
' Ejecuta el comando que no devuelve resultados (NonQuery) con sus parámetros.
|
' Ejecuta el comando que no devuelve resultados (NonQuery) con sus parámetros.
|
||||||
con.ExecNonQuery2(sqlCommand, orderedParams)
|
con.ExecNonQuery2(sqlCommand, paramsList)
|
||||||
' Envía una respuesta de éxito con un mensaje de confirmación.
|
' Envía una respuesta de éxito con un mensaje de confirmación.
|
||||||
SendSuccessResponse(resp, CreateMap("message": "Command executed successfully"))
|
SendSuccessResponse(resp, CreateMap("message": "Command executed successfully"))
|
||||||
|
|
||||||
@@ -262,5 +243,3 @@ Private Sub SendErrorResponse(resp As ServletResponse, statusCode As Int, errorM
|
|||||||
resp.ContentType = "application/json"
|
resp.ContentType = "application/json"
|
||||||
resp.Write(jsonGenerator.ToString)
|
resp.Write(jsonGenerator.ToString)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
320
RDCHandler.bas
320
RDCHandler.bas
@@ -1,320 +0,0 @@
|
|||||||
B4J=true
|
|
||||||
Group=Default Group
|
|
||||||
ModulesStructureVersion=1
|
|
||||||
Type=Class
|
|
||||||
Version=4.19
|
|
||||||
@EndOfDesignText@
|
|
||||||
'Handler class
|
|
||||||
Sub Class_Globals
|
|
||||||
' #if VERSION1
|
|
||||||
Private const T_NULL = 0, T_STRING = 1, T_SHORT = 2, T_INT = 3, T_LONG = 4, T_FLOAT = 5 _
|
|
||||||
,T_DOUBLE = 6, T_BOOLEAN = 7, T_BLOB = 8 As Byte
|
|
||||||
Private bc As ByteConverter
|
|
||||||
Private cs As CompressedStreams
|
|
||||||
' #end if
|
|
||||||
Private DateTimeMethods As Map
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Public Sub Initialize
|
|
||||||
DateTimeMethods = CreateMap(91: "getDate", 92: "getTime", 93: "getTimestamp")
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Sub Handle(req As ServletRequest, resp As ServletResponse)
|
|
||||||
Log("***********************************************")
|
|
||||||
Log(">>>> RDC")
|
|
||||||
Dim start As Long = DateTime.Now
|
|
||||||
Dim q As String
|
|
||||||
Dim in As InputStream = req.InputStream
|
|
||||||
Dim method As String = req.GetParameter("method")
|
|
||||||
Dim con As SQL
|
|
||||||
Try
|
|
||||||
con = Main.rdcConnector0.GetConnection("")
|
|
||||||
If method = "query2" Then
|
|
||||||
q = ExecuteQuery2(con, in, resp)
|
|
||||||
'#if VERSION1
|
|
||||||
Else if method = "query" Then
|
|
||||||
in = cs.WrapInputStream(in, "gzip")
|
|
||||||
q = ExecuteQuery(con, in, resp)
|
|
||||||
Else if method = "batch" Then
|
|
||||||
in = cs.WrapInputStream(in, "gzip")
|
|
||||||
q = ExecuteBatch(con, in, resp)
|
|
||||||
'#end if
|
|
||||||
Else if method = "batch2" Then
|
|
||||||
q = ExecuteBatch2(con, in, resp)
|
|
||||||
Else
|
|
||||||
Log("Unknown method: " & method)
|
|
||||||
resp.SendError(500, "unknown method")
|
|
||||||
End If
|
|
||||||
Catch
|
|
||||||
Log(LastException)
|
|
||||||
resp.SendError(500, LastException.Message)
|
|
||||||
End Try
|
|
||||||
If con <> Null And con.IsInitialized Then con.Close
|
|
||||||
Log($"Command: ${q}, took: ${DateTime.Now - start}ms, client=${req.RemoteAddress}"$)
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub ExecuteQuery2 (con As SQL, in As InputStream, resp As ServletResponse) As String
|
|
||||||
Dim ser As B4XSerializator
|
|
||||||
Dim m As Map = ser.ConvertBytesToObject(Bit.InputStreamToBytes(in))
|
|
||||||
Dim cmd As DBCommand = m.Get("command")
|
|
||||||
Dim limit As Int = m.Get("limit")
|
|
||||||
Dim rs As ResultSet = con.ExecQuery2(Main.rdcConnector0.GetCommand(cmd.Name), cmd.Parameters)
|
|
||||||
If limit <= 0 Then limit = 0x7fffffff 'max int
|
|
||||||
Dim jrs As JavaObject = rs
|
|
||||||
Dim rsmd As JavaObject = jrs.RunMethod("getMetaData", Null)
|
|
||||||
Dim cols As Int = rs.ColumnCount
|
|
||||||
Dim res As DBResult
|
|
||||||
res.Initialize
|
|
||||||
res.columns.Initialize
|
|
||||||
res.Tag = Null 'without this the Tag properly will not be serializable.
|
|
||||||
For i = 0 To cols - 1
|
|
||||||
res.columns.Put(rs.GetColumnName(i), i)
|
|
||||||
Next
|
|
||||||
res.Rows.Initialize
|
|
||||||
Do While rs.NextRow And limit > 0
|
|
||||||
Dim row(cols) As Object
|
|
||||||
For i = 0 To cols - 1
|
|
||||||
Dim ct As Int = rsmd.RunMethod("getColumnType", Array(i + 1))
|
|
||||||
'check whether it is a blob field
|
|
||||||
If ct = -2 Or ct = 2004 Or ct = -3 Or ct = -4 Then
|
|
||||||
row(i) = rs.GetBlob2(i)
|
|
||||||
Else If ct = 2005 Then
|
|
||||||
row(i) = rs.GetString2(i)
|
|
||||||
Else if ct = 2 Or ct = 3 Then
|
|
||||||
row(i) = rs.GetDouble2(i)
|
|
||||||
Else If DateTimeMethods.ContainsKey(ct) Then
|
|
||||||
Dim SQLTime As JavaObject = jrs.RunMethodJO(DateTimeMethods.Get(ct), Array(i + 1))
|
|
||||||
If SQLTime.IsInitialized Then
|
|
||||||
row(i) = SQLTime.RunMethod("getTime", Null)
|
|
||||||
Else
|
|
||||||
row(i) = Null
|
|
||||||
End If
|
|
||||||
Else
|
|
||||||
row(i) = jrs.RunMethod("getObject", Array(i + 1))
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
res.Rows.Add(row)
|
|
||||||
Loop
|
|
||||||
rs.Close
|
|
||||||
Dim data() As Byte = ser.ConvertObjectToBytes(res)
|
|
||||||
resp.OutputStream.WriteBytes(data, 0, data.Length)
|
|
||||||
Return "query: " & cmd.Name
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub ExecuteBatch2(con As SQL, in As InputStream, resp As ServletResponse) As String
|
|
||||||
Dim ser As B4XSerializator
|
|
||||||
Dim m As Map = ser.ConvertBytesToObject(Bit.InputStreamToBytes(in))
|
|
||||||
Dim commands As List = m.Get("commands")
|
|
||||||
Dim res As DBResult
|
|
||||||
res.Initialize
|
|
||||||
res.columns = CreateMap("AffectedRows (N/A)": 0)
|
|
||||||
res.Rows.Initialize
|
|
||||||
res.Tag = Null
|
|
||||||
Try
|
|
||||||
con.BeginTransaction
|
|
||||||
For Each cmd As DBCommand In commands
|
|
||||||
con.ExecNonQuery2(Main.rdcConnector0.GetCommand(cmd.Name), _
|
|
||||||
cmd.Parameters)
|
|
||||||
Next
|
|
||||||
res.Rows.Add(Array As Object(0))
|
|
||||||
con.TransactionSuccessful
|
|
||||||
Catch
|
|
||||||
con.Rollback
|
|
||||||
Log(LastException)
|
|
||||||
resp.SendError(500, LastException.Message)
|
|
||||||
End Try
|
|
||||||
Dim data() As Byte = ser.ConvertObjectToBytes(res)
|
|
||||||
resp.OutputStream.WriteBytes(data, 0, data.Length)
|
|
||||||
Return $"batch (size=${commands.Size})"$
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
'#if VERSION1
|
|
||||||
|
|
||||||
Private Sub ExecuteBatch(con As SQL, in As InputStream, resp As ServletResponse) As String
|
|
||||||
Dim clientVersion As Float = ReadObject(in) 'ignore
|
|
||||||
Dim numberOfStatements As Int = ReadInt(in)
|
|
||||||
Dim res(numberOfStatements) As Int
|
|
||||||
Try
|
|
||||||
con.BeginTransaction
|
|
||||||
For i = 0 To numberOfStatements - 1
|
|
||||||
Dim queryName As String = ReadObject(in)
|
|
||||||
Dim params As List = ReadList(in)
|
|
||||||
con.ExecNonQuery2(Main.rdcConnector0.GetCommand(queryName), _
|
|
||||||
params)
|
|
||||||
Next
|
|
||||||
con.TransactionSuccessful
|
|
||||||
|
|
||||||
Dim out As OutputStream = cs.WrapOutputStream(resp.OutputStream, "gzip")
|
|
||||||
WriteObject(Main.VERSION, out)
|
|
||||||
WriteObject("batch", out)
|
|
||||||
WriteInt(res.Length, out)
|
|
||||||
For Each r As Int In res
|
|
||||||
WriteInt(r, out)
|
|
||||||
Next
|
|
||||||
out.Close
|
|
||||||
Catch
|
|
||||||
con.Rollback
|
|
||||||
Log(LastException)
|
|
||||||
resp.SendError(500, LastException.Message)
|
|
||||||
End Try
|
|
||||||
Return $"batch (size=${numberOfStatements})"$
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub ExecuteQuery (con As SQL, in As InputStream, resp As ServletResponse) As String
|
|
||||||
' Log("==== ExecuteQuery ==== ")
|
|
||||||
Dim clientVersion As Float = ReadObject(in) 'ignore
|
|
||||||
Dim queryName As String = ReadObject(in)
|
|
||||||
Dim limit As Int = ReadInt(in)
|
|
||||||
Dim params As List = ReadList(in)
|
|
||||||
' Log("EL QUERY: |" & queryName & "|")
|
|
||||||
Private theSql As String = Main.rdcConnector0.GetCommand(queryName)
|
|
||||||
' Log(theSql)
|
|
||||||
' Log(params)
|
|
||||||
' Log(params.Size)
|
|
||||||
Dim rs As ResultSet = con.ExecQuery2(theSql, params)
|
|
||||||
If limit <= 0 Then limit = 0x7fffffff 'max int
|
|
||||||
Dim jrs As JavaObject = rs
|
|
||||||
Dim rsmd As JavaObject = jrs.RunMethod("getMetaData", Null)
|
|
||||||
Dim cols As Int = rs.ColumnCount
|
|
||||||
Dim out As OutputStream = cs.WrapOutputStream(resp.OutputStream, "gzip")
|
|
||||||
WriteObject(Main.VERSION, out)
|
|
||||||
WriteObject("query", out)
|
|
||||||
WriteInt(rs.ColumnCount, out)
|
|
||||||
' Log($"cols: ${cols}"$)
|
|
||||||
For i = 0 To cols - 1
|
|
||||||
WriteObject(rs.GetColumnName(i), out)
|
|
||||||
Next
|
|
||||||
|
|
||||||
Do While rs.NextRow And limit > 0
|
|
||||||
WriteByte(1, out)
|
|
||||||
For i = 0 To cols - 1
|
|
||||||
Dim ct As Int = rsmd.RunMethod("getColumnType", Array(i + 1))
|
|
||||||
'check whether it is a blob field
|
|
||||||
If ct = -2 Or ct = 2004 Or ct = -3 Or ct = -4 Then
|
|
||||||
WriteObject(rs.GetBlob2(i), out)
|
|
||||||
Else
|
|
||||||
WriteObject(jrs.RunMethod("getObject", Array(i + 1)), out)
|
|
||||||
End If
|
|
||||||
Next
|
|
||||||
Loop
|
|
||||||
WriteByte(0, out)
|
|
||||||
out.Close
|
|
||||||
rs.Close
|
|
||||||
|
|
||||||
Return "query: " & queryName
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub WriteByte(value As Byte, out As OutputStream)
|
|
||||||
out.WriteBytes(Array As Byte(value), 0, 1)
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Private Sub WriteObject(o As Object, out As OutputStream)
|
|
||||||
Dim data() As Byte
|
|
||||||
If o = Null Then
|
|
||||||
out.WriteBytes(Array As Byte(T_NULL), 0, 1)
|
|
||||||
Else If o Is Short Then
|
|
||||||
out.WriteBytes(Array As Byte(T_SHORT), 0, 1)
|
|
||||||
data = bc.ShortsToBytes(Array As Short(o))
|
|
||||||
Else If o Is Int Then
|
|
||||||
out.WriteBytes(Array As Byte(T_INT), 0, 1)
|
|
||||||
data = bc.IntsToBytes(Array As Int(o))
|
|
||||||
Else If o Is Float Then
|
|
||||||
out.WriteBytes(Array As Byte(T_FLOAT), 0, 1)
|
|
||||||
data = bc.FloatsToBytes(Array As Float(o))
|
|
||||||
Else If o Is Double Then
|
|
||||||
out.WriteBytes(Array As Byte(T_DOUBLE), 0, 1)
|
|
||||||
data = bc.DoublesToBytes(Array As Double(o))
|
|
||||||
Else If o Is Long Then
|
|
||||||
out.WriteBytes(Array As Byte(T_LONG), 0, 1)
|
|
||||||
data = bc.LongsToBytes(Array As Long(o))
|
|
||||||
Else If o Is Boolean Then
|
|
||||||
out.WriteBytes(Array As Byte(T_BOOLEAN), 0, 1)
|
|
||||||
Dim b As Boolean = o
|
|
||||||
Dim data(1) As Byte
|
|
||||||
If b Then data(0) = 1 Else data(0) = 0
|
|
||||||
Else If GetType(o) = "[B" Then
|
|
||||||
data = o
|
|
||||||
out.WriteBytes(Array As Byte(T_BLOB), 0, 1)
|
|
||||||
WriteInt(data.Length, out)
|
|
||||||
Else 'If o Is String Then (treat all other values as string)
|
|
||||||
out.WriteBytes(Array As Byte(T_STRING), 0, 1)
|
|
||||||
data = bc.StringToBytes(o, "UTF8")
|
|
||||||
WriteInt(data.Length, out)
|
|
||||||
End If
|
|
||||||
If data.Length > 0 Then out.WriteBytes(data, 0, data.Length)
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub ReadObject(In As InputStream) As Object
|
|
||||||
Dim data(1) As Byte
|
|
||||||
In.ReadBytes(data, 0, 1)
|
|
||||||
Select data(0)
|
|
||||||
Case T_NULL
|
|
||||||
Return Null
|
|
||||||
Case T_SHORT
|
|
||||||
Dim data(2) As Byte
|
|
||||||
Return bc.ShortsFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
|
||||||
Case T_INT
|
|
||||||
Dim data(4) As Byte
|
|
||||||
Return bc.IntsFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
|
||||||
Case T_LONG
|
|
||||||
Dim data(8) As Byte
|
|
||||||
Return bc.LongsFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
|
||||||
Case T_FLOAT
|
|
||||||
Dim data(4) As Byte
|
|
||||||
Return bc.FloatsFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
|
||||||
Case T_DOUBLE
|
|
||||||
Dim data(8) As Byte
|
|
||||||
Return bc.DoublesFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
|
||||||
Case T_BOOLEAN
|
|
||||||
Dim b As Byte = ReadByte(In)
|
|
||||||
Return b = 1
|
|
||||||
Case T_BLOB
|
|
||||||
Dim len As Int = ReadInt(In)
|
|
||||||
Dim data(len) As Byte
|
|
||||||
Return ReadBytesFully(In, data, data.Length)
|
|
||||||
Case Else
|
|
||||||
Dim len As Int = ReadInt(In)
|
|
||||||
Dim data(len) As Byte
|
|
||||||
ReadBytesFully(In, data, data.Length)
|
|
||||||
Return BytesToString(data, 0, data.Length, "UTF8")
|
|
||||||
End Select
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub ReadBytesFully(In As InputStream, Data() As Byte, Len As Int) As Byte()
|
|
||||||
Dim count = 0, Read As Int
|
|
||||||
Do While count < Len And Read > -1
|
|
||||||
Read = In.ReadBytes(Data, count, Len - count)
|
|
||||||
count = count + Read
|
|
||||||
Loop
|
|
||||||
Return Data
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub WriteInt(i As Int, out As OutputStream)
|
|
||||||
Dim data() As Byte
|
|
||||||
data = bc.IntsToBytes(Array As Int(i))
|
|
||||||
out.WriteBytes(data, 0, data.Length)
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub ReadInt(In As InputStream) As Int
|
|
||||||
Dim data(4) As Byte
|
|
||||||
Return bc.IntsFromBytes(ReadBytesFully(In, data, data.Length))(0)
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub ReadByte(In As InputStream) As Byte
|
|
||||||
Dim data(1) As Byte
|
|
||||||
In.ReadBytes(data, 0, 1)
|
|
||||||
Return data(0)
|
|
||||||
End Sub
|
|
||||||
|
|
||||||
Private Sub ReadList(in As InputStream) As List
|
|
||||||
Dim len As Int = ReadInt(in)
|
|
||||||
Dim l1 As List
|
|
||||||
l1.Initialize
|
|
||||||
For i = 0 To len - 1
|
|
||||||
l1.Add(ReadObject(in))
|
|
||||||
Next
|
|
||||||
Return l1
|
|
||||||
End Sub
|
|
||||||
'#end If
|
|
||||||
39
faviconHandler.bas
Normal file
39
faviconHandler.bas
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
B4J=true
|
||||||
|
Group=Default Group
|
||||||
|
ModulesStructureVersion=1
|
||||||
|
Type=Class
|
||||||
|
Version=10.3
|
||||||
|
@EndOfDesignText@
|
||||||
|
'Class module: FaviconHandler
|
||||||
|
' Manejador para la petición de /favicon.ico
|
||||||
|
' Simplemente devuelve un estado HTTP 204 (No Content)
|
||||||
|
' para indicar al navegador que no hay un favicon.
|
||||||
|
|
||||||
|
Sub Class_Globals
|
||||||
|
' No se necesitan variables globales para este manejador simple.
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Sub Initialize
|
||||||
|
' No se necesita inicialización específica para este manejador.
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Sub Handle(req As ServletRequest, resp As ServletResponse)
|
||||||
|
' Registra la petición en el Log (opcional, para depuración)
|
||||||
|
' Log("Petición de Favicon recibida: " & req.RequestURI)
|
||||||
|
'
|
||||||
|
' Establece el código de estado HTTP a 204 (No Content).
|
||||||
|
' Esto le dice al navegador que la petición fue exitosa, pero no hay contenido que devolver.
|
||||||
|
resp.Status = 204
|
||||||
|
|
||||||
|
' Es buena práctica cerrar el OutputStream, aunque para 204 no haya contenido explícito.
|
||||||
|
' Algunos servidores web podrían requerir cerrar el stream de respuesta.
|
||||||
|
Try
|
||||||
|
resp.OutputStream.Close
|
||||||
|
Catch
|
||||||
|
Log("Error al cerrar el OutputStream en FaviconHandler: " & LastException)
|
||||||
|
End Try
|
||||||
|
|
||||||
|
' El Return es fundamental para que el manejador termine su ejecución
|
||||||
|
' y no intente procesar la petición con otros manejadores o caiga en el "catch-all".
|
||||||
|
Return
|
||||||
|
End Sub
|
||||||
@@ -31,26 +31,27 @@ Library7=json
|
|||||||
Library8=jsql
|
Library8=jsql
|
||||||
Library9=bcrypt
|
Library9=bcrypt
|
||||||
Module1=ChangePassHandler
|
Module1=ChangePassHandler
|
||||||
Module10=RDCConnector
|
Module10=ping
|
||||||
Module11=TestHandler
|
Module11=RDCConnector
|
||||||
|
Module12=TestHandler
|
||||||
Module2=DBHandlerB4X
|
Module2=DBHandlerB4X
|
||||||
Module3=DBHandlerJSON
|
Module3=DBHandlerJSON
|
||||||
Module4=DoLoginHandler
|
Module4=DoLoginHandler
|
||||||
Module5=GlobalParameters
|
Module5=faviconHandler
|
||||||
Module6=LoginHandler
|
Module6=GlobalParameters
|
||||||
Module7=LogoutHandler
|
Module7=LoginHandler
|
||||||
Module8=Manager
|
Module8=LogoutHandler
|
||||||
Module9=ping
|
Module9=Manager
|
||||||
NumberOfFiles=10
|
NumberOfFiles=10
|
||||||
NumberOfLibraries=9
|
NumberOfLibraries=9
|
||||||
NumberOfModules=11
|
NumberOfModules=12
|
||||||
Version=10.3
|
Version=10.3
|
||||||
@EndOfDesignText@
|
@EndOfDesignText@
|
||||||
'Non-UI application (console / server application)
|
'Non-UI application (console / server application)
|
||||||
#Region Project Attributes
|
#Region Project Attributes
|
||||||
#CommandLineArgs:
|
#CommandLineArgs:
|
||||||
#MergeLibraries: True
|
#MergeLibraries: True
|
||||||
' VERSION 5.09.01
|
' VERSION 5.09.08
|
||||||
'###########################################################################################################
|
'###########################################################################################################
|
||||||
'###################### PULL #############################################################
|
'###################### PULL #############################################################
|
||||||
'Ctrl + click ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=git&Args=pull
|
'Ctrl + click ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=git&Args=pull
|
||||||
@@ -119,24 +120,25 @@ Sub AppStart (Args() As String)
|
|||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
End If
|
End If
|
||||||
srvr.AddHandler("/ping", "ping", False) ' Agrega un manejador a la ruta "/test", asignando las solicitudes a la clase TestHandler, el último parámetro indica si el manejador debe ejecutar en un nuevo hilo (False en este caso)
|
srvr.AddHandler("/ping", "ping", True) ' Agrega un manejador a la ruta "/test", asignando las solicitudes a la clase TestHandler, el último parámetro indica si el manejador debe ejecutar en un nuevo hilo (False en este caso)
|
||||||
srvr.AddHandler("/test", "TestHandler", False) ' Agrega un manejador a la ruta "/test", asignando las solicitudes a la clase TestHandler, el último parámetro indica si el manejador debe ejecutar en un nuevo hilo (False en este caso)
|
srvr.AddHandler("/test", "TestHandler", True) ' Agrega un manejador a la ruta "/test", asignando las solicitudes a la clase TestHandler, el último parámetro indica si el manejador debe ejecutar en un nuevo hilo (False en este caso)
|
||||||
|
|
||||||
' --- INICIO DE CAMBIOS ---
|
' --- INICIO DE CAMBIOS ---
|
||||||
' 1. Rutas para el sistema de Login
|
' 1. Rutas para el sistema de Login
|
||||||
srvr.AddHandler("/login", "LoginHandler", False) ' Sirve la página de login
|
srvr.AddHandler("/login", "LoginHandler", True) ' Sirve la página de login
|
||||||
srvr.AddHandler("/dologin", "DoLoginHandler", False) ' Procesa el intento de login
|
srvr.AddHandler("/dologin", "DoLoginHandler", True) ' Procesa el intento de login
|
||||||
srvr.AddHandler("/logout", "LogoutHandler", False) ' Cierra la sesión
|
srvr.AddHandler("/logout", "LogoutHandler", True) ' Cierra la sesión
|
||||||
srvr.AddHandler("/changepass", "ChangePassHandler", False)
|
srvr.AddHandler("/changepass", "ChangePassHandler", True)
|
||||||
' 2. El handler del manager se queda igual, pero ahora estará protegido
|
' 2. El handler del manager se queda igual, pero ahora estará protegido
|
||||||
srvr.AddHandler("/manager", "Manager", False)
|
srvr.AddHandler("/manager", "Manager", True)
|
||||||
' --- FIN DE CAMBIOS ---
|
' --- FIN DE CAMBIOS ---
|
||||||
|
|
||||||
srvr.AddHandler("/DBJ", "DBHandlerJSON", False)
|
srvr.AddHandler("/DBJ", "DBHandlerJSON", True)
|
||||||
srvr.AddHandler("/dbrquery", "DBHandlerJSON", False)
|
srvr.AddHandler("/dbrquery", "DBHandlerJSON", True)
|
||||||
|
srvr.AddHandler("/favicon.ico", "faviconHandler", True)
|
||||||
' srvr.AddHandler("/*", "DB1Handler", False) ' Si no se especifica una base de datos, entonces asignamos la solicitud a la DB1.
|
' srvr.AddHandler("/*", "DB1Handler", False) ' Si no se especifica una base de datos, entonces asignamos la solicitud a la DB1.
|
||||||
|
|
||||||
srvr.AddHandler("/*", "DBHandlerB4X", False)
|
srvr.AddHandler("/*", "DBHandlerB4X", True)
|
||||||
|
|
||||||
srvr.Start
|
srvr.Start
|
||||||
Log("===========================================================")
|
Log("===========================================================")
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
ModuleBookmarks1=
|
ModuleBookmarks1=
|
||||||
ModuleBookmarks10=
|
ModuleBookmarks10=
|
||||||
ModuleBookmarks11=
|
ModuleBookmarks11=
|
||||||
|
ModuleBookmarks12=
|
||||||
ModuleBookmarks2=
|
ModuleBookmarks2=
|
||||||
ModuleBookmarks3=
|
ModuleBookmarks3=
|
||||||
ModuleBookmarks4=
|
ModuleBookmarks4=
|
||||||
@@ -14,6 +15,7 @@ ModuleBreakpoints0=
|
|||||||
ModuleBreakpoints1=
|
ModuleBreakpoints1=
|
||||||
ModuleBreakpoints10=
|
ModuleBreakpoints10=
|
||||||
ModuleBreakpoints11=
|
ModuleBreakpoints11=
|
||||||
|
ModuleBreakpoints12=
|
||||||
ModuleBreakpoints2=
|
ModuleBreakpoints2=
|
||||||
ModuleBreakpoints3=
|
ModuleBreakpoints3=
|
||||||
ModuleBreakpoints4=
|
ModuleBreakpoints4=
|
||||||
@@ -26,6 +28,7 @@ ModuleClosedNodes0=
|
|||||||
ModuleClosedNodes1=
|
ModuleClosedNodes1=
|
||||||
ModuleClosedNodes10=
|
ModuleClosedNodes10=
|
||||||
ModuleClosedNodes11=
|
ModuleClosedNodes11=
|
||||||
|
ModuleClosedNodes12=
|
||||||
ModuleClosedNodes2=
|
ModuleClosedNodes2=
|
||||||
ModuleClosedNodes3=
|
ModuleClosedNodes3=
|
||||||
ModuleClosedNodes4=
|
ModuleClosedNodes4=
|
||||||
@@ -34,6 +37,6 @@ ModuleClosedNodes6=
|
|||||||
ModuleClosedNodes7=
|
ModuleClosedNodes7=
|
||||||
ModuleClosedNodes8=
|
ModuleClosedNodes8=
|
||||||
ModuleClosedNodes9=
|
ModuleClosedNodes9=
|
||||||
NavigationStack=DoLoginHandler,Initialize,7,0,Manager,Initialize,98,0,ChangePassHandler,Handle,27,0,DoLoginHandler,Handle,9,0,Manager,Handle0,202,6,TestHandler,Handle,11,0,LoginHandler,Handle,16,1,Manager,Handle,110,6,Main,Process_Globals,24,0,Main,AppStart,85,0
|
NavigationStack=DBHandlerJSON,Initialize,16,0,DBHandlerJSON,Handle,207,6,ChangePassHandler,Handle,15,0,DBHandlerB4X,Handle,80,0,Main,AppStart,88,0,DBHandlerJSON,Class_Globals,10,0,DBHandlerJSON,SendErrorResponse,239,0,RDCConnector,LoadConfigMap,86,0,RDCConnector,GetCommand,90,0,RDCConnector,Initialize,75,0,RDCConnector,Class_Globals,9,0
|
||||||
SelectedBuild=0
|
SelectedBuild=0
|
||||||
VisibleModules=2,3,10,8,11,6
|
VisibleModules=2,3,11,9,12,7,1
|
||||||
|
|||||||
Reference in New Issue
Block a user