# How Apollo’s HTTP Client Manages Cache and Fetches Data from the Online Database

> Discover how Apollo's HTTP client uses libcurl to manage its local cache and efficiently fetch data from online databases for offline access and quick updates.

- Repository: [Damián Parrino/apollo-ps4](https://github.com/bucanero/apollo-ps4)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Apollo’s HTTP client uses libcurl to download remote resources into a local cache directory at `/data/apollo/cache/`, then reads files locally to support offline access and database queries.**

The Apollo PS4 save-tool, maintained by bucanero, relies on a lightweight HTTP client to communicate with online databases and download updates. This article examines how the Apollo HTTP client cache system stores fetched data and manages local resources using libcurl, based on the implementation in the `bucanero/apollo-ps4` repository.

## Initializing the HTTP Client with libcurl

Apollo’s network stack begins with **`http_init()`** in `source/http.c:18-33`. This function loads the PS4 networking sysmodules, initializes the NetCtl service, and invokes `curl_global_init()` to prepare libcurl for transfers.

If any initialization step fails, the function returns **`HTTP_FAILED`**, preventing the application from attempting network operations when the system is not ready.

## Downloading Resources into the Apollo HTTP Client Cache

The core fetch operation is **`http_download()`** in [`source/http.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/http.c). This function constructs the full request URL, opens the destination file, and configures libcurl options through **`set_curl_opts()`** before executing the transfer with `curl_easy_perform()`.

When the download succeeds, the file persists in the destination path. On failure, the function calls **`unlink_secure()`** to remove partially written files, ensuring the cache does not contain corrupted data.

### Cache Directory Structure and Configuration

The cache location is defined in [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h):

```c
#define APOLLO_PATH               "/data/apollo/"
#define APOLLO_LOCAL_CACHE        APOLLO_PATH "cache/"

```

This expands to **`/data/apollo/cache/`** on the PS4 filesystem. Common cached files include:

- `games.ftp` – Downloaded game database lists
- `ver.check` – Version information for update checks
- `appdata.zip` – Patch archives for application updates
- `users.ftp` – User index files from FTP servers

## Managing the Apollo HTTP Client Cache Lifecycle

Apollo creates the cache directory at startup in [`source/main.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/main.c) using `mkdirs(APOLLO_LOCAL_CACHE)`. The application provides several mechanisms to maintain cache integrity.

The **`clean_directory()`** function in `source/common.c:222-240` recursively deletes files matching a specific suffix filter. This utility supports:

- **Selective cleaning**: Removing only `.txt` files when the database URL changes
- **Complete purging**: Removing all cached content via the manual "Clear cache" menu entry

When users modify the FTP or online database URL in [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c), the system calls `clean_directory(APOLLO_LOCAL_CACHE, ".txt")` to invalidate stale database lists while preserving other cached resources.

## Fetching Data from the Online Database

Apollo retrieves database information through a two-step cache-then-read pattern.

First, the user configures the database URL through **`db_url_callback()`** in [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c), which stores the endpoint in `apollo_config.save_db`.

To fetch the game list, the system calls:

```c
http_download(apollo_config.save_db, "games.txt", 
              APOLLO_LOCAL_CACHE "games.ftp", 0);

```

This downloads [`games.txt`](https://github.com/bucanero/apollo-ps4/blob/main/games.txt) from the remote server and saves it as `games.ftp` in the local cache. Subsequent operations read the file locally using `readTextFile(APOLLO_LOCAL_CACHE "games.ftp")`, enabling offline access to the database.

### Checking for Updates

The update mechanism follows the same cached approach. The **`update_callback()`** function in [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c) downloads version information from `APOLLO_UPDATE_URL` to `APOLLO_LOCAL_CACHE "ver.check"`.

After reading the cached version file, Apollo compares it against `APOLLO_VERSION`. If a newer version exists, the system can trigger a patch download:

```c
http_download(ONLINE_PATCH_URL, "apollo-ps4-update.zip", 
              APOLLO_LOCAL_CACHE "appdata.zip", 1);

```

## Practical Code Examples

### Initializing the Client and Downloading a Database

```c
#include "http.h"
#include "common.h"

int main(void)
{
    if (http_init() == HTTP_FAILED) {
        LOG("Network init failed");
        return -1;
    }

    /* Download the online game list */
    const char *url = "https://example.com/apollo/";
    const char *dst = APOLLO_LOCAL_CACHE "games.ftp";
    
    if (http_download(url, "games.txt", dst, 1) == HTTP_SUCCESS) {
        LOG("Games list cached to %s", dst);
    }

    http_end();
    return 0;
}

```

### Clearing the Local Cache Programmatically

```c
/* Callback for Settings → Clear Cache menu entry */
static void clearcache_callback(int sel)
{
    LOG("Cleaning folder '%s'...", APOLLO_LOCAL_CACHE);
    clean_directory(APOLLO_LOCAL_CACHE, "");  // Empty suffix = delete all
    
    show_message("%s\n%s", 
                 _("Local cache folder cleaned:"), 
                 APOLLO_LOCAL_CACHE);
}

```

### Checking for Application Updates

```c
/* Excerpt from settings.c update_callback() */
if (!http_download(APOLLO_UPDATE_URL, NULL,
                   APOLLO_LOCAL_CACHE "ver.check", 0)) {
    LOG("Failed to fetch version file");
    return;
}

char *buffer = readTextFile(APOLLO_LOCAL_CACHE "ver.check");
if (buffer && strcasecmp(APOLLO_VERSION, buffer) != 0) {
    LOG("New version available: %s", buffer);
    /* Trigger download of apollo-ps4-update.zip */
}

```

## Summary

- Apollo’s HTTP client is a **libcurl wrapper** implemented in [`source/http.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/http.c) that handles network initialization, file transfers, and cleanup.
- All remote resources are cached to **`/data/apollo/cache/`** (defined as `APOLLO_LOCAL_CACHE` in [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h)) to enable offline access and reduce network load.
- The **`http_download()`** function writes files atomically, removing partial downloads on failure via `unlink_secure()`.
- Cache maintenance is handled by **`clean_directory()`** in `source/common.c:222-240`, supporting both selective purging by file extension and complete clearing.
- Online database queries follow a **cache-then-read pattern**: the client downloads [`games.txt`](https://github.com/bucanero/apollo-ps4/blob/main/games.txt) to `games.ftp`, then parses the local file for game listings.

## Frequently Asked Questions

### Where does Apollo store cached HTTP downloads?

Apollo stores all cached files in **`/data/apollo/cache/`**, defined by the `APOLLO_LOCAL_CACHE` macro in [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h). This directory is created at application startup in [`source/main.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/main.c) using `mkdirs()`.

### What library does Apollo use for HTTP requests?

Apollo uses **libcurl** for all HTTP and FTP operations. The wrapper functions `http_init()`, `http_download()`, and `http_end()` in [`source/http.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/http.c) manage libcurl’s global state, perform transfers, and handle PS4-specific networking sysmodules.

### How does Apollo check for software updates?

The `update_callback()` function in [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c) downloads a version file from `APOLLO_UPDATE_URL` to `APOLLO_LOCAL_CACHE "ver.check"`. It compares the cached version string against the compiled `APOLLO_VERSION` using `strcasecmp()`. If they differ, Apollo can download `apollo-ps4-update.zip` to the cache and apply the patch.

### Can users manually clear the HTTP cache?

Yes. The settings menu provides a "Clear cache" option that triggers `clearcache_callback()` in [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c). This calls `clean_directory(APOLLO_LOCAL_CACHE, "")` from `source/common.c:222-240`, which recursively deletes all files in the cache directory. Users can also trigger selective clearing when changing database URLs, which removes only `.txt` files while preserving other cached data.