HTTP
RiptOPL can read a game library straight off an ordinary HTTP server: a small games.csv catalog
says what exists, and the console streams the ISO itself with plain HTTP byte ranges as the game
asks for sectors. The server must satisfy the client profile: no transfer encoding, no content
encoding other than identity, no multipart responses, exact Content-Range and Content-Length
for range reads, and complete response bodies. Check it with the
conformance tool.
Use HTTP only on a trusted, isolated local network. It provides no encryption or server/content authentication; range and length validation detect malformed responses, not substituted game data.
The design, the byte-range reader RiptOPL follows, and the PC server are Docmine17's (Open-PS2-Loader-HTTP).
His unmodified server is the compatibility baseline. If you already run it, RiptOPL points at
it as-is: same port, same games.csv, same folder layout. No new API, no catalog conversion, no
regeneration step, nothing to upgrade.
Status
Implemented and host-tested, not yet verified on PlayStation 2 hardware. Every part below exists in the build, but none of it has run on a PlayStation 2. Treat HTTP as a development feature until that changes.
| Part | State |
|---|---|
| Catalog fetch and parse | done, and cross-checked against a reference parser |
| Byte-range validation | done, and covered by host tests |
| Network settings, Test action | written, not hardware-tested |
| Game list, artwork, per-game settings | written, not hardware-tested |
| Launching a game | written, not hardware-tested โ this is the least proven part |
| DVD9 (dual layer) | probe implemented, never seen a real dual-layer read |
| Virtual memory cards | deliberately unavailable |
| Neutrino, PS1/VCD, Ember | deliberately unavailable |
| ZSO / compressed images | listed, refused by name |
Setting it up
On the PC, run an HTTP server meeting the profile above, with your ISOs under its document root,
and put a games.csv beside them. Docmine17's http_server.py does exactly this and defaults to
port 1100.
On the console, set Network Connectivity to Manual or Auto in Game Sources, then open Settings โ Network:
| Row | What it is |
|---|---|
| Protocol | choose HTTP |
| HTTP server | the PC's IPv4 address |
| HTTP port | 1100 by default; anything valid works, 80 and 8080 included |
| HTTP base path | / unless your catalog and images live in a subfolder |
| Test HTTP server | fetches the catalog, parses it, and reads one real byte range |
Use Test before saving. It tells you which part failed โ unreachable, catalog missing, catalog unreadable, or the server not returning the exact bytes asked for โ rather than one generic error.
An empty catalog is a valid answer, and Test says so plainly: it proves the server is there, and proves nothing at all about whether byte ranges work.
The first protocol selected while the adapter is unused can start immediately. Switching away from an already loaded protocol requires restarting RiptOPL; the UI reports that requirement. Only one protocol can own the adapter in a session.
The catalog
games.csv at the root of your base path, one game per line:
SLUS_123.45,Example Game,DVD,DVD/Example Game.iso
SLUS_200.01,"Example, The",DVD,DVD/example-the.iso
SLES_512.34,Short One,CD,CD/Short One.iso
STARTUP,TITLE,MEDIA,PATH โ the boot identifier, the name shown on screen, CD or DVD, and the
path to the image relative to your base path. The title and the filename need not resemble each
other.
Older catalogs keep working untouched. These are all still accepted:
# Filename derived from the title; media defaults to DVD
SLUS_123.45,Example Game
# Explicit media
SLUS_200.02,Another Game,CD
# Extension already on the title, not doubled
SLUS_300.03,Already Has Ext.iso,CD
# Startup only; it doubles as title and filename
SLUS_400.04
Blank lines and lines starting with # are ignored. Both LF and CRLF work, and a missing final
newline is fine. A field containing a comma or a quote can be double-quoted, "" being a literal
quote.
A row RiptOPL cannot use is skipped and the rest of the library still loads โ one typo does not
cost you every game. What gets a row skipped: no startup ID, a startup longer than 12 characters, a
media field that is not exactly CD or DVD, a path that escapes your base directory, an absolute
URL, or a filename that is not an image.
If a row names a path explicitly, that path is what gets requested. It is never quietly retried under a name derived from the title โ that is how you end up launching a different disc than the one you picked.
What works, and what does not
| Feature | Over HTTP |
|---|---|
| PS2 ISO, CD and DVD5 | the supported target |
| DVD9 | implemented, unproven โ see Status |
| Per-game settings, artwork, cheats | yes, stored locally (see below) |
| Favourites, last played | yes |
| Saving to a physical memory card | yes |
| Virtual memory cards | no โ nothing writes to the server, so there is nowhere to keep one |
| Neutrino core | no โ it would need its own HTTP backend |
| PS1 / VCD / Ember | no |
| ZSO and other compressed images | no โ they are listed but refuse to launch |
| HTTPS, passwords, redirects | no โ this is plain LAN HTTP |
The PS2 logo animation is skipped on HTTP launches. Checking it means reading the logo out of the image through a file handle, and HTTP has no filesystem to open one on.
Where per-game data lives
Folder-based sources keep CFG/, ART/ and CHT/ under the configured library prefix; APA uses its selected PFS data home.
HTTP cannot: the server is read-only and there is no drive to write to. So HTTP keeps them with
your settings instead โ under RiptOPLโs active local settings home (boot-directory/discovery or Custom Settings Path).
That is the one deliberate exception to the usual rule, and it is why covers and per-game options
for HTTP games go next to settings_riptopl.cfg rather than on the server.
When something goes wrong
RiptOPL refuses rather than guesses. A read is only accepted when the server returns exactly the bytes that were asked for: the right status, the right byte interval, and the right length. A server that ignores the range, answers a different interval, or stops early gets a disc read error instead of quietly feeding the game whatever arrived.
| What you see | What it means |
|---|---|
| Cannot reach the HTTP server | wrong address or port, or the server is not running |
| games.csv is missing, unreadable or too large | the catalog did not arrive intact |
| The server did not return the exact bytes | the server does not support byte ranges properly |
| Compressed images are not supported | the row points at a .zso |
If the server disappears mid-game, the console retries the same read once on a fresh connection and then reports a disc error. It will not sit there reconnecting forever.
Notes for anyone changing this code
src/httpcatalog.candpc/http/catalog_reference.pyare one contract. The fixtures inpc/http/fixtures/hold them to it andpc/http/tests/compare_catalog.pyproves it. Change one, change all three, in the same commit.- Run the host tests.
sh pc/http/tests/run.shcompiles the real sources and exercises the parsers directly โ header framing, range validation, truncation, and every catalog fixture in three line-ending forms. modules/network/common/httpstream.incis shared by the menu RPC module and the in-game cdvdman driver. Both IRX rules depend on it in the top-level Makefile, because make cannot see inside a sub-make and a stale IRX otherwise builds clean locally and fails CI.- The two lwIP stacks are not interchangeable.
MSG_DONTWAITis0x08on the menu path and0x40in SMSTCPIP, and SMSTCPIP exports noselect, so the in-game reader polls against a deadline instead. docs/HTTP-INTEGRATION-PLAN.mdcarries the phase ledger, the evidence table and the console test matrix. Read it before picking this up.
Credits
- Docmine17 โ the HTTP design, the byte-range reader this port follows, and the PC server.