SERVING A SECURE PAGE WITH PLAIN-HTTP MEDIA FROM A TIBBO DEVICE
Applies to: Tibbo G3 devices (e.g. TPP2W(G3))
Sample project: HTTPS_HTTP
OVERVIEW
Every HTTPS connection incurs a TLS handshake, which takes a noticeable amount of processing time and requires larger socket buffers. The TLS engine can also hold only about seven sessions at once. A web page that loads many images can open many connections, and making all of them over HTTPS is slow and may lead to request timeouts.
A practical compromise is to serve the page itself over HTTPS and fixed, non-sensitive media files (images) over plain HTTP. The HTTPS_HTTP sample does exactly this:
- 2 HTTPS sockets on port 443 serve index.html.
- 6 HTTP sockets on port 80 serve eight image tiles that the page assembles into one picture.
This article covers the certificate the HTTPS side needs, how sockets and buffers are set up, how the page references the HTTP images, and what to expect from the browser.
WHEN THIS APPROACH IS APPROPRIATE
Anything sent over HTTP can be read and changed by anyone on the network path. Serve only content that is public and harmless if altered: logos, photos, icons, fixed diagrams.
Never serve over HTTP:
- anything containing user or device data;
- login pages, forms, or anything that sets or reads cookies;
- scripts (.js), stylesheets (.css), fonts, or frames. Browsers block these on an HTTPS page when they come over HTTP (this is "mixed active content"), so they would not work anyway.
Images, audio, and video loaded over HTTP from an HTTPS page are "mixed passive content". Browsers load them, but they mark the page as not fully secure (see "What the browser shows" below).
WHAT YOU NEED
- OpenSSL 3.x on your PC to create the certificate.
- TIDE with the HTTPS_HTTP sample project.
- The IP address the device will use. The examples use 192.168.1.218; replace it with your own address.
- A web browser on a PC in the same network.
PART 1 - THE CERTIFICATE
The HTTPS side of this sample is a TLS server, so it needs exactly the same certificate and server bundle as the SSL_MULTI_SERVER sample. Follow the TLS server article [LINK: TLS_Inbound_SSL_MULTI_SERVER]:
- Part 1: create the certificate with the device's IP in the SAN (ECDSA P-256 recommended).
- Part 2: build server_bundle.der (certificate DER followed by key DER).
- Part 4: install the .crt file on Windows as a trusted root.
If you have already done this for SSL_MULTI_SERVER on the same device IP, you can reuse the same server_bundle.der and the same Windows installation. The certificate is bound to the IP address, not to the port, so it works on port 443 as well as 8443.
Copy server_bundle.der into the HTTPS_HTTP project folder and ensure it is included in the project in TIDE. The name must match CERT_BUNDLE in global.tbh:
#define CERT_BUNDLE "server_bundle.der"
PART 2 - SOCKETS AND BUFFERS
The settings are in global.tbh:
const DEVICE_IP = "192.168.1.218" must match the IP in the certificate
const DEVICE_MASK = "255.255.255.0"
const DEVICE_GW = "192.168.1.1"
const NUM_HTTPS_SOCKS = 2
#define HTTPS_LISTEN_PORT "443"
#define HTTPS_RX_BUFF 6 use 8 for RSA 2048
#define HTTPS_TX_BUFF 6 use 8 for RSA 2048
#define HTTPS_VAR_BUFF 1
const NUM_HTTP_SOCKS = 6
#define HTTP_LISTEN_PORT "80"
#define HTTP_TX_BUFF 3
#define HTTP_VAR_BUFF 1Sockets 0 to NUM_HTTPS_SOCKS-1 are the HTTPS sockets; the rest, up to NUM_HTTPS_SOCKS + NUM_HTTP_SOCKS - 1, are the HTTP sockets. The sample allocates and configures each group in a for...next loop, so changing a count in global.tbh is all that is needed. Buffer sizes are given in pages (1 page = 256 bytes).
HTTPS sockets need an RX buffer
During the TLS handshake, the browser sends data to the device, and the TLS engine needs a real RX buffer to receive it. Each HTTPS socket gets RX, TX, and variable buffers:
sock.rxbuffrq(HTTPS_RX_BUFF)
sock.txbuffrq(HTTPS_TX_BUFF)
sock.varbuffrq(HTTPS_VAR_BUFF)
HTTP sockets do not need an RX buffer
On a plain HTTP socket the incoming request is handled by the built-in HTTP engine, and the data that matters flows one way, from the device to the browser. The sample therefore requests only TX and variable buffers, and shorts the RX buffer by redirecting the socket to itself:
sock.txbuffrq(HTTP_TX_BUFF)
sock.varbuffrq(HTTP_VAR_BUFF)
...
sock.redir(PL_REDIR_SOCK0 + sock.num)This cannot be done on the HTTPS sockets, because of the handshake.
With the default values, the sample uses 26 pages for the two HTTPS sockets (2 x (6 + 6 + 1)) and 24 pages for the six HTTP sockets (6 x (3 + 1)). The device prints the number of free pages after allocation at boot.
Both groups use the built-in HTTP engine
sock.httpmode = YES
sock.httpportlist = HTTPS_LISTEN_PORT (or HTTP_LISTEN_PORT)
sock.inconmode = PL_SOCK_INCONMODE_ANY_IP_ANY_PORTFor the HTTPS sockets, the only extra step is starting TLS when a browser connects. When the socket reports PL_SST_EST_POPENED, the sample loads the bundle and starts the handshake:
romfile.open(CERT_BUNDLE)
tls_res = sock.tlsinit(romfile.offset)
tls_res = sock.tlshandshake("")Once the handshake completes (PL_SST_EST_TLS), the HTTP engine serves the page over the encrypted connection. The HTTP sockets need no code of their own. Why only two HTTPS sockets? The page is a single file, so one or two HTTPS connections are enough. The images are where the bulk of the connections happens.
PART 3 - THE PAGE
index.html is served over HTTPS. Each image points explicitly at the HTTP server by using a full http:// address. The device fills in its own IP with server-side script, so the page works whatever address the device has:
<img src="http://<? sock.setdata(net.ip) ?>/tile_01.jpg">
<img src="http://<? sock.setdata(net.ip) ?>/tile_02.jpg">
...
<img src="http://<? sock.setdata(net.ip) ?>/tile_08.jpg">A relative address such as src="tile_01.jpg" would make the browser fetch the image from the same HTTPS server as the page, which defeats the purpose.
The sample includes eight 200 x 200 pixel JPEG tiles (tile_01.jpg to tile_08.jpg, about 3 KB each), which the page arranges into a 4 x 2 grid. Keep media files small: every image is sent through a 3-page TX buffer.
PART 4 - BUILD AND TEST
- Build the project in TIDE and upload it to the device.
- At boot the device prints the free buffer pages and "HTTPS_HTTP ready. HTTPS on port 443 (2 sockets), HTTP on port 80 (6 sockets)".
- Open https://192.168.1.218 in the browser (use your device's address).
- The page appears with the eight tiles forming one picture.
The debug output shows which socket served each request:
https[0] incoming from 192.168.1.70:51230
https[0] TLS handshake started...
https[0] TLS established, HTTP engine serving
http[2] incoming from 192.168.1.70:51231
http[3] incoming from 192.168.1.70:51232
...The page request should appear on an https[n] socket and the tile requests on http[n] sockets.
WHAT THE BROWSER SHOWS
Because the images arrive over HTTP, the browser treats the page as mixed content. Depending on the browser and its version, you may see:
- The page and images load, and the address bar shows a "not fully secure" or "not secure" indicator instead of the padlock; or
- The browser tries to upgrade the image addresses to https://on its own. With this sample the upgraded requests still succeed, because the HTTPS sockets can serve the same files, but they then use the HTTPS sockets instead of the HTTP ones. The debug output will show the tile requests on https[n] instead of http[n].
A certificate warning is a different problem: it means the certificate is not trusted or does not match the address. See Troubleshooting.
TROUBLESHOOTING
The browser shows a certificate warning
Install the .crt file as a trusted root (TLS server article, Part 4), check that the address in the browser matches the IP in the certificate, and restart the browser.
"tlsinit FAILED" in the device's debug output
server_bundle.der is missing, misnamed, or not built with the certificate first and the key second.
"TLS handshake FAILED - resetting", or the page loads slowly
For RSA 2048, raise HTTPS_RX_BUFF and HTTPS_TX_BUFF to 8.
Not enough buffer pages at boot
Reduce NUM_HTTP_SOCKS or HTTP_TX_BUFF, or use an ECDSA certificate so the HTTPS buffers can stay at 6 pages.
Comments
0 comments
Article is closed for comments.