Catalog/docs/api-race-upload-spec.md

6.5 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.xml servlet mappings
  • decompiled sources in WEB-INF/lib/*_src (notably AblServletSvlt, 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 (extends Logon4Svlt)
  • Body (application/x-www-form-urlencoded):
    • login
    • pwd
    • cmdIU=check

Other cmdIU values used:

  • cmdIU=login (logout)
  • cmdIU=np (password change)
  • cmdIU=checkSso (SSO branch if enabled)
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.abl
  • POST|GET /admin/pg/Foto.abl
  • POST|GET /admin/pg/TipoGara.abl
  • POST|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).
  • POST|GET /Foto2.abl
  • POST|GET /Logon.abl (mapped to com.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 fileName for generic file upload; this still works (stored by original filename)
  • Temporary target directory: DOCBASE + tmp/ (getPathTmp())
  • Per-upload file size target: about 20000 KB for this servlet path

Upload race image

Endpoint:

  • POST /admin/pg/Gara.abl

Required form fields:

  • cmd=loadImg
  • imgFile (binary)
  • id (race id)
  • codImage (slot index)
  • totImgNumber (typically 3 in 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=removeImg
  • id
  • codImage
  • totImgNumber

Response schema is the same JsonUploadImageResponse[].

Upload CSV/file for race processing

Endpoint:

  • POST /admin/pg/Gara.abl

UI helper (Ab.saveFile) sends:

  • cmd=saveFile
  • fileName (binary file)
  • codFile (slot id, usually 1)
  • id (often 0 in 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:

  • addPuntoFoto
  • delPuntoFoto
  • modPuntoFoto
  • indexFoto
  • noIndexFoto
  • creaPuntiFoto
  • indexCsvPisa
  • salvaFileCsv

Important parameters by command:

  • id_gara for race-level operations
  • id_puntoFoto and id_puntoFotoIdx for point selection
  • point fields such as descrizionePuntoFoto, pathRelativoFoto, tipoPuntoFoto

CSV flow coupling:

  1. cmd=saveFile uploads to tmp/ and returns fileName
  2. UI stores it into hidden field fileNameOnServer_1
  3. cmd=salvaFileCsv copies DOCBASE/tmp/<fileNameOnServer_1> to DOCBASE/admin/csv/<id_gara>.csv
  4. cmd=indexCsvPisa reads admin/csv/<id_gara>.csv via Gara.getImpCsvFileName() and updates matching photos

Image retrieval behavior

/foto/* (GetFileTnSvlt):

  • accepts id_foto query parameter, or extracts id from URL suffix pattern like name-<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 returns result=true with an error message.

For robust clients, validate both:

  • result
  • message text + expected output field (imgPath / fileName non-empty)

Practical automation sequence

  1. Login on /admin/menu/Menu4.abl with cmdIU=check, store cookies.
  2. Create/update race data on /admin/pg/Gara.abl with regular form commands.
  3. Upload images with cmd=loadImg.
  4. (Optional) upload CSV with cmd=saveFile.
  5. Finalize CSV placement with cmd=salvaFileCsv and run cmd=indexCsvPisa.
  6. Read thumbnails from /foto/* and originals from /fotoOriginali/*.