- Implemented IRaceUploadCommunicationClient with methods for saving races, creating race points, indexing race points, retrieving race details, and uploading files to the receiver. - Added ReceiveFilePath option to CatalogCommunicationOptions for file transfer configuration. - Enhanced CatalogCommunicationServiceCollectionExtensions to validate ReceiveFilePath. - Developed RaceUploadCommunicationClient to handle race-related API interactions, including saving race data and uploading processed images. - Updated API documentation to reflect new race upload and file transfer endpoints. - Modified Avalonia UI to support race creation and processed image uploads, including new input fields and buttons. - Introduced RaceSaveRequest and ReceiveFileUploadRequest models for structured data handling.
8.2 KiB
API Specification (code-backed): races, images, and authentication
Scope and evidence
This document is reverse-engineered from:
- JSP/JS usage in the web app
WEB-INF/web.xmlservlet mappings- decompiled sources in
WEB-INF/lib/*_src(notablyAblServletSvlt,AcServlet,GaraSvlt,Logon4Svlt,Menu4Svlt,GetFileTnSvlt)
The upload response schemas below are now confirmed from code, not inferred.
Base URL
Examples use:
https://your-host
Authentication (how to obtain the usable token)
Actual auth model
This app uses server session authentication, not JWT bearer tokens.
Login success sets session attributes:
loginUser_id(Long)utenteLogon(user object)
For automation, the practical token is the session cookie (JSESSIONID and any app cookies).
Admin login endpoint
POST /admin/menu/Menu4.abl- Servlet mapping:
com.ablia.anag.servlet.Menu4Svlt(extendsLogon4Svlt) - Body (
application/x-www-form-urlencoded):loginpwdcmdIU=check
Other cmdIU values used:
cmdIU=login(logout)cmdIU=np(password change)cmdIU=checkSso(SSO branch if enabled)
cURL login example (capture session cookie)
curl -i -c cookies.txt -X POST "https://your-host/admin/menu/Menu4.abl" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "login=YOUR_USER&pwd=YOUR_PASSWORD&cmdIU=check"
Reuse cookie jar for authenticated calls:
curl -i -b cookies.txt "https://your-host/admin/pg/Gara.abl?cmd=search"
Token note (Bearer/Basic)
- No
Authorization: Bearer ...flow is present in inspected sources. - A helper exists to parse
Authorization: Basic(getBasicAuthorizationHeaders), but no race/photo endpoint uses it directly.
Relevant endpoints
Admin race/photo endpoints
POST|GET /admin/pg/Gara.ablPOST|GET /admin/pg/Foto.ablPOST|GET /admin/pg/TipoGara.ablPOST|GET /admin/pg/LogFoto.abl
Deployment caveat:
- some deployments expose the same admin pages under
POST|GET /admin/pg_RUS/*.abl. - On
https://www.regalamiunsorriso.it, post-login dashboard links point to/admin/pg_RUS/Gara.abl(not/admin/pg/Gara.abl).
Public/web endpoints related to photos/users
POST|GET /Foto2.ablPOST|GET /Logon.abl(mapped tocom.ablia.pg.servlet.Logon2Svlt)POST|GET /Users.abl
Note: /Login.abl in web.xml is mapped to cart servlet (CartSvlt), not admin login.
File serving endpoints
GET /foto/*→GetFileTnSvlt(thumbnail by default)GET /fotoOriginali/*→GetFileOrigSvlt(original file flow)
Multipart upload contract (common engine)
All race-image/file uploads go through AblServletSvlt.manageImgFileMultipartRequest + AcServlet.manageMultipartRequestParameters.
Key behavior:
- File fields explicitly recognized:
imgFile,nomeFile - UI also sends
fileNamefor generic file upload; this still works (stored by original filename) - Temporary target directory:
DOCBASE + tmp/(getPathTmp()) - Per-upload file size target: about
20000 KBfor this servlet path
Upload race image
Endpoint:
POST /admin/pg/Gara.abl
Required form fields:
cmd=loadImgimgFile(binary)id(race id)codImage(slot index)totImgNumber(typically3in UI)
Storage details:
- Race attachment path from
Gara.getPathAttach()is_img/_gara/ - Thumbnail is generated into
_img/_gara/100/(100x75)
Response schema (confirmed)
Response is JSON array with one object (JsonUploadImageResponse):
result(boolean)message(string)imgPath(string)
Example success payload shape:
[
{
"result": true,
"message": "...Immagine 1 Salvata...",
"imgPath": "../../_img/_gara/100/<generated-file>"
}
]
Delete race image
Endpoint:
POST /admin/pg/Gara.abl
Fields:
cmd=removeImgidcodImagetotImgNumber
Response schema is the same JsonUploadImageResponse[].
Upload CSV/file for race processing
Endpoint:
POST /admin/pg/Gara.abl
UI helper (Ab.saveFile) sends:
cmd=saveFilefileName(binary file)codFile(slot id, usually1)id(often0in UI flow)
Response schema (confirmed)
JSON array with one JsonUploadFileResponse object:
result(boolean)message(string)fileName(stored/original name)fileNameLink(typically../../tmp/<fileName>)
Example shape:
[
{
"result": true,
"message": "...",
"fileName": "punti-foto.csv",
"fileNameLink": "../../tmp/punti-foto.csv"
}
]
Race command API (/admin/pg/Gara.abl)
Confirmed custom commands in GaraSvlt:
asq+act=save(generic save used by admin UI toolbar)ni(new record flow before save)addPuntoFotodelPuntoFotomodPuntoFotoindexFotonoIndexFotocreaPuntiFotoindexCsvPisasalvaFileCsv
Important parameters by command:
id_garafor race-level operationsid_puntoFotoandid_puntoFotoIdxfor point selection- point fields such as
descrizionePuntoFoto,pathRelativoFoto,tipoPuntoFoto
Race save payload fields (from admin/pg_RUS/gara.jsp + _V4/_js/_bean.js):
- mandatory in practice:
descrizione,dataGaraInizio,id_tipoGara - commonly sent:
dataGaraFine,flgEventoInLinea,flgTipoIndex,pathBase,flgFree,localita - command envelope for save:
cmd=asq,act=save
Confirmed fixed-flag value sets from UI templates:
flgEventoInLinea:0(Non In Linea),1(Stand By),2(In Linea)flgTipoIndex:0,1flgFree:0(No),1(SI)
Server-side normalization behavior:
Gara.save()appends trailing/topathBaseif missing.- if
pathBaseis empty anddataGaraIniziois set, server auto-derivespathBaseas<year>/<id_gara>/. PuntoFoto.prepareSave()appends trailing/topathRelativoFotoif missing.
CSV flow coupling:
cmd=saveFileuploads totmp/and returnsfileName- UI stores it into hidden field
fileNameOnServer_1 cmd=salvaFileCsvcopiesDOCBASE/tmp/<fileNameOnServer_1>toDOCBASE/admin/csv/<id_gara>.csvcmd=indexCsvPisareadsadmin/csv/<id_gara>.csvviaGara.getImpCsvFileName()and updates matching photos
Processed photo transfer channel (/ReceiveFile.abl)
The original 3-piano -> WWW photo push does not use Gara.abl multipart for each processed photo.
It uses UploadFile against a dedicated receiver servlet:
POST /ReceiveFile.abl- servlet class:
com.ablia.servlet.ReceiveFileSvlt - typically unauthenticated (
isSecureServlet=falsein decompiled source)
Observed request shape:
- query params:
name,path,overwriteRemoteFile,bs - request body: raw file bytes stream
Usage in workflow:
- destination path is computed per punto-foto on remote side (
puntoFotoR.getPathCompletoFoto()) - processed image and thumbnail (
tn_<filename>) are both transferred - after transfer, photo flags are updated/indexed via DB-backed commands (
indexFoto/ CSV/indexing flows)
Image retrieval behavior
/foto/* (GetFileTnSvlt):
- accepts
id_fotoquery parameter, or extracts id from URL suffix pattern likename-<id>.jpg - if photo not found, serves
_img/_imgNotFound.png - returns thumbnail by default in this servlet flow
/fotoOriginali/* (GetFileOrigSvlt):
- routes to original-file logic
- applies user/account checks (valid user, not expired, max photos)
- blocks some originals by filename markers (
_X,_Y,_Z) depending on profile - logs photo view events when original is served
Known response caveat
Do not treat result=true as universally reliable for success semantics:
- in some error branches (
_loadImg,_removeImg,_saveFile), code still returnsresult=truewith an error message.
For robust clients, validate both:
resultmessagetext + expected output field (imgPath/fileNamenon-empty)
Practical automation sequence
- Login on
/admin/menu/Menu4.ablwithcmdIU=check, store cookies. - Create race on
/admin/pg_RUS/Gara.ablwithcmd=asq,act=saveand race fields. - Create and/or manage punti foto (
addPuntoFoto,creaPuntiFoto,modPuntoFoto). - Transfer processed files with
/ReceiveFile.ablto remote race/punto paths. - Trigger indexing (
indexFotoper punto, or CSV viasaveFile+salvaFileCsv+indexCsvPisa). - Read thumbnails from
/foto/*and originals from/fotoOriginali/*.