UVHTTP Contributor Guide
Overview
This document is intended for contributors to the UVHTTP library. It describes how to participate in library development, coding standards, best practices, and more.
Development Environment
System Requirements
- Operating System: Linux, macOS, Windows
- Compiler: GCC 4.8+, Clang 3.4+, MSVC 2015+
- CMake: 3.10+
- Dependencies:
- libuv 1.x
- mbedtls 2.x (optional, for TLS)
- mimalloc (optional, high-performance memory allocator)
Installing Dependencies
Ubuntu/Debian
sudo apt-get update
sudo apt-get install build-essential cmakeCentOS/RHEL
sudo yum groupinstall "Development Tools"
sudo yum install cmakemacOS
brew install cmakeBuilding the Project
Build Mode Specification
The UVHTTP project defines three build modes, each suited to different scenarios:
| Build Mode | Use Case | Compile Flags | Applicable Programs |
|---|---|---|---|
| Release | Production, performance testing | -O2 -DNDEBUG | All benchmark programs, example programs |
| Debug | Development, debugging, unit testing | -O0 -g | Unit tests, test programs |
| Coverage | Code coverage analysis | -O0 --coverage | Coverage testing |
Important notes:
- Performance testing must use Release mode, otherwise the data is inaccurate (Debug mode can be 10-100 times slower)
- For detailed build mode specifications, refer to BUILD_MODES.md
Basic Build
Release Mode (recommended for performance testing)
make buildDebug Mode (for development and debugging)
make buildCoverage Mode (for coverage analysis)
make buildCompilation Options
Edit the option() defaults in CMakeLists.txt, then run make build:
# Enable WebSocket support — set BUILD_WITH_WEBSOCKET to ON in CMakeLists.txt
# Enable the mimalloc allocator — set BUILD_WITH_MIMALLOC to ON in CMakeLists.txt
# Enable TLS support — set BUILD_WITH_HTTPS to ON in CMakeLists.txt
# Debug mode — set ENABLE_DEBUG to ON in CMakeLists.txt
# Enable code coverage — set ENABLE_COVERAGE to ON in CMakeLists.txt
# Enable example programs — set BUILD_EXAMPLES to ON in CMakeLists.txt
make buildSelecting the Memory Allocator
Edit CMakeLists.txt, modify the value of UVHTTP_ALLOCATOR_TYPE, then run make build:
# System allocator (default) — UVHTTP_ALLOCATOR_TYPE=0
# mimalloc allocator — UVHTTP_ALLOCATOR_TYPE=1
make buildCoding Standards
Naming Conventions
- Functions:
uvhttp_module_action(e.g.,uvhttp_server_new) - Types:
uvhttp_name_t(e.g.,uvhttp_server_t) - Constants:
UVHTTP_UPPER_CASE(e.g.,UVHTTP_MAX_HEADERS) - Macros:
UVHTTP_UPPER_CASE(e.g.,UVHTTP_MALLOC)
Code Style
- Standard: C99
- Indentation: 4 spaces
- Braces: K&R style
- Line length: 120 characters maximum
Comment Standards
/**
* @brief Brief description of the function
* @param param1 Description of parameter 1
* @param param2 Description of parameter 2
* @return Description of the return value
*/
uvhttp_error_t uvhttp_function(int param1, const char* param2);Memory Management
Unified Allocator
UVHTTP provides a unified memory management interface, selecting the allocator type at compile time.
Basic Operations
// Allocate memory
void* ptr = uvhttp_alloc(size);
if (!ptr) {
return UVHTTP_ERROR_OUT_OF_MEMORY;
}
// Reallocate
ptr = uvhttp_realloc(ptr, new_size);
if (!ptr) {
return UVHTTP_ERROR_OUT_OF_MEMORY;
}
// Free memory
uvhttp_free(ptr);
// Allocate and initialize
ptr = uvhttp_calloc(count, size);
if (!ptr) {
return UVHTTP_ERROR_OUT_OF_MEMORY;
}Allocator Types
UVHTTP supports two allocator types:
System allocator (default)
- Stable and reliable, no extra dependencies
- Zero abstraction overhead
- Suitable for most scenarios
mimalloc allocator
- Modern allocator
- Built-in small-object optimization
- Multithreaded scalability
- Reduced memory fragmentation
Compile-Time Configuration
Edit CMakeLists.txt, modify the value of UVHTTP_ALLOCATOR_TYPE, then run make build:
# System allocator (default) — UVHTTP_ALLOCATOR_TYPE=0
# mimalloc allocator — UVHTTP_ALLOCATOR_TYPE=1
make buildPerformance Characteristics
- Zero runtime overhead: all functions are inline
- Compile-time optimization: the compiler can fully optimize
- Type safety: compile-time type checking
- Predictability: no dynamic dispatch
Best Practices
- Uniform use: always use
uvhttp_alloc/uvhttp_free, do not mix withmalloc/free - Paired allocation: every allocation has a corresponding free
- Check return values: check whether the allocation succeeded
- Avoid leaks: ensure all paths free memory
- Avoid double free: set the pointer to
NULLafter freeing
Complete Example
#include "uvhttp_allocator.h"
void example_memory_usage(void) {
// Allocate memory
char* buffer = uvhttp_alloc(1024);
if (!buffer) {
fprintf(stderr, "Failed to allocate memory\n");
return;
}
// Use the memory
strcpy(buffer, "Hello, World!");
// Reallocate
buffer = uvhttp_realloc(buffer, 2048);
if (!buffer) {
fprintf(stderr, "Failed to reallocate memory\n");
return;
}
// Free the memory
uvhttp_free(buffer);
buffer = NULL; // avoid dangling pointer
}Memory Leak Detection
Use Valgrind to detect memory leaks:
# Build the Debug version — set ENABLE_DEBUG to ON in CMakeLists.txt, then run:
make build
# Run Valgrind
valgrind --leak-check=full --show-leak-kinds=all ./dist/bin/helloworldError Handling
Error Codes
All error codes are negative, and UVHTTP_OK (0) indicates success.
typedef enum {
UVHTTP_OK = 0,
UVHTTP_ERROR_INVALID_PARAM = -1,
UVHTTP_ERROR_OUT_OF_MEMORY = -2,
UVHTTP_ERROR_IO = -3,
// ... more error codes
} uvhttp_error_t;Error Handling Patterns
// Basic error handling
uvhttp_error_t result = uvhttp_server_listen(server, host, port);
if (result != UVHTTP_OK) {
fprintf(stderr, "Error: %s\n", uvhttp_error_string(result));
fprintf(stderr, "Description: %s\n", uvhttp_error_description(result));
fprintf(stderr, "Suggestion: %s\n", uvhttp_error_suggestion(result));
return 1;
}
// Error recovery
if (result != UVHTTP_OK && uvhttp_error_is_recoverable(result)) {
// Attempt a recovery operation
result = uvhttp_server_listen(server, "0.0.0.0", 8081);
}Error Handling Principles
- Check all function calls that could fail
- Use a unified error type
- Provide meaningful error messages
- Support error recovery
Testing
Running Tests
# Run all tests
./run_tests.sh
# Run a specific test
./dist/bin/test_router_full_coverage
# Generate a coverage report
./run_tests.sh --detailedWriting Tests
#include <gtest/gtest.h>
TEST(UvhttpTest, BasicFunctionality) {
// Test code
EXPECT_EQ(result, UVHTTP_OK);
}Test Coverage
- Unit tests: test individual functions
- Integration tests: test module interactions
- Performance tests: test performance metrics
Performance Optimization
Zero-Copy Optimization
// Use libuv buffers
uv_buf_t buf = uv_buf_init(data, len);
uv_write(req, stream, &buf, 1, callback);
// Use sendfile
uvhttp_static_sendfile("/path/to/file", response);Caching Strategy
// Prewarm the cache
uvhttp_static_prewarm_cache(ctx, "/static/index.html");
// Use an LRU cache
cache_manager_t* cache = NULL;
uvhttp_lru_cache_create(1024 * 1024, 256, 0, &cache);Memory Optimization
// Use inline functions
static inline void* uvhttp_alloc(size_t size) {
return malloc(size);
}
// Avoid unnecessary copies
const char* data = uvhttp_request_get_body(request, &len);Debugging Tips
Enabling Debug Output
# Set ENABLE_DEBUG to ON in CMakeLists.txt, then run:
make buildUsing GDB
gdb ./dist/bin/helloworld
(gdb) run
(gdb) backtrace
(gdb) print variableLog Output
#include "uvhttp_logging.h"
// Log output goes to stderr in debug builds
// (controlled by NDEBUG / UVHTTP_FEATURE_LOGGING at compile time)
// Output logs
UVHTTP_LOG_DEBUG("Debug message: %s", message);
UVHTTP_LOG_INFO("Info message: %s", message);
UVHTTP_LOG_ERROR("Error message: %s", message);Committing Code
Commit Conventions
<type>(<scope>): <subject>
<body>
<footer>Types
feat: new featurefix: bug fixdocs: documentation updatestyle: code formatting changesrefactor: refactoringperf: performance optimizationtest: testing relatedchore: build/tooling related
Example
feat(server): add WebSocket support
Implement WebSocket protocol support for real-time
communication.
- Add WebSocket handshake handling
- Add frame parsing and generation
- Add connection management
Closes #123Code Review
Review Focus Points
- Memory management: correct use of
uvhttp_alloc/uvhttp_free - Error handling: check all functions that could fail
- Naming conventions: follow the naming conventions
- Code style: conform to the coding standards
- Performance: avoid unnecessary copies and allocations
- Security: input validation and bounds checking
Review Process
- Create a Pull Request
- CI/CD tests run automatically
- Code review
- Make changes and re-review
- Merge into the main branch
FAQ
Q: How do I choose a memory allocator?
A:
- System allocator: suitable for most scenarios, stable and reliable
- mimalloc: suitable for high-concurrency, multithreaded scenarios with better performance
# Edit CMakeLists.txt, set UVHTTP_ALLOCATOR_TYPE to 1, then run:
make buildQ: How do I handle memory leaks?
A:
- Use Valgrind to detect leaks
- Ensure every
uvhttp_allochas a correspondinguvhttp_free - Use RAII patterns to manage resources
Q: How do I optimize performance?
A:
- Use zero-copy techniques
- Enable caching
- Use the mimalloc allocator
- Avoid unnecessary memory allocations
Q: How do I debug network issues?
A:
- Enable debug logging
- Capture packets with tcpdump
- Debug with GDB
- Check error codes and error messages
Reference Materials
License
MIT License - see the LICENSE file for details