# HTTP

> Reference for the HTTP driver: polling HTTP and HTTPS endpoints as tags, credentials, path mapping, body parsing, PUT writes and types.

The HTTP driver polls **generic HTTP endpoints** as tags: a LAN sensor with a tiny
web server, a gateway that publishes readings at fixed URLs, a service of your own.
It is the simplest client-mode driver in the product: **Ganter Lab connects to the
equipment** with plain GET requests and reads each response body as one value.

Two properties draw the line around what it is for:

- The transport is **the device's own choice**. A device reaches its service over TLS
  until its **Send over plain HTTP** tick says otherwise, and a host written with
  `http://` or `https://` in front of it moves that tick and is kept as the bare host,
  so the two can never disagree. Either way the driver sends the device's credential,
  a username and password as HTTP Basic or a bearer token, on every request. What the
  [AVEVA PI](driver-aveva-pi) and [Redfish](driver-redfish) drivers still add for
  those two services is their vocabulary (PI paths and WebIds, Redfish resource
  trees), which this driver knows nothing about.
- The **whole response body is the value**. The driver is not a JSON field
  extractor: a numeric tag expects the body to be the bare number.

## Connection fields {#connection-fields}

| Field | What it is | Format | Default |
|---|---|---|---|
| Host | The endpoint's host name or IP address. A host written with `http://` or `https://` in front of it moves the transport tick below to match and is stored without it. A port written after the host (`:8080`) goes to the Port field and a path after it (`/api`) to the Resource path, so a whole address such as `http://192.168.0.5:8080/api` can be pasted here. An IPv6 address keeps its brackets. | Host name, IP, or either with `http://` or `https://` in front | empty |
| Port | The TCP port. A new device leaves it empty, and an empty box means the port the chosen transport answers on, 443 over HTTPS and 80 in the clear: the box shows that port in grey and follows the transport tick, which is also how a device saved with 0 reads. | 1 to 65535, or empty | empty |
| Resource path | An optional path prefix put in front of **every** tag's path, e.g. `api/v2`. Blank prefixes nothing. | path text | blank |
| Send over plain HTTP | Steps this one device down from HTTPS to clear HTTP. Off means HTTPS, which is what keeps a credential off the wire. The panel states the consequence: on plain HTTP the requests, and any credential the device carries, travel unencrypted. Use it for an endpoint that answers on no other transport. | on / off | off |
| Username | Account for **HTTP Basic** authentication, used only when no bearer token is set. Empty (with no token) leaves the requests anonymous. | Free text | empty |
| Password | The password paired with the username. Protected at rest per Windows user; a secret entered under another Windows account shows as unreadable and must be re-entered. | Free text | empty |
| Bearer token | A token sent as `Authorization: Bearer …` on every request. When set it **wins over** the username/password pair. Protected at rest the same way. | Token text | empty |

On connect the driver verifies the endpoint with a HEAD request to the **configured
address**, host plus resource path, falling back to GET when HEAD is not
implemented; an address that answers either one successfully counts as reachable.
A service whose root answers 404 while its API answers normally is therefore online,
as long as the resource path points at the API. Over HTTPS the service's TLS
certificate is accepted when Windows trusts it, or when you approved that very
certificate under [Equipment access](#equipment-access) on this driver's page. A credential on a
device stepped down to plain HTTP travels unencrypted, and the station says so in the
connector journal when the device connects. Each request is given ten seconds:
an endpoint that accepts the connection and then says nothing costs one reading,
not the whole device, because the other tags of the device are read in the same
pass. The poll interval is configurable: the device default (1000 ms) applies to
every tag that does not state its own.

## Tag addressing {#tag-addressing}

The tag's **Path** field is the URL path relative to the device's resource path:

| Field | What it does | Values | Default |
|---|---|---|---|
| Path | The path requested for this tag. The full URL is `<transport>://<host>:<port>/<resource path>/<path>`. | Free text (required) | empty |

Example: host `192.168.0.40` stepped down to plain HTTP, resource path `api`, tag
path `sensors/temp` polls `http://192.168.0.40/api/sensors/temp`.

## Reads {#reads}

Each poll GETs the tag's URL and parses the **entire response body** by the tag's
declared data type:

| Type | Accepted body |
|---|---|
| Float | A number, invariant format (`21.5`, decimal point, no thousands separators) |
| Int32 | An integer (`42`) |
| Boolean | `true` or `false` |
| String | Anything; the body is the value verbatim (a JSON document arrives as its raw text) |

A body the declared type cannot parse, or a non-success status code, reads as a
failed read: the tag goes to bad quality and its read-failure policy decides what
is presented, as described on the [Connector](connector) page. A non-success status is
the endpoint refusing the read, and the tag's reason names the status and quotes what the
endpoint said with it (`HTTP 404 Not Found: …`), in the same words as a refused write or
command. A body the declared type cannot parse gives the tag a reason that quotes what could not
be read, and the device stays connected. An endpoint that does not answer at all is the device's
connection failing: the device reports it and reconnects, and its tags point to it. The tag's red line says such a status in the station's language, with what it means for 401, 403 and 404, and a body that does not parse as an answer that does not read as the tag's type; the Events page keeps the endpoint's own words.

## Writes {#writes}

Tags with a writable access mode write with **PUT** to the same URL: the body is
the value as JSON, sent with content type `application/json`. A number goes as a
bare literal (`42.5`), a boolean as `true` or `false`, and text goes quoted
(`"automatic"`). The endpoint decides what to make of it; a non-success status is the endpoint refusing the value, and the refusal names the status and quotes what the endpoint said with it, in the same words as a refused command, so whoever wrote the value reads why. As everywhere else, the write box takes the engineering value and the tag's
conversion stages are reversed before the raw value goes on the wire, as described
on the [Connector](connector) page.

## Supported data types {#supported-data-types}

Boolean, Int32, Float and String.

## Commands {#commands}

A tag reads a value; a command asks the service to do something. Declare each one on the
device, in the **Commands** card of its page: a name, the path it is POSTed to (under the
device's own address, exactly as a tag's path is), and optionally the name of the one value
it takes. The row's Run verb sends it and reports what the service answered, and the command
also becomes a method on the device in this station's own OPC UA address space, so anything
that can call a method can issue it. The value you type is sent as the request body, as
written.

What the service answers is the command's result. A status the service returns outside the success
range is the service refusing the command, not the connection failing: the refusal names the status
and quotes what the service said with it ("HTTP 500 Internal Server Error: the burner is locked out"), and nothing else on
the device is disturbed by it.

## Discovery {#discovery}

The driver has no discovery scan. Add each endpoint by host and each value by its
path; the add-a-device flow is described on the [Connector](connector) page.

## Equipment access {#equipment-access}

An HTTPS endpoint with a self-signed certificate, or one issued by an authority of its own,
presents a certificate no root installed in Windows vouches for. That root does not need to
be installed on this computer. The first connection is refused, the device reads **Waiting
for certificate approval** in the tree and on its page, whose **Review certificate** button
opens this card on the certificate, and the certificate waits under **Equipment access** at
the end of the HTTP driver's page, the same card the OPC UA driver's page carries, until you
decide:

| Group | What it lists | What you can do |
|---|---|---|
| Waiting for approval | Each refused certificate, under the name it claims: its SHA-256 fingerprint, the address it was met at, when it last tried and how many times, and its details (subject, issuer, domain names, validity dates). The one a device's Review certificate opened is marked Selected for review. | **Approve** accepts the certificate from the device's next connection attempt. **Block** keeps refusing it without listing it here again. **Discard all pending certificates** empties the list without approving or blocking anything. |
| Approved equipment | The certificates you approved or imported, with who decided and when, and the address each was last met at. | **Withdraw approval** closes the device's connection and returns its certificate to the list. **Import certificate** approves a public certificate file you already have (.der, .cer, .crt or .pem) before the first connection. |
| Blocked equipment | The certificates you blocked. A blocked certificate is refused even if Windows trusts it. | **Unblock** returns the certificate to the list, without approving it. |

Check the fingerprint with whoever manages the equipment before you approve it. An approval
accepts that certificate and no other, and only within its validity dates; it stands in for
the root Windows lacks and for the name the certificate carries, so an endpoint dialed by its
IP address connects although its certificate names another host, and nothing else about the
certificate is relaxed. When the endpoint answers an address whose certificate you approved
with another one, reading stops, the new one waits here, and the station raises "Certificate
changed: `<name>`" with a **Review** button. A certificate Windows already trusts is accepted
as before and never appears here; nothing is approved automatically. A device stepped down to
plain HTTP presents no certificate and never waits here.

The driver's own failure says the reason instead of a nameless TLS error: "This equipment's
certificate (the first 16 characters of the fingerprint) is waiting for your approval under
Equipment access on the HTTP driver's page. Reading starts once you approve it." A blocked one
reads "…is blocked at this station. Review it under Equipment access on the HTTP driver's
page." A certificate outside its validity dates, revoked or with a broken signature is refused
with that reason and is never listed, since no approval makes it sound.

The decisions are kept in the station's data folder, under `ua\pki\http`, and survive a
restart. Only a role that may configure the Connector is drawn the verbs, and they act only
in the station's own window: a browser on another device reads the card without changing it,
and no agent tool approves a certificate (`connector_browse` reports the waiting device with
`awaitingCertificate`). The list holds up to 100 certificates waiting for approval; once it
is full, a new one is still refused but not listed, and the card says so.
