|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This file provides guidance to coding agents working with this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Apache Traffic Server (ATS) is a high-performance HTTP/HTTPS caching proxy |
| 8 | +server written in C++20. It uses an event-driven, multi-threaded architecture |
| 9 | +with a sophisticated plugin system. |
| 10 | + |
| 11 | +**Key Technologies:** |
| 12 | +- Language: C++20 |
| 13 | +- Build System: CMake (migrated from autotools in v10) |
| 14 | +- Testing: Catch2 (unit tests) + AuTest Python framework (end-to-end tests) |
| 15 | +- Protocols: TLS, HTTP/1.1, HTTP/2, HTTP/3 (via Quiche) |
| 16 | + |
| 17 | +## Project Structure |
| 18 | + |
| 19 | +Core sources live in `src/` (for example `src/proxy`, `src/iocore`, |
| 20 | +`src/traffic_server`). Public headers are in `include/`. Built-in plugins are |
| 21 | +in `plugins/` and `plugins/experimental/`. End-to-end tests are in `tests/`, |
| 22 | +especially `tests/gold_tests/`. Build system files are in `cmake/` plus the |
| 23 | +top-level `CMakeLists.txt`, and docs are in `doc/`. Third party libraries that |
| 24 | +we include locally are in `lib/`. |
| 25 | + |
| 26 | +## Codex Agent Quick Start |
| 27 | + |
| 28 | +Use this sequence for most tasks: |
| 29 | + |
| 30 | +```bash |
| 31 | +# Configure and build a dev tree. |
| 32 | +cmake --preset dev |
| 33 | +cmake --build build-dev |
| 34 | + |
| 35 | +# Run a focused unit test or test suite. |
| 36 | +ctest --test-dir build-dev -j4 |
| 37 | + |
| 38 | +# Format before commit. |
| 39 | +cmake --build build-dev -t format |
| 40 | +``` |
| 41 | + |
| 42 | +For environments using the default preset naming: |
| 43 | + |
| 44 | +```bash |
| 45 | +cmake --preset default |
| 46 | +cmake --build build-default |
| 47 | +ctest --test-dir build-default |
| 48 | +cmake --build build-default -t format |
| 49 | +``` |
| 50 | + |
| 51 | +If this file drifts from current project conventions, run `/init` to |
| 52 | +re-bootstrap agent guidance, then keep repository-specific commands and rules |
| 53 | +below. |
| 54 | + |
| 55 | +## Personal Preferences |
| 56 | + |
| 57 | +If `.codex/AGENTS.local.md` exists, load it for user-specific style preferences |
| 58 | +and working conventions. This file is optional and should stay untracked. |
| 59 | + |
| 60 | +### Key CMake Options |
| 61 | +- `BUILD_EXPERIMENTAL_PLUGINS=ON` - Enable experimental plugins |
| 62 | +- `ENABLE_QUICHE=ON` - QUIC/HTTP3 support |
| 63 | +- `ENABLE_CRIPTS=ON` - Cripts scripting API |
| 64 | +- `BUILD_REGRESSION_TESTING=ON` - Enable legacy test suite |
| 65 | +- `ENABLE_ASAN=ON` - Configure ASan instrumentation |
| 66 | +- `BUILD_TESTING=ON` - Enable building of the Catch2 tests |
| 67 | + |
| 68 | +## Testing |
| 69 | + |
| 70 | +### Unit Tests (Catch2) |
| 71 | +Built automatically with the project. Run via ctest: |
| 72 | +```bash |
| 73 | +ctest --test-dir build -j4 |
| 74 | +``` |
| 75 | + |
| 76 | +### Running a Single Unit Test |
| 77 | +Unit tests are built into executables. Find the test binary and run it directly: |
| 78 | +```bash |
| 79 | +# Unit tests are typically in build/src/<component>/ |
| 80 | +./build/src/tscore/test_tscore |
| 81 | +``` |
| 82 | + |
| 83 | +### End-to-End Tests (AuTest) |
| 84 | + |
| 85 | +**Enable autests during configuration:** |
| 86 | +```bash |
| 87 | +cmake -B build -DENABLE_AUTEST=ON |
| 88 | +cmake --build build |
| 89 | +cmake --install build |
| 90 | +``` |
| 91 | + |
| 92 | +**Run all autests:** |
| 93 | +```bash |
| 94 | +cmake --build build -t autest |
| 95 | +``` |
| 96 | + |
| 97 | +**Run specific test(s):** |
| 98 | +```bash |
| 99 | +cd build/tests |
| 100 | +./autest.sh --sandbox /tmp/sbcodex --clean=none -f <test_name_without_test_py> |
| 101 | +``` |
| 102 | + |
| 103 | +For example, to run `cache-auth.test.py`: |
| 104 | +```bash |
| 105 | +./autest.sh --sandbox /tmp/sbcursor --clean=none -f cache-auth |
| 106 | +``` |
| 107 | + |
| 108 | +To run multiple tests efficiently, pass the -j option. |
| 109 | + |
| 110 | +```bash |
| 111 | +cd build/tests |
| 112 | +./autest.sh -j4 --sandbox /tmp/sbcodex --clean=none -f 'header_rewrite*' |
| 113 | +``` |
| 114 | + |
| 115 | +Most end-to-end test coverage is in `tests/gold_tests/`. The CI system uses the |
| 116 | +Docker image `ci.trafficserver.apache.org/ats/fedora:43` (Fedora version updated |
| 117 | +regularly). |
| 118 | + |
| 119 | +### Writing Autests |
| 120 | + |
| 121 | +**New tests should use the `Test.ATSReplayTest()` approach**, which references a |
| 122 | +`replay.yaml` file that describes the test configuration and traffic patterns |
| 123 | +using the Proxy Verifier format. This is simpler, more maintainable, and |
| 124 | +parseable by tools. |
| 125 | + |
| 126 | +**For complete details on writing autests, see:** |
| 127 | +- `doc/developer-guide/testing/autests.en.rst` - Comprehensive guide to autest |
| 128 | +- Proxy Verifier format: https://github.com/yahoo/proxy-verifier |
| 129 | +- AuTest framework: https://autestsuite.bitbucket.io/ |
| 130 | + |
| 131 | +## Development Workflow |
| 132 | + |
| 133 | +### Code Formatting |
| 134 | +Always format code before committing: |
| 135 | +```bash |
| 136 | +cmake --build build -t format |
| 137 | +``` |
| 138 | + |
| 139 | +### Before Commit Checklist |
| 140 | +- Keep scope tight and avoid unrelated file churn. |
| 141 | +- Run formatter: `cmake --build build -t format` (or `build-dev` when used). |
| 142 | +- Run targeted tests for changed areas (or explain why tests were skipped). |
| 143 | +- Keep commit message body wrapped to 72 characters per line. |
| 144 | +- Describe why the change was needed, not only what changed. |
| 145 | + |
| 146 | +### Editing Safety |
| 147 | +- Do not revert unrelated working tree changes. |
| 148 | +- Prefer minimal diffs over broad refactors unless requested. |
| 149 | +- Do not edit generated artifacts unless the task explicitly requires it. |
| 150 | +- When touching behavior, add or update tests when practical. |
| 151 | + |
| 152 | +### Git Workflow |
| 153 | +- Branch off `master` for almost all PRs |
| 154 | +- PRs must pass all Jenkins CI jobs before merging |
| 155 | +- Use the GitHub PR workflow (not Jira) |
| 156 | +- Set appropriate labels: **Backport**, **WIP**, etc. |
| 157 | + |
| 158 | +### Commit Message Format |
| 159 | +When an agent creates commits, use a short imperative summary line (under 50 |
| 160 | +characters when practical) plus concise body text (1-3 sentences) focused on |
| 161 | +"why" rather than only "what". If the PR fixes an issue, add 'Fixes: |
| 162 | +#<issue_number>'. Keep commit message body lines to 72 characters. |
| 163 | + |
| 164 | +## Architecture Overview |
| 165 | + |
| 166 | +### Core Components |
| 167 | + |
| 168 | +**I/O Core (`src/iocore/`):** |
| 169 | +- `eventsystem/` - Event-driven engine (Continuations, Events, Processors) |
| 170 | +- `cache/` - Disk and RAM cache implementation |
| 171 | +- `net/` - Network layer with TLS and QUIC support |
| 172 | +- `dns/` - Asynchronous DNS resolution |
| 173 | +- `hostdb/` - Internal DNS cache |
| 174 | +- `aio/` - Asynchronous I/O |
| 175 | + |
| 176 | +**Proxy Logic (`src/proxy/`):** |
| 177 | +- `http/` - HTTP/1.1 protocol implementation |
| 178 | +- `http2/` - HTTP/2 support |
| 179 | +- `http3/` - HTTP/3 implementation |
| 180 | +- `hdrs/` - Header parsing and management |
| 181 | +- `logging/` - Flexible logging system |
| 182 | +- `http/remap/` - URL remapping and routing |
| 183 | + |
| 184 | +**Management (`src/mgmt/`):** |
| 185 | +- JSONRPC server for runtime configuration and management |
| 186 | +- Configuration file parsing and validation |
| 187 | + |
| 188 | +**Base Libraries (`src/`):** |
| 189 | +- `tscore/` - Core utilities and data structures |
| 190 | +- `tsutil/` - Core utilities (metrics, debugging, regex, etc.) |
| 191 | +- `api/` - Plugin API implementation |
| 192 | +- `tscpp/api/` - C++ API wrapper for plugins |
| 193 | +- `cripts/` - Cripts scripting framework for plugins |
| 194 | + |
| 195 | +### Event-Driven Architecture |
| 196 | + |
| 197 | +ATS uses a **Continuation-based** programming model: |
| 198 | +- All async operations use Continuations (callback objects) |
| 199 | +- Events are dispatched through an event system |
| 200 | +- Multiple thread pools handle different event types |
| 201 | +- Non-blocking I/O throughout |
| 202 | + |
| 203 | +### Configuration Files |
| 204 | + |
| 205 | +Primary configs (installed to `/etc/trafficserver/` by default): |
| 206 | +- `records.yaml` - Main configuration (formerly records.config) |
| 207 | +- `remap.config` - URL remapping rules |
| 208 | +- `plugin.config` - Plugin loading configuration |
| 209 | +- `ip_allow.yaml` - IP access control |
| 210 | +- `ssl_multicert.config` - TLS certificate configuration |
| 211 | +- `sni.yaml` - SNI-based routing |
| 212 | +- `storage.config` - Cache storage configuration |
| 213 | + |
| 214 | +Configuration can be modified at runtime via: |
| 215 | +- `traffic_ctl config reload` (for some settings) |
| 216 | +- JSONRPC API |
| 217 | + |
| 218 | +## Plugin Development |
| 219 | + |
| 220 | +### Plugin Types |
| 221 | +- **Global plugins** - Loaded in `plugin.config`, affect all requests |
| 222 | +- **Remap plugins** - Loaded per remap rule, affect specific mapped requests |
| 223 | + |
| 224 | +### Key Plugin APIs |
| 225 | +Headers in `include/ts/`: |
| 226 | +- `ts.h` - Main plugin API |
| 227 | +- `remap.h` - Remap plugin API |
| 228 | +- `InkAPIPrivateIOCore.h` - Advanced internal APIs |
| 229 | + |
| 230 | +### Plugin Hooks |
| 231 | +Plugins register callbacks at various points in request processing: |
| 232 | +- `TS_HTTP_READ_REQUEST_HDR_HOOK` |
| 233 | +- `TS_HTTP_SEND_REQUEST_HDR_HOOK` |
| 234 | +- `TS_HTTP_READ_RESPONSE_HDR_HOOK` |
| 235 | +- `TS_HTTP_SEND_RESPONSE_HDR_HOOK` |
| 236 | +- Many more (see `ts.h`) |
| 237 | + |
| 238 | +### Example Plugins |
| 239 | +- `example/plugins/` - Simple example plugins |
| 240 | +- `plugins/` - Stable core plugins |
| 241 | +- `plugins/experimental/` - Experimental plugins |
| 242 | + |
| 243 | +## Common Development Patterns |
| 244 | + |
| 245 | +### When Modifying HTTP Processing |
| 246 | +1. Understand the state machine: `src/proxy/http/HttpSM.cc` - HTTP State Machine |
| 247 | +2. Hook into the appropriate stage via plugin hooks or core modification |
| 248 | +3. Use `HttpTxn` objects to access transaction state |
| 249 | +4. Headers are accessed via `HDRHandle` and field APIs |
| 250 | + |
| 251 | +### When Adding Configuration |
| 252 | +1. Define record in `src/records/RecordsConfig.cc` |
| 253 | +2. Add validation if needed |
| 254 | +3. Update documentation in `doc/admin-guide/` |
| 255 | +4. Configuration can be read via `REC_` APIs |
| 256 | + |
| 257 | +### When Working with Cache |
| 258 | +- Cache is content-addressable, keyed by URL (modifiable via plugins) |
| 259 | +- Cache operations are async, continuation-based |
| 260 | +- Cache has RAM and disk tiers |
| 261 | +- Cache code is in `src/iocore/cache/` |
| 262 | + |
| 263 | +### When Debugging |
| 264 | +1. Enable debug tags in `records.yaml`: |
| 265 | + ```yaml |
| 266 | + proxy.config.diags.debug.enabled: 1 |
| 267 | + proxy.config.diags.debug.tags: http|cache |
| 268 | + ``` |
| 269 | +2. Check logs in `/var/log/trafficserver/`: |
| 270 | + - `diags.log` - Debug output |
| 271 | + - `error.log` - Errors and warnings |
| 272 | +3. Use `traffic_top` for live statistics |
| 273 | +4. Use `traffic_ctl` for runtime inspection |
| 274 | + |
| 275 | +**Debug Controls in Code:** |
| 276 | +```cpp |
| 277 | +static DbgCtl dbg_ctl{"my_component"}; |
| 278 | +SMDebug(dbg_ctl, "Processing request for URL: %s", url); |
| 279 | +``` |
| 280 | + |
| 281 | +## Important Conventions |
| 282 | + |
| 283 | +### License Headers |
| 284 | +- Always add Apache License 2.0 headers to the top of new source and test files |
| 285 | +- This includes `.cc`, `.h`, `.py`, and other code files |
| 286 | +- Follow the existing license header format used in the codebase |
| 287 | + |
| 288 | +### Code Style |
| 289 | +- `.editorconfig` and `.clang-format` is the source of truth for baseline formatting rules. |
| 290 | +- C++20 standard (nothing from C++23 or later) |
| 291 | +- Use RAII principles |
| 292 | +- Prefer smart pointers for ownership |
| 293 | +- Don't use templates unless needed and appropriate |
| 294 | +- Run `cmake --build build -t format` before committing |
| 295 | +- Source code line length: 132 characters maximum |
| 296 | +- Don't add comments where the code documents itself, don't comment AI interactions |
| 297 | + |
| 298 | +**C++ Formatting (Mozilla-based style):** |
| 299 | +- Indentation: 2 spaces for C/C++ |
| 300 | +- Braces: Linux style (opening brace on same line) |
| 301 | +- Pointer alignment: Right (`Type *ptr`, not `Type* ptr`) |
| 302 | +- Variable declarations: Add empty line after declarations before subsequent code |
| 303 | +- Avoid naked conditions (always use braces with if statements) |
| 304 | + |
| 305 | +**Naming Conventions:** |
| 306 | +- CamelCase for classes: `HttpSM`, `NetVConnection` |
| 307 | +- snake_case for variables and functions: `server_entry`, `handle_api_return()` |
| 308 | +- UPPER_CASE for macros and constants: `HTTP_SM_SET_DEFAULT_HANDLER` |
| 309 | +- Private member variables have the `m_` prefix. |
| 310 | + |
| 311 | +**Modern C++ Patterns (Preferred):** |
| 312 | +```cpp |
| 313 | +// GOOD - Modern C++20 |
| 314 | +auto buffer = std::make_unique<MIOBuffer>(alloc_index); |
| 315 | +for (const auto &entry : container) { |
| 316 | + if (auto *vc = entry.get_vc(); vc != nullptr) { |
| 317 | + // Process vc |
| 318 | + } |
| 319 | +} |
| 320 | +
|
| 321 | +// AVOID - Legacy C-style |
| 322 | +MIOBuffer *buffer = (MIOBuffer*)malloc(sizeof(MIOBuffer)); |
| 323 | +``` |
| 324 | + |
| 325 | +### Python Code Style (for tests and tools) |
| 326 | +- Python 3.11+ with proper type annotations |
| 327 | +- 4-space indentation, never TABs |
| 328 | + |
| 329 | +### Memory Management |
| 330 | +- Custom allocators supported (jemalloc, mimalloc) |
| 331 | +- Use `ats_malloc` family for large allocations |
| 332 | +- IOBuffers for network data (zero-copy where possible) |
| 333 | + |
| 334 | +### Threading |
| 335 | +- Event threads handle most work |
| 336 | +- DNS has dedicated threads |
| 337 | +- Disk I/O uses thread pool |
| 338 | +- Most code should be async/event-driven, not thread-based |
| 339 | + |
| 340 | +### Error Handling |
| 341 | +- Return error codes for recoverable errors |
| 342 | +- Use `ink_release_assert` for unrecoverable errors |
| 343 | +- Log errors appropriately (ERROR vs WARNING vs NOTE) |
| 344 | + |
| 345 | +## Key Files for Understanding Architecture |
| 346 | + |
| 347 | +- `include/iocore/eventsystem/Continuation.h` - Core async pattern |
| 348 | +- `src/proxy/http/HttpSM.cc` - HTTP request state machine |
| 349 | +- `src/iocore/net/UnixNetVConnection.cc` - Network connection handling |
| 350 | +- `src/iocore/cache/Cache.cc` - Cache implementation |
| 351 | +- `src/proxy/http/remap/RemapConfig.cc` - URL remapping logic |
| 352 | +- `include/ts/ts.h` - Plugin API |
| 353 | + |
| 354 | +## Resources |
| 355 | + |
| 356 | +- Official docs: https://trafficserver.apache.org/ |
| 357 | +- Developer wiki: https://cwiki.apache.org/confluence/display/TS/ |
| 358 | +- CI dashboard: https://ci.trafficserver.apache.org/ |
| 359 | +- AuTest framework: https://autestsuite.bitbucket.io/ |
| 360 | +- Proxy Verifier: https://github.com/yahoo/proxy-verifier |
0 commit comments