# HTTP

> Riferimento del driver HTTP - interrogare endpoint HTTP e HTTPS come tag, credenziali, corrispondenza dei percorsi, analisi del corpo, scritture PUT e tipi.

Il driver HTTP interroga **endpoint HTTP generici** come tag: un sensore di LAN con un
minuscolo server web, un gateway che pubblica letture a URL fissi, un servizio scritto
in proprio. È il driver in modo client più semplice del prodotto: **è Ganter Lab a
collegarsi all'apparecchiatura** con semplici richieste GET, e legge il corpo di ogni
risposta come un solo valore.

Due proprietà tracciano il confine di ciò a cui serve:

- Il trasporto è **la scelta del dispositivo stesso**. Un dispositivo raggiunge il suo
  servizio in TLS finché la sua spunta **Invia in HTTP semplice** non dice altro, e un host
  scritto con `http://` o `https://` davanti sposta quella spunta e resta salvato come host
  nudo, così i due non possono mai contraddirsi.
  In un modo o nell'altro il driver invia la credenziale del dispositivo
  a ogni richiesta, un nome utente e una password in HTTP Basic oppure un token di
  autorizzazione. Quello che i driver [AVEVA PI](driver-aveva-pi) e
  [Redfish](driver-redfish) aggiungono ancora per quei due servizi è il loro lessico:
  percorsi PI e WebId, alberi di risorse di Redfish, di cui questo driver non sa nulla.
- **Il valore è tutto il corpo della risposta**. Il driver non è un estrattore di campi
  JSON: un tag numerico si aspetta che il corpo sia il numero nudo.

## Campi di connessione {#connection-fields}

| Campo | Che cos'è | Formato | Predefinito |
|---|---|---|---|
| Indirizzo host | Il nome host o l'indirizzo IP dell'endpoint. Un host scritto con `http://` o `https://` davanti sposta la spunta del trasporto qui sotto perché corrisponda, e resta salvato senza di esso. Una porta scritta dopo l'host (`:8080`) va nel campo Porta e un percorso dopo di esso (`/api`) nel percorso della risorsa, così qui si può incollare un indirizzo intero come `http://192.168.0.5:8080/api`. Un indirizzo IPv6 conserva le sue parentesi quadre. | Nome host, IP, oppure uno dei due con `http://` o `https://` davanti | vuoto |
| Porta | La porta TCP. Un dispositivo nuovo la lascia vuota, e un campo vuoto significa la porta su cui risponde il trasporto scelto, 443 in HTTPS e 80 in chiaro: il campo mostra quella porta in grigio e segue la scelta del trasporto; un dispositivo salvato con 0 si legge allo stesso modo. | Da 1 a 65535, o vuoto | vuoto |
| Percorso della risorsa | Un prefisso di percorso facoltativo messo davanti al percorso di **ogni** tag, per esempio `api/v2`. Vuoto non aggiunge alcun prefisso. | testo di percorso | vuoto |
| Invia in HTTP semplice | Fa scendere questo solo dispositivo da HTTPS all'HTTP in chiaro. Disattivato significa HTTPS, ed è questo che tiene una credenziale fuori dal cavo. Il pannello ne dichiara la conseguenza: in HTTP semplice le richieste, e qualsiasi credenziale del dispositivo, viaggiano non cifrate. Da usare per un endpoint che non risponde su nessun altro trasporto. | attivo / disattivo | disattivo |
| Nome utente | L'account per l'autenticazione **HTTP Basic**, usato solo quando non è impostato alcun token di autorizzazione. Vuoto (e senza token) lascia le richieste anonime. | Testo libero | vuoto |
| Password di accesso | La password abbinata al nome utente. Protetta a riposo per utente di Windows; un segreto inserito sotto un altro account Windows si presenta come illeggibile e va reinserito. | Testo libero | vuoto |
| Token di autorizzazione | Un token inviato come `Authorization: Bearer …` a ogni richiesta. Quando è impostato **vince** sulla coppia nome utente e password. Protetto a riposo allo stesso modo. | Testo del token | vuoto |

Alla connessione il driver verifica l'endpoint con una richiesta HEAD all'**indirizzo
configurato**, host più percorso della risorsa, ripiegando su GET quando HEAD non è
implementato; un indirizzo che risponde con successo a una delle due conta come
raggiungibile. Un servizio la cui radice risponde 404 mentre la sua API risponde
normalmente è quindi connesso, purché il percorso della risorsa punti all'API. In HTTPS
il certificato TLS del servizio viene accettato quando Windows lo considera attendibile, o
quando è stato approvato proprio quel certificato in
[Accesso delle apparecchiature](#equipment-access), nella pagina di questo driver. Una credenziale su un dispositivo sceso all'HTTP semplice viaggia non cifrata, e la
stazione lo scrive nel diario del connettore quando il dispositivo si collega. A ogni
richiesta vengono concessi dieci secondi: un endpoint che accetta la connessione e poi
non dice nulla costa una lettura, non l'intero dispositivo, perché gli altri tag del
dispositivo vengono letti nella stessa passata. L'intervallo di interrogazione è
configurabile: il valore predefinito del dispositivo (1000 ms) vale per ogni tag che
non dichiari il proprio.

## Indirizzamento dei tag {#tag-addressing}

Il campo **Percorso** del tag è il percorso dell'URL relativo al percorso della risorsa
del dispositivo:

| Campo | Che cosa fa | Valori | Predefinito |
|---|---|---|---|
| Percorso | Il percorso richiesto per questo tag. L'URL completo è `<transport>://<host>:<port>/<resource path>/<path>`. | Testo libero (obbligatorio) | vuoto |

Esempio: host `192.168.0.40` sceso all'HTTP semplice, percorso della risorsa `api`,
percorso del tag `sensors/temp` interroga `http://192.168.0.40/api/sensors/temp`.

## Letture {#reads}

Ogni interrogazione esegue una GET sull'URL del tag e analizza **l'intero corpo della
risposta** secondo il tipo di dato dichiarato dal tag:

| Tipo | Corpo accettato |
|---|---|
| Float | Un numero, in formato invariante (`21.5`, punto decimale, senza separatore delle migliaia) |
| Int32 | Un intero (`42`) |
| Boolean | `true` oppure `false` |
| String | Qualunque cosa; il corpo è il valore tale e quale (un documento JSON arriva come il suo testo grezzo) |

Un corpo che il tipo dichiarato non riesce ad analizzare, oppure un codice di stato
diverso da un successo, si legge come lettura fallita: il tag passa a cattiva qualità e
la sua politica di lettura fallita decide che cosa viene presentato, come è descritto
nella pagina [Connector](connector). Uno stato diverso da un successo è l'endpoint che
rifiuta la lettura, e il motivo del tag nomina lo stato e cita quello che l'endpoint ha
detto insieme a esso (`HTTP 404 Not Found: …`), con le stesse parole di una scrittura o di
un comando rifiutati. Un corpo che il tipo dichiarato non riesce ad analizzare dà al tag un
motivo che cita quello che non si è potuto leggere, e il dispositivo resta connesso. Un
endpoint che non risponde affatto è la connessione del dispositivo che fallisce: il
dispositivo lo segnala e si riconnette, e i suoi tag rimandano a esso. La riga rossa del tag dice uno stato simile nella lingua della stazione, con ciò che significa per 401, 403 e 404, e un corpo che non si analizza come una risposta che non si legge come un valore del tipo del tag; la pagina Eventi conserva le parole dell'endpoint stesso.

## Scritture {#writes}

I tag con una modalità di accesso scrivibile scrivono con **PUT** sullo stesso URL: il
corpo è il valore in JSON, inviato con tipo di contenuto `application/json`. Un numero
va come letterale nudo (`42.5`), un booleano come `true` oppure `false`, e il testo va
tra virgolette (`"automatic"`). È l'endpoint a decidere che cosa farne; uno stato diverso da un successo è l'endpoint che rifiuta il valore: il rifiuto nomina lo stato e cita quello che l'endpoint ha detto insieme a esso, con le stesse parole di quello di un comando rifiutato, e chi ha scritto il valore ne legge il motivo. Come dappertutto, la casella di
scrittura prende il valore ingegneristico e le fasi di conversione del tag vengono
percorse all'indietro prima che il valore grezzo vada sul bus, come è descritto nella
pagina [Connector](connector).

## Tipi di dato supportati {#supported-data-types}

Boolean, Int32, Float e String.

## Comandi {#commands}

Un tag legge un valore; un comando chiede al servizio di fare qualcosa. Ognuno si dichiara
sul dispositivo, nella scheda **Comandi** della sua pagina: un nome, il
percorso a cui viene inviato con una POST (sotto l'indirizzo proprio del dispositivo,
esattamente come il percorso di un tag) e, facoltativamente, il nome dell'unico valore
che accetta. Il verbo Invia della riga lo manda e riferisce quello che il servizio ha
risposto, e il comando diventa anche un metodo sul dispositivo nello spazio degli
indirizzi OPC UA proprio di questa stazione, così qualunque cosa sappia chiamare un
metodo lo può emettere. Il valore che scrivi viene inviato come corpo della richiesta,
così come è scritto.

Quello che il servizio risponde è il risultato del comando. Uno stato che il servizio
restituisce fuori dall'intervallo di successo è il servizio che rifiuta il comando, non
la connessione che fallisce: il rifiuto nomina lo stato e cita quello che il servizio
ha detto insieme a esso (« HTTP 500 Internal Server Error: il bruciatore è in blocco »), e nient'altro sul
dispositivo ne viene disturbato.

## Rilevamento {#discovery}

Il driver non ha alcuna scansione di rilevamento. Aggiungi ogni endpoint per host e
ogni valore per il suo percorso; il flusso per aggiungere un dispositivo è descritto
nella pagina [Connector](connector).

## Accesso delle apparecchiature {#equipment-access}

Un endpoint HTTPS con un certificato autofirmato, o emesso da un'autorità propria, presenta un certificato di cui nessuna radice installata in Windows si fa garante. Non serve installare quella radice su questo computer. La prima connessione viene rifiutata, il dispositivo legge **In attesa dell'approvazione del certificato** nell'albero e nella sua pagina, il cui pulsante **Verifica il certificato** apre questa scheda sul certificato, e il certificato attende in **Accesso delle apparecchiature**, alla fine della pagina del driver HTTP, la stessa scheda che porta la pagina del driver OPC UA, finché non si decide:

| Gruppo | Che cosa elenca | Che cosa si può fare |
|---|---|---|
| In attesa di approvazione | Ogni certificato rifiutato, con il nome che dichiara: la sua impronta SHA-256, l'indirizzo a cui è stato incontrato, quando ha tentato l'ultima volta e quante volte, e i suoi dettagli (soggetto, emittente, nomi di dominio, date di validità). Quello aperto da **Verifica il certificato** di un dispositivo è segnato come Selezionato per la verifica. | **Approva** accetta il certificato dal tentativo di connessione successivo. **Blocca** continua a rifiutarlo senza elencarlo di nuovo qui. **Scarta tutti i certificati in attesa** svuota l'elenco senza approvare né bloccare nulla. |
| Apparecchiature approvate | I certificati approvati o importati, con chi ha deciso e quando, e l'indirizzo a cui ciascuno è stato incontrato l'ultima volta. | **Ritira l'approvazione** chiude la connessione e riporta il certificato nell'elenco. **Importa certificato** approva un file di certificato pubblico già in proprio possesso (.der, .cer, .crt o .pem) prima della prima connessione. |
| Apparecchiature bloccate | I certificati bloccati. Un certificato bloccato viene rifiutato anche se Windows lo considera attendibile. | **Sblocca** riporta il certificato nell'elenco, senza approvarlo. |

Verificare l'impronta con chi gestisce l'apparecchiatura prima di approvare il certificato. Un'approvazione accetta quel certificato e nessun altro, e solo entro le sue date di validità; sostituisce la radice che manca a Windows e il nome che il certificato porta, così un endpoint chiamato con il suo indirizzo IP si collega anche se il suo certificato porta un altro nome, e nient'altro del certificato viene allentato. Quando l'apparecchiatura risponde a un indirizzo di cui era stato approvato il certificato con un altro (un certificato rinnovato), la lettura si ferma, il nuovo attende qui e la stazione segnala « Certificato cambiato: `<nome>` » con un pulsante **Verifica**. Un certificato che Windows considera già attendibile viene accettato come prima e non compare mai qui; nulla viene approvato automaticamente.

L'errore del driver stesso dice il motivo invece di un errore TLS senza nome: « Il certificato di questa apparecchiatura (i primi 16 caratteri dell'impronta) attende la vostra approvazione in Accesso delle apparecchiature, nella pagina del driver HTTP. La lettura inizia appena lo approvate. » Uno bloccato dice « …è bloccato in questa stazione. Verificarlo in Accesso delle apparecchiature, nella pagina del driver HTTP. » Un certificato fuori dalle sue date di validità, revocato o con la firma non valida viene rifiutato con quel motivo e non viene mai elencato, perché nessuna approvazione lo rende valido.

Le decisioni sono conservate nella cartella dati della stazione, in `ua\pki\http`, e sopravvivono a un riavvio. I verbi vengono disegnati solo per un ruolo che può configurare il Connector, e agiscono solo nella finestra della stazione stessa: un browser su un altro dispositivo legge la scheda senza cambiarla, e nessuno strumento di agente approva un certificato (`connector_browse` segnala il dispositivo in attesa con `awaitingCertificate`). L'elenco tiene fino a 100 certificati in attesa di approvazione; quando è pieno, uno nuovo viene ancora rifiutato ma non elencato, e la scheda lo dice.
