5.5 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Overview
GCDWebServer is a lightweight, GCD-based HTTP 1.1 server written in Objective-C (ARC) for embedding in iOS, macOS, and tvOS apps. It has no third-party dependencies. This fork targets iOS 16 / tvOS 16 / macOS 12 (set in both GCDWebServer.xcodeproj and GCDWebServer.podspec).
Not supported by design: keep-alive connections and HTTPS.
Build & Test
There is no Swift Package Manager Package.swift; the build is driven entirely by GCDWebServer.xcodeproj (and CocoaPods for consumers).
Schemes (xcodebuild -list -project GCDWebServer.xcodeproj):
GCDWebServer (Mac|iOS|tvOS)— the static library / framework per platform.GCDWebServers (Mac|iOS|tvOS)— the framework target plus the XCTest unit tests (Frameworks/Tests.m).Build All.
Run the unit tests (XCTest):
xcodebuild test -scheme "GCDWebServers (Mac)"
Run a single XCTest method:
xcodebuild test -scheme "GCDWebServers (Mac)" -only-testing:Tests/Tests/testPaths
Full CI test suite (builds for all platforms at oldest + current deployment targets, then runs the request/response replay tests):
./Run-Tests.sh
Run-Tests.sh does the bulk of the real testing. It builds the GCDWebServer (Mac) target, then runs the resulting command-line GCDWebServer executable in test modes (webServer, webDAV, htmlForm, htmlFileUpload, webUploader) against recorded fixtures.
How the fixture-replay tests work
The Tests/ directory holds recorded HTTP exchanges, not code. Each test case is a pair of files: NNN-<method>.request (raw bytes sent to the server) and NNN-<code>.response (expected raw response bytes). The test runner (-mode <mode> -root <payload-dir> -tests <test-dir>) replays each .request against a server rooted at an extracted copy of Tests/Payload.zip and byte-compares the reply to the .response. To add coverage for a new behavior, add a matching .request/.response pair to the relevant Tests/<Mode> directory rather than writing new XCTest code.
Formatting
Source style for Objective-C is defined by .clang-format (Google base style, ColumnLimit: 0). Format files with clang-format -style=file -i <files>. The Swift example apps use 2-space indentation (SwiftFormat).
Architecture
The entire library is built around 4 core classes in GCDWebServer/Core/:
- GCDWebServer — owns the listening socket and the ordered list of handlers. Manages start/stop, options, Bonjour, NAT port mapping, and (on iOS) automatic suspend/resume across foreground/background transitions.
- GCDWebServerConnection — one instance per open HTTP connection, lives until the connection closes. Drives reading the request and writing the response. Subclassable via hooks (it's exposed but not used directly).
- GCDWebServerRequest — created once HTTP headers arrive; wraps the request and consumes the body. Subclasses in
GCDWebServer/Requests/choose how the body is handled (in memory, streamed to disk, parsed as a form, etc.). - GCDWebServerResponse — produced by a handler; wraps response headers and an optional body. Subclasses in
GCDWebServer/Responses/cover data-in-memory, file-on-disk, streamed, and error responses.
GCDWebServer/Core/GCDWebServerFunctions.{h,m} holds shared C helpers (e.g. GCDWebServerNormalizePath, MIME-type and date helpers). GCDWebServerPrivate.h is the internal/private header (including the logging-facility abstraction). GCDWebServerHTTPStatusCodes.h enumerates status codes.
Handler model
A request is matched and processed by handlers added to the server, evaluated in LIFO order (last added wins). Each handler is two GCD blocks:
GCDWebServerMatchBlock— runs as soon as headers are received; inspects method/URL/headers and returns aGCDWebServerRequestsubclass instance to claim the request, ornilto pass.GCDWebServerProcessBlock(sync) orGCDWebServerAsyncProcessBlock(async) — runs after the full request body is received and returns aGCDWebServerResponse(ornil/error response → 500).
Handlers run on arbitrary GCD threads, so handler code must be thread-safe and re-entrant.
Extensions (subclasses of GCDWebServer)
GCDWebUploader/—GCDWebUploader, an HTML5 web UI for uploading/downloading/managing files in a directory. Ships front-end assets inGCDWebUploader.bundle.GCDWebDAVServer/—GCDWebDAVServer, a class-1 WebDAV server (partial class-2 for macOS Finder). Depends onlibxml2.
Example apps & framework packaging
Mac/main.m— macOS command-line example (also serves as the test-runner executable).iOS/,tvOS/— Swift example apps (AppDelegate.swift,ViewController.swift).Frameworks/— umbrella header (GCDWebServers.h), module map, and the XCTest target source (Tests.m).
Consumer linking requirements
When integrated manually (not via CocoaPods), consuming apps must link libz, and WebDAV additionally needs libxml2 with $(SDKROOT)/usr/include/libxml2 on the header search path. The GCDWebServer.podspec defines three subspecs: Core (default), WebDAV, and WebUploader.
Logging & debug builds
Define DEBUG=1 in GCC_PREPROCESSOR_DEFINITIONS to enable verbose logging plus internal consistency checks. Runtime verbosity is controlled via +[GCDWebServer setLogLevel:]. If XLFacility is present in the same Xcode project, GCDWebServer routes logging through it automatically (see GCDWebServerPrivate.h).