blob: d3dff5df459b49d4f08b03ba0533a6de337cdcb6 [file] [view]
# AGENTS.md
This file provides guidance to coding agents working with this repository.
## Project Overview
Apache Traffic Server (ATS) is a high-performance HTTP/HTTPS caching proxy
server written in C++20. It uses an event-driven, multi-threaded architecture
with a sophisticated plugin system.
**Key Technologies:**
- Language: C++20
- Build System: CMake (migrated from autotools in v10)
- Testing: Catch2 (unit tests) + AuTest Python framework (end-to-end tests)
- Protocols: TLS, HTTP/1.1, HTTP/2, HTTP/3 (via Quiche)
## Project Structure
Core sources live in `src/` (for example `src/proxy`, `src/iocore`,
`src/traffic_server`). Public headers are in `include/`. Built-in plugins are
in `plugins/` and `plugins/experimental/`. End-to-end tests are in `tests/`,
especially `tests/gold_tests/`. Build system files are in `cmake/` plus the
top-level `CMakeLists.txt`, and docs are in `doc/`. Third party libraries that
we include locally are in `lib/`.
## Codex Agent Quick Start
Use this sequence for most tasks:
```bash
# Configure and build a dev tree.
cmake --preset dev
cmake --build build-dev
# Run a focused unit test or test suite.
ctest --test-dir build-dev -j4
# Format before commit.
cmake --build build-dev -t format
```
For environments using the default preset naming:
```bash
cmake --preset default
cmake --build build-default
ctest --test-dir build-default
cmake --build build-default -t format
```
If this file drifts from current project conventions, run `/init` to
re-bootstrap agent guidance, then keep repository-specific commands and rules
below.
## Personal Preferences
If `.codex/AGENTS.local.md` exists, load it for user-specific style preferences
and working conventions. This file is optional and should stay untracked.
### Key CMake Options
- `BUILD_EXPERIMENTAL_PLUGINS=ON` - Enable experimental plugins
- `ENABLE_QUICHE=ON` - QUIC/HTTP3 support
- `ENABLE_CRIPTS=ON` - Cripts scripting API
- `BUILD_REGRESSION_TESTING=ON` - Enable legacy test suite
- `ENABLE_ASAN=ON` - Configure ASan instrumentation
- `BUILD_TESTING=ON` - Enable building of the Catch2 tests
## Testing
### Unit Tests (Catch2)
Built automatically with the project. Run via ctest:
```bash
ctest --test-dir build -j4
```
### Running a Single Unit Test
Unit tests are built into executables. Find the test binary and run it directly:
```bash
# Unit tests are typically in build/src/<component>/
./build/src/tscore/test_tscore
```
### End-to-End Tests (AuTest)
**Enable autests during configuration:**
```bash
cmake -B build -DENABLE_AUTEST=ON
cmake --build build
cmake --install build
```
**Run all autests:**
```bash
cmake --build build -t autest
```
**Run specific test(s):**
```bash
cd build/tests
./autest.sh --sandbox /tmp/sbcodex --clean=none -f <test_name_without_test_py>
```
For example, to run `cache-auth.test.py`:
```bash
./autest.sh --sandbox /tmp/sbcursor --clean=none -f cache-auth
```
To run multiple tests efficiently, pass the -j option.
```bash
cd build/tests
./autest.sh -j4 --sandbox /tmp/sbcodex --clean=none -f 'header_rewrite*'
```
Most end-to-end test coverage is in `tests/gold_tests/`. The CI system uses the
Docker image `ci.trafficserver.apache.org/ats/fedora:43` (Fedora version updated
regularly).
### Writing Autests
**New tests should use the `Test.ATSReplayTest()` approach**, which references a
`replay.yaml` file that describes the test configuration and traffic patterns
using the Proxy Verifier format. This is simpler, more maintainable, and
parseable by tools.
If `ATSReplayTest` is not a good fit (say, the test needs a custom client), then
organize the test around a test class with member functions that configure any
servers, the ATS process, and the client. See
`tests/gold_tests/ats_probe/ats_probe.test.py` for an example of a test organized
around a test class.
In autests, launch Python helpers with `{sys.executable}` rather than a
hardcoded `python3`, so the test runs under the same interpreter the harness
uses.
**For complete details on writing autests, see:**
- `doc/developer-guide/testing/autests.en.rst` - Comprehensive guide to autest
- Proxy Verifier format: https://github.com/yahoo/proxy-verifier
- AuTest framework: https://autestsuite.bitbucket.io/
## Development Workflow
### Code Formatting
Always format code before committing:
```bash
cmake --build build -t format
```
### Before Commit Checklist
- Keep scope tight and avoid unrelated file churn.
- Run formatter: `cmake --build build -t format` (or `build-dev` when used).
- Run targeted tests for changed areas (or explain why tests were skipped).
- Keep commit message body wrapped to 72 characters per line.
- Describe why the change was needed, not only what changed.
### Editing Safety
- Do not revert unrelated working tree changes.
- Prefer minimal diffs over broad refactors unless requested.
- Do not edit generated artifacts unless the task explicitly requires it.
- When touching behavior, add or update tests when practical.
### Git Workflow
- Branch off `master` for almost all PRs
- PRs must pass all Jenkins CI jobs before merging
- Use the GitHub PR workflow (not Jira)
- Set appropriate labels: **Backport**, **WIP**, etc.
### Commit Message Format
When an agent creates commits, use a short imperative summary line (under 50
characters when practical) plus concise body text (1-3 sentences) focused on
"why" rather than only "what". If the PR fixes an issue, add 'Fixes:
#<issue_number>'. Keep commit message body lines to 72 characters.
## Architecture Overview
### Core Components
**I/O Core (`src/iocore/`):**
- `eventsystem/` - Event-driven engine (Continuations, Events, Processors)
- `cache/` - Disk and RAM cache implementation
- `net/` - Network layer with TLS and QUIC support
- `dns/` - Asynchronous DNS resolution
- `hostdb/` - Internal DNS cache
- `aio/` - Asynchronous I/O
**Proxy Logic (`src/proxy/`):**
- `http/` - HTTP/1.1 protocol implementation
- `http2/` - HTTP/2 support
- `http3/` - HTTP/3 implementation
- `hdrs/` - Header parsing and management
- `logging/` - Flexible logging system
- `http/remap/` - URL remapping and routing
**Management (`src/mgmt/`):**
- JSONRPC server for runtime configuration and management
- Configuration file parsing and validation
**Base Libraries (`src/`):**
- `tscore/` - Core utilities and data structures
- `tsutil/` - Core utilities (metrics, debugging, regex, etc.)
- `api/` - Plugin API implementation
- `tscpp/api/` - C++ API wrapper for plugins
- `cripts/` - Cripts scripting framework for plugins
### Event-Driven Architecture
ATS uses a **Continuation-based** programming model:
- All async operations use Continuations (callback objects)
- Events are dispatched through an event system
- Multiple thread pools handle different event types
- Non-blocking I/O throughout
### Configuration Files
Primary configs (installed to `/etc/trafficserver/` by default):
- `records.yaml` - Main configuration (formerly records.config)
- `remap.config` - URL remapping rules
- `plugin.config` - Plugin loading configuration
- `ip_allow.yaml` - IP access control
- `ssl_multicert.config` - TLS certificate configuration
- `sni.yaml` - SNI-based routing
- `storage.config` - Cache storage configuration
Configuration can be modified at runtime via:
- `traffic_ctl config reload` (for some settings)
- JSONRPC API
## Plugin Development
### Plugin Types
- **Global plugins** - Loaded in `plugin.config`, affect all requests
- **Remap plugins** - Loaded per remap rule, affect specific mapped requests
### Key Plugin APIs
Headers in `include/ts/`:
- `ts.h` - Main plugin API
- `remap.h` - Remap plugin API
- `InkAPIPrivateIOCore.h` - Advanced internal APIs
### Plugin Hooks
Plugins register callbacks at various points in request processing:
- `TS_HTTP_READ_REQUEST_HDR_HOOK`
- `TS_HTTP_SEND_REQUEST_HDR_HOOK`
- `TS_HTTP_READ_RESPONSE_HDR_HOOK`
- `TS_HTTP_SEND_RESPONSE_HDR_HOOK`
- Many more (see `ts.h`)
### Example Plugins
- `example/plugins/` - Simple example plugins
- `plugins/` - Stable core plugins
- `plugins/experimental/` - Experimental plugins
## Common Development Patterns
### When Modifying HTTP Processing
1. Understand the state machine: `src/proxy/http/HttpSM.cc` - HTTP State Machine
2. Hook into the appropriate stage via plugin hooks or core modification
3. Use `HttpTxn` objects to access transaction state
4. Headers are accessed via `HDRHandle` and field APIs
### When Adding Configuration
1. Define record in `src/records/RecordsConfig.cc`
2. Add validation if needed
3. Update documentation in `doc/admin-guide/`
4. Configuration can be read via `REC_` APIs
### When Working with Cache
- Cache is content-addressable, keyed by URL (modifiable via plugins)
- Cache operations are async, continuation-based
- Cache has RAM and disk tiers
- Cache code is in `src/iocore/cache/`
### When Debugging
1. Enable debug tags in `records.yaml`:
```yaml
proxy.config.diags.debug.enabled: 1
proxy.config.diags.debug.tags: http|cache
```
2. Check logs in `/var/log/trafficserver/`:
- `diags.log` - Debug output
- `error.log` - Errors and warnings
3. Use `traffic_top` for live statistics
4. Use `traffic_ctl` for runtime inspection
**Debug Controls in Code:**
```cpp
static DbgCtl dbg_ctl{"my_component"};
SMDebug(dbg_ctl, "Processing request for URL: %s", url);
```
## Important Conventions
### License Headers
- Always add Apache License 2.0 headers to the top of new source and test files
- This includes `.cc`, `.h`, `.py`, and other code files
- Follow the existing license header format used in the codebase
### Code Style
- `.editorconfig` and `.clang-format` is the source of truth for baseline formatting rules.
- C++20 standard (nothing from C++23 or later)
- Use RAII principles
- Prefer smart pointers for ownership
- Don't use templates unless needed and appropriate
- Run `cmake --build build -t format` before committing
- Source code line length: 132 characters maximum
- Don't add comments where the code documents itself, don't comment AI interactions
**C++ Formatting (Mozilla-based style):**
- Indentation: 2 spaces for C/C++
- Braces: Linux style (opening brace on same line)
- Pointer alignment: Right (`Type *ptr`, not `Type* ptr`)
- Variable declarations: Add empty line after declarations before subsequent code
- Avoid naked conditions (always use braces with if statements)
**Naming Conventions:**
- CamelCase for classes: `HttpSM`, `NetVConnection`
- snake_case for variables and functions: `server_entry`, `handle_api_return()`
- UPPER_CASE for macros and constants: `HTTP_SM_SET_DEFAULT_HANDLER`
- Private member variables use both `_` and `m_` prefixes in the source code;
be consistent with the surrounding code. For new files, prefer the `_` prefix
because that reflects the community consensus.
- Boolean variables and functions returning boolean values are named as
predicates: use `was_modified` rather than `modified`.
**Doxygen Comments:**
When adding doxygen comments:
- `@brief` is assumed for the first sentence, so give a brief summary right
after `/** ` without using `@brief`.
- In the description of classes, functions, and member variables, convey the
responsibility of the item being described (its role and intent), not just
what the code obviously does.
- Use `@a <name>` to reference a function argument by name in prose
(e.g. "If @a size is zero..."). Use `@c <text>` for inline code or
constants (e.g. `@c true`, `@c NULL`, `@c MyEnum::VALUE`).
- Use `@ref`, `@see`, or `@sa` to cross-reference related types or functions
when that helps convey how items interact.
- Use `@param` with `[in]`, `[out]`, or `[in,out]` to indicate the
parameter's direction, followed by a description of its meaning.
- Use `@return` to describe the semantics of the returned value. Don't
restate the type; that is obvious from the signature and rendered docs.
- Use `@note` for non-obvious caveats and `@warning` for hazards (e.g. lock
ordering, lifetime, or threading constraints).
- Use `@code` ... `@endcode` for embedded usage examples.
- For templates, document type parameters with `@tparam`.
Conventions specific to this codebase:
- Every new header file should start with a `/** @file` block (see existing
headers in `include/` for the standard license/section layout).
- Prefer trailing briefs for data members and enumerators, e.g.
`int max_conns{0}; ///< Maximum concurrent connections.`
- Use single-line `///` briefs for short function or type docs where a full
`/** ... */` block would be overkill.
**Modern C++ Patterns (Preferred):**
```cpp
// GOOD - Modern C++20
auto buffer = std::make_unique<MIOBuffer>(alloc_index);
for (const auto &entry : container) {
if (auto *vc = entry.get_vc(); vc != nullptr) {
// Process vc
}
}
// AVOID - Legacy C-style
MIOBuffer *buffer = (MIOBuffer*)malloc(sizeof(MIOBuffer));
```
### Python Code Style (for tests and tools)
- Python 3.11+ with proper type annotations
- 4-space indentation, never TABs
- Type annotations on all function signatures
- Prefer f-strings over `str.format()` when building command lines, config lines,
and `Testers` expressions.
### Memory Management
- Custom allocators supported (jemalloc, mimalloc)
- Use `ats_malloc` family for large allocations
- IOBuffers for network data (zero-copy where possible)
### Threading
- Event threads handle most work
- DNS has dedicated threads
- Disk I/O uses thread pool
- Most code should be async/event-driven, not thread-based
### Error Handling
- Return error codes for recoverable errors
- Use `ink_release_assert` for unrecoverable errors
- Log errors appropriately (ERROR vs WARNING vs NOTE)
## Key Files for Understanding Architecture
- `include/iocore/eventsystem/Continuation.h` - Core async pattern
- `src/proxy/http/HttpSM.cc` - HTTP request state machine
- `src/iocore/net/UnixNetVConnection.cc` - Network connection handling
- `src/iocore/cache/Cache.cc` - Cache implementation
- `src/proxy/http/remap/RemapConfig.cc` - URL remapping logic
- `include/ts/ts.h` - Plugin API
## Security
See [SECURITY.md](SECURITY.md) for the project's security policy, threat model,
scope, and vulnerability reporting process.
## Resources
- Official docs: https://trafficserver.apache.org/
- Developer wiki: https://github.com/apache/trafficserver/wiki
- CI dashboard: https://ci.trafficserver.apache.org/
- AuTest framework: https://autestsuite.bitbucket.io/
- Proxy Verifier: https://github.com/yahoo/proxy-verifier