1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
//! Centralized constants for the mik-sdk crate.
//!
//! All limits, sizes, and magic numbers are defined here for easy tuning
//! and consistent behavior across the SDK.
//!
//! # Environment Variables
//!
//! Some limits can be configured via environment variables:
//!
//! | Variable | Default | Description |
//! |----------------------|--------------------|------------------------------------|
//! | `MIK_MAX_JSON_SIZE` | 1 MB (1,000,000) | Maximum JSON input size |
//! | `MIK_MAX_BODY_SIZE` | 10 MB (10,485,760) | Maximum request body size (bridge) |
//!
//! ## Example
//!
//! ```bash
//! # Allow 5MB JSON payloads
//! MIK_MAX_JSON_SIZE=5000000
//!
//! # Allow 50MB request bodies (set in bridge component)
//! MIK_MAX_BODY_SIZE=52428800
//! ```
use OnceLock;
// ============================================================================
// TIME CONSTANTS
// ============================================================================
/// Seconds in a day (24 * 60 * 60).
pub const SECONDS_PER_DAY: u64 = 86400;
/// Seconds in an hour (60 * 60).
pub const SECONDS_PER_HOUR: u64 = 3600;
/// Seconds in a minute.
pub const SECONDS_PER_MINUTE: u64 = 60;
// ============================================================================
// JSON LIMITS
// ============================================================================
/// Default maximum JSON input size (1MB) - prevents memory exhaustion.
const DEFAULT_MAX_JSON_SIZE: usize = 1_000_000;
/// Cached max JSON size from environment.
static MAX_JSON_SIZE_CACHE: = new;
/// Returns the maximum allowed JSON input size in bytes.
///
/// Reads from `MIK_MAX_JSON_SIZE` environment variable on first call.
/// Falls back to 1MB (1,000,000 bytes) if not set or invalid.
///
/// The value is cached for the lifetime of the process, so environment
/// changes after first access have no effect.
///
/// # Example
///
/// ```bash
/// # 5MB limit
/// MIK_MAX_JSON_SIZE=5000000
///
/// # 500KB limit
/// MIK_MAX_JSON_SIZE=512000
/// ```
/// Maximum JSON nesting depth - prevents stack overflow.
///
/// Set conservatively low (20) because:
/// 1. Real-world JSON rarely exceeds 10 levels of nesting
/// 2. miniserde uses recursive parsing which consumes stack per level
/// 3. WASM environments may have limited stack space
pub const MAX_JSON_DEPTH: usize = 20;
// ============================================================================
// HTTP REQUEST LIMITS
// ============================================================================
/// Maximum decoded URL length (64KB).
/// Prevents DoS via extremely long encoded URLs.
pub const MAX_URL_DECODED_LEN: usize = 65536;
/// Maximum number of form fields.
/// Prevents DoS via forms with thousands of tiny fields.
pub const MAX_FORM_FIELDS: usize = 1000;
/// Maximum individual header value length (8KB).
/// Prevents memory exhaustion from single large headers.
pub const MAX_HEADER_VALUE_LEN: usize = 8192;
/// Maximum total size of all headers combined (1MB).
/// Prevents memory exhaustion from many headers.
pub const MAX_TOTAL_HEADERS_SIZE: usize = 1024 * 1024;
// ============================================================================
// ENCODING
// ============================================================================
/// Hex character lookup table for fast byte-to-hex conversion.
pub const HEX_CHARS: & = b"0123456789abcdef";
// ============================================================================
// COMMON HEADER NAMES
// ============================================================================
/// Content-Type header name (lowercase for lookups).
pub const HEADER_CONTENT_TYPE: &str = "content-type";
/// Content-Type header name (title-case for setting headers).
pub const HEADER_CONTENT_TYPE_TITLE: &str = "Content-Type";
/// Authorization header name (lowercase for lookups).
pub const HEADER_AUTHORIZATION: &str = "authorization";
/// Trace ID header name (lowercase for lookups).
pub const HEADER_TRACE_ID: &str = "x-trace-id";
/// Trace ID header name (title-case for setting headers).
pub const HEADER_TRACE_ID_TITLE: &str = "X-Trace-Id";
// ============================================================================
// COMMON MIME TYPES
// ============================================================================
/// JSON MIME type.
pub const MIME_JSON: &str = "application/json";
/// RFC 7807 Problem Details MIME type.
pub const MIME_PROBLEM_JSON: &str = "application/problem+json";
/// HTML MIME type.
pub const MIME_HTML: &str = "text/html";
/// Form URL-encoded MIME type.
pub const MIME_FORM_URLENCODED: &str = "application/x-www-form-urlencoded";
// ============================================================================
// HTTP STATUS TITLES
// ============================================================================
/// Returns the standard title for an HTTP status code.
///
/// This centralizes status code → title mapping for RFC 7807 Problem Details
/// responses and logging.
///
/// # Examples
///
/// ```
/// use mik_sdk::constants::status_title;
///
/// assert_eq!(status_title(200), "OK");
/// assert_eq!(status_title(404), "Not Found");
/// assert_eq!(status_title(500), "Internal Server Error");
/// assert_eq!(status_title(999), "Error"); // Unknown codes
/// ```
pub const