iodine 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/ext/iodine/fio-stl.h +861 -250
- data/ext/iodine/fio-stl.md +150 -195
- data/ext/iodine/iodine_utils.h +1 -1
- data/lib/iodine/version.rb +1 -1
- metadata +2 -2
data/ext/iodine/fio-stl.h
CHANGED
|
@@ -73,7 +73,7 @@ supports macros that will help detect and validate it's version.
|
|
|
73
73
|
/** MINOR version: Deprecation, or significant features added. May break ABI. */
|
|
74
74
|
#define FIO_VERSION_MINOR 8
|
|
75
75
|
/** PATCH version: Bug fixes, minor features may be added. */
|
|
76
|
-
#define FIO_VERSION_PATCH
|
|
76
|
+
#define FIO_VERSION_PATCH 2
|
|
77
77
|
/** Build version: optional build info (string), i.e. "beta.02" */
|
|
78
78
|
/* #define FIO_VERSION_BUILD */
|
|
79
79
|
|
|
@@ -2146,6 +2146,7 @@ FIO_IFUNC void fio_u2bufzu(void *buf, size_t i) { fio_u2buf32u(buf, i); }
|
|
|
2146
2146
|
#warning \
|
|
2147
2147
|
"Couldn't calculate local version for fio_buf2zu and fio_u2bufzu\n\tSIZE_T_MAX == "##SIZE_T_MAX
|
|
2148
2148
|
#endif
|
|
2149
|
+
|
|
2149
2150
|
/* *****************************************************************************
|
|
2150
2151
|
Vector Math, Shuffle & Reduction on native types, for up to 2048 bits
|
|
2151
2152
|
***************************************************************************** */
|
|
@@ -5026,7 +5027,85 @@ FIO_IFUNC uint64_t fio_cycle_counter(void) {
|
|
|
5026
5027
|
}
|
|
5027
5028
|
|
|
5028
5029
|
/* *****************************************************************************
|
|
5029
|
-
|
|
5030
|
+
Finding first different byte
|
|
5031
|
+
***************************************************************************** */
|
|
5032
|
+
#if FIO___DIFF_INDEX
|
|
5033
|
+
/**
|
|
5034
|
+
* Returns index of first different byte, or original length if none found.
|
|
5035
|
+
*/
|
|
5036
|
+
FIO_SFUNC size_t fio___diff_index(const void *a_, const void *b_, size_t len) {
|
|
5037
|
+
|
|
5038
|
+
const uint8_t *a = a_, *b = b_;
|
|
5039
|
+
if (FIO_UNLIKELY(!len | (a == b)))
|
|
5040
|
+
return len;
|
|
5041
|
+
if (a[0] != b[0])
|
|
5042
|
+
return 0;
|
|
5043
|
+
if (len == 1)
|
|
5044
|
+
return len;
|
|
5045
|
+
size_t i = 0;
|
|
5046
|
+
while (len > 127) {
|
|
5047
|
+
uint64_t a1[16], b1[16], tst = 0;
|
|
5048
|
+
fio_memcpy128(a1, a + i);
|
|
5049
|
+
fio_memcpy128(b1, b + i);
|
|
5050
|
+
for (size_t j = 0; j < (sizeof(a1) / sizeof(a1[0])); ++j)
|
|
5051
|
+
tst |= (a1[j] ^ b1[j]);
|
|
5052
|
+
if (tst) {
|
|
5053
|
+
len |= 127;
|
|
5054
|
+
break;
|
|
5055
|
+
}
|
|
5056
|
+
i += 128;
|
|
5057
|
+
len -= 128;
|
|
5058
|
+
}
|
|
5059
|
+
|
|
5060
|
+
#define fio___diff_index_step(half) \
|
|
5061
|
+
do { \
|
|
5062
|
+
if ((len & half)) { \
|
|
5063
|
+
uint64_t a1[(half / 8)], b1[(half / 8)]; \
|
|
5064
|
+
for (size_t rounds = (len == half); 1; ++rounds) { \
|
|
5065
|
+
uint64_t tst = 0; \
|
|
5066
|
+
fio_memcpy##half(a1, a + i); \
|
|
5067
|
+
fio_memcpy##half(b1, b + i); \
|
|
5068
|
+
for (size_t j = 0; j < (sizeof(a1) / sizeof(a1[0])); ++j) { \
|
|
5069
|
+
a1[j] ^= b1[j]; \
|
|
5070
|
+
tst |= a1[j]; \
|
|
5071
|
+
} \
|
|
5072
|
+
if (tst) \
|
|
5073
|
+
break; \
|
|
5074
|
+
if (rounds) \
|
|
5075
|
+
return i + half; \
|
|
5076
|
+
i += (len & (half - 1)); \
|
|
5077
|
+
} \
|
|
5078
|
+
for (size_t j = 0; j < (sizeof(a1) / sizeof(a1[0])); ++j) \
|
|
5079
|
+
if (a1[j]) \
|
|
5080
|
+
return i + (j << 3) + \
|
|
5081
|
+
(fio_lsb_index_unsafe(fio_ltole64(a1[j])) >> 3); \
|
|
5082
|
+
return i; \
|
|
5083
|
+
} \
|
|
5084
|
+
} while (0)
|
|
5085
|
+
|
|
5086
|
+
fio___diff_index_step(64);
|
|
5087
|
+
fio___diff_index_step(32);
|
|
5088
|
+
fio___diff_index_step(16);
|
|
5089
|
+
fio___diff_index_step(8);
|
|
5090
|
+
|
|
5091
|
+
if ((len & 4)) {
|
|
5092
|
+
size_t tst = (fio_buf2u32u(a + i) == fio_buf2u32u(b + i));
|
|
5093
|
+
i += (tst << 2); /* should skip? */
|
|
5094
|
+
len |= (4 - (!tst)); /* should seek inside? */
|
|
5095
|
+
}
|
|
5096
|
+
if ((len & 2)) {
|
|
5097
|
+
size_t tst = (fio_buf2u16u(a + i) == fio_buf2u16u(b + i));
|
|
5098
|
+
i += (tst << 1); /* should skip? */
|
|
5099
|
+
len |= (2 - (!tst)); /* should seek inside? */
|
|
5100
|
+
}
|
|
5101
|
+
|
|
5102
|
+
if (len & 1)
|
|
5103
|
+
i += (a[i] == b[i]);
|
|
5104
|
+
return i;
|
|
5105
|
+
}
|
|
5106
|
+
#endif
|
|
5107
|
+
/* *****************************************************************************
|
|
5108
|
+
String and Buffer Information Containers
|
|
5030
5109
|
***************************************************************************** */
|
|
5031
5110
|
|
|
5032
5111
|
/** An information type for reporting the string's state. */
|
|
@@ -5055,15 +5134,205 @@ typedef struct fio_ubuf_info_s {
|
|
|
5055
5134
|
unsigned char *buf;
|
|
5056
5135
|
} fio_ubuf_info_s;
|
|
5057
5136
|
|
|
5137
|
+
/* *****************************************************************************
|
|
5138
|
+
Case Sensitive and Insensitive Equality
|
|
5139
|
+
***************************************************************************** */
|
|
5140
|
+
|
|
5141
|
+
/**
|
|
5142
|
+
* Returns true if equal, similar to:
|
|
5143
|
+
* (a.len == b.len && !memcmp(a.buf, b.buf, a.len))
|
|
5144
|
+
*/
|
|
5145
|
+
FIO_SFUNC bool fio_buf_info_is_eq(const fio_buf_info_s a,
|
|
5146
|
+
const fio_buf_info_s b) {
|
|
5147
|
+
if (a.len != b.len)
|
|
5148
|
+
return false;
|
|
5149
|
+
size_t n = a.len;
|
|
5150
|
+
if (!n || a.buf == b.buf)
|
|
5151
|
+
return true;
|
|
5152
|
+
if (!a.buf || !b.buf)
|
|
5153
|
+
return false;
|
|
5154
|
+
const uint8_t *x = (const uint8_t *)a.buf, *y = (const uint8_t *)b.buf;
|
|
5155
|
+
if (x[0] != y[0])
|
|
5156
|
+
return false;
|
|
5157
|
+
if (n <= 32) {
|
|
5158
|
+
if (n > 24)
|
|
5159
|
+
return !((fio_buf2u64u(x) ^ fio_buf2u64u(y)) |
|
|
5160
|
+
(fio_buf2u64u(x + 8) ^ fio_buf2u64u(y + 8)) |
|
|
5161
|
+
(fio_buf2u64u(x + 16) ^ fio_buf2u64u(y + 16)) |
|
|
5162
|
+
(fio_buf2u64u(x + n - 8) ^ fio_buf2u64u(y + n - 8)));
|
|
5163
|
+
if (n > 16)
|
|
5164
|
+
return !((fio_buf2u64u(x) ^ fio_buf2u64u(y)) |
|
|
5165
|
+
(fio_buf2u64u(x + 8) ^ fio_buf2u64u(y + 8)) |
|
|
5166
|
+
(fio_buf2u64u(x + n - 8) ^ fio_buf2u64u(y + n - 8)));
|
|
5167
|
+
if (n >= 8)
|
|
5168
|
+
return !((fio_buf2u64u(x) ^ fio_buf2u64u(y)) |
|
|
5169
|
+
(fio_buf2u64u(x + n - 8) ^ fio_buf2u64u(y + n - 8)));
|
|
5170
|
+
if (n >= 4)
|
|
5171
|
+
return !((fio_buf2u32u(x) ^ fio_buf2u32u(y)) |
|
|
5172
|
+
(fio_buf2u32u(x + n - 4) ^ fio_buf2u32u(y + n - 4)));
|
|
5173
|
+
if (n >= 2)
|
|
5174
|
+
return !((fio_buf2u16u(x) ^ fio_buf2u16u(y)) | (x[n - 1] ^ y[n - 1]));
|
|
5175
|
+
return true;
|
|
5176
|
+
}
|
|
5177
|
+
/* test 32 byte tail */
|
|
5178
|
+
if (((fio_buf2u64u(x + n - 32) ^ fio_buf2u64u(y + n - 32)) |
|
|
5179
|
+
(fio_buf2u64u(x + n - 24) ^ fio_buf2u64u(y + n - 24)) |
|
|
5180
|
+
(fio_buf2u64u(x + n - 16) ^ fio_buf2u64u(y + n - 16)) |
|
|
5181
|
+
(fio_buf2u64u(x + n - 8) ^ fio_buf2u64u(y + n - 8))))
|
|
5182
|
+
return false;
|
|
5183
|
+
while (n >= 128) {
|
|
5184
|
+
uint8_t diff = 0;
|
|
5185
|
+
for (size_t j = 0; j < 128; ++j)
|
|
5186
|
+
diff |= (uint8_t)(x[j] ^ y[j]);
|
|
5187
|
+
if (diff)
|
|
5188
|
+
return false;
|
|
5189
|
+
x += 128;
|
|
5190
|
+
y += 128;
|
|
5191
|
+
n -= 128;
|
|
5192
|
+
}
|
|
5193
|
+
if (n > 64) {
|
|
5194
|
+
uint8_t diff = 0;
|
|
5195
|
+
for (size_t j = 0; j < 64; ++j)
|
|
5196
|
+
diff |= (uint8_t)(x[j] ^ y[j]);
|
|
5197
|
+
if (diff)
|
|
5198
|
+
return false;
|
|
5199
|
+
x += 64;
|
|
5200
|
+
y += 64;
|
|
5201
|
+
n -= 64;
|
|
5202
|
+
}
|
|
5203
|
+
if (n > 32)
|
|
5204
|
+
return !((fio_buf2u64u(x) ^ fio_buf2u64u(y)) |
|
|
5205
|
+
(fio_buf2u64u(x + 8) ^ fio_buf2u64u(y + 8)) |
|
|
5206
|
+
(fio_buf2u64u(x + 16) ^ fio_buf2u64u(y + 16)) |
|
|
5207
|
+
(fio_buf2u64u(x + 24) ^ fio_buf2u64u(y + 24)));
|
|
5208
|
+
|
|
5209
|
+
return true;
|
|
5210
|
+
}
|
|
5211
|
+
|
|
5212
|
+
/** An ASCII case insensitive compare for binary strings (not UTF-8). */
|
|
5213
|
+
FIO_SFUNC bool fio_buf_info_is_ieq(fio_buf_info_s a, fio_buf_info_s b) {
|
|
5214
|
+
if (a.len != b.len)
|
|
5215
|
+
return false;
|
|
5216
|
+
size_t n = a.len;
|
|
5217
|
+
if (!n || a.buf == b.buf)
|
|
5218
|
+
return true;
|
|
5219
|
+
const uint8_t *x = (const uint8_t *)a.buf;
|
|
5220
|
+
const uint8_t *y = (const uint8_t *)b.buf;
|
|
5221
|
+
uint8_t diff = 0;
|
|
5222
|
+
{ /* fast path, testing first byte */
|
|
5223
|
+
unsigned letter = ((y[0] | 0x20U) - 'a') <= ('z' - 'a');
|
|
5224
|
+
if ((x[0] ^ y[0]) & ~(letter << 5))
|
|
5225
|
+
return false;
|
|
5226
|
+
}
|
|
5227
|
+
if (n == 1)
|
|
5228
|
+
return true;
|
|
5229
|
+
while (n >= 64) {
|
|
5230
|
+
for (size_t j = 0; j < 64; ++j) {
|
|
5231
|
+
unsigned letter = ((unsigned)(y[j] | 0x20U) - 'a') <= ('z' - 'a');
|
|
5232
|
+
diff |= (uint8_t)((x[j] ^ y[j]) & ~(letter << 5));
|
|
5233
|
+
}
|
|
5234
|
+
if (diff)
|
|
5235
|
+
return false;
|
|
5236
|
+
x += 64;
|
|
5237
|
+
y += 64;
|
|
5238
|
+
n -= 64;
|
|
5239
|
+
}
|
|
5240
|
+
while (n >= 16) {
|
|
5241
|
+
for (size_t j = 0; j < 16; ++j) {
|
|
5242
|
+
unsigned letter = ((unsigned)(y[j] | 0x20U) - 'a') <= ('z' - 'a');
|
|
5243
|
+
diff |= (uint8_t)((x[j] ^ y[j]) & ~(letter << 5));
|
|
5244
|
+
}
|
|
5245
|
+
if (diff)
|
|
5246
|
+
return false;
|
|
5247
|
+
x += 16;
|
|
5248
|
+
y += 16;
|
|
5249
|
+
n -= 16;
|
|
5250
|
+
}
|
|
5251
|
+
if (n & 8) {
|
|
5252
|
+
for (size_t j = 0; j < 8; ++j) {
|
|
5253
|
+
unsigned letter = ((unsigned)(y[j] | 0x20U) - 'a') <= ('z' - 'a');
|
|
5254
|
+
diff |= (uint8_t)((x[j] ^ y[j]) & ~(letter << 5));
|
|
5255
|
+
}
|
|
5256
|
+
n &= 7;
|
|
5257
|
+
x += n;
|
|
5258
|
+
y += n;
|
|
5259
|
+
for (size_t j = 0; j < 8; ++j) {
|
|
5260
|
+
unsigned letter = ((unsigned)(y[j] | 0x20U) - 'a') <= ('z' - 'a');
|
|
5261
|
+
diff |= (uint8_t)((x[j] ^ y[j]) & ~(letter << 5));
|
|
5262
|
+
}
|
|
5263
|
+
return !diff;
|
|
5264
|
+
}
|
|
5265
|
+
for (size_t j = 0; j < n; ++j) {
|
|
5266
|
+
unsigned letter = ((unsigned)(y[j] | 0x20U) - 'a') <= ('z' - 'a');
|
|
5267
|
+
diff |= (uint8_t)((x[j] ^ y[j]) & ~(letter << 5));
|
|
5268
|
+
}
|
|
5269
|
+
return !diff;
|
|
5270
|
+
}
|
|
5271
|
+
|
|
5272
|
+
/**
|
|
5273
|
+
* Returns true if equal, similar to:
|
|
5274
|
+
* (a.len == b.len && !memcmp(a.buf, b.buf, a.len))
|
|
5275
|
+
*/
|
|
5276
|
+
FIO_IFUNC bool fio_ubuf_info_is_eq(const fio_ubuf_info_s a,
|
|
5277
|
+
const fio_ubuf_info_s b) {
|
|
5278
|
+
return fio_buf_info_is_eq(
|
|
5279
|
+
(fio_buf_info_s){.len = a.len, .buf = (char *)a.buf},
|
|
5280
|
+
(fio_buf_info_s){.len = b.len, .buf = (char *)b.buf});
|
|
5281
|
+
}
|
|
5282
|
+
|
|
5283
|
+
/** An ASCII case insensitive compare for binary strings (not UTF-8). */
|
|
5284
|
+
FIO_IFUNC bool fio_ubuf_info_is_ieq(const fio_ubuf_info_s a,
|
|
5285
|
+
const fio_ubuf_info_s b) {
|
|
5286
|
+
return fio_buf_info_is_ieq(
|
|
5287
|
+
(const fio_buf_info_s){.len = a.len, .buf = (char *)a.buf},
|
|
5288
|
+
(const fio_buf_info_s){.len = b.len, .buf = (char *)b.buf});
|
|
5289
|
+
}
|
|
5290
|
+
|
|
5291
|
+
/**
|
|
5292
|
+
* Returns true if equal, similar to:
|
|
5293
|
+
* (a.len == b.len && !memcmp(a.buf, b.buf, a.len))
|
|
5294
|
+
*/
|
|
5295
|
+
FIO_IFUNC bool fio_str_info_is_eq(const fio_str_info_s a,
|
|
5296
|
+
const fio_str_info_s b) {
|
|
5297
|
+
return fio_buf_info_is_eq((const fio_buf_info_s){.len = a.len, .buf = a.buf},
|
|
5298
|
+
(const fio_buf_info_s){.len = b.len, .buf = b.buf});
|
|
5299
|
+
}
|
|
5300
|
+
|
|
5301
|
+
/** An ASCII case insensitive compare for binary strings (not UTF-8). */
|
|
5302
|
+
FIO_IFUNC bool fio_str_info_is_ieq(const fio_str_info_s a,
|
|
5303
|
+
const fio_str_info_s b) {
|
|
5304
|
+
return fio_buf_info_is_ieq(
|
|
5305
|
+
(const fio_buf_info_s){.len = a.len, .buf = a.buf},
|
|
5306
|
+
(const fio_buf_info_s){.len = b.len, .buf = b.buf});
|
|
5307
|
+
}
|
|
5308
|
+
|
|
5309
|
+
/* *****************************************************************************
|
|
5310
|
+
String and Buffer Information – Helper Macros
|
|
5311
|
+
***************************************************************************** */
|
|
5312
|
+
|
|
5313
|
+
#ifdef FIO_MEMALT
|
|
5314
|
+
/** Compares two `fio_str_info_s` objects for content equality. */
|
|
5315
|
+
#define FIO_STR_INFO_IS_EQ(s1, s2) fio_str_info_is_eq(s1, s2)
|
|
5316
|
+
#else
|
|
5058
5317
|
/** Compares two `fio_str_info_s` objects for content equality. */
|
|
5059
5318
|
#define FIO_STR_INFO_IS_EQ(s1, s2) \
|
|
5060
5319
|
((s1).len == (s2).len && \
|
|
5061
5320
|
(!(s1).len || (s1).buf == (s2).buf || \
|
|
5062
5321
|
((s1).buf && (s2).buf && (s1).buf[0] == (s2).buf[0] && \
|
|
5063
5322
|
!FIO_MEMCMP((s1).buf, (s2).buf, (s1).len))))
|
|
5323
|
+
#endif
|
|
5064
5324
|
|
|
5325
|
+
#ifdef FIO_MEMALT
|
|
5326
|
+
/** Compares two `fio_buf_info_s` objects for content equality. */
|
|
5327
|
+
#define FIO_BUF_INFO_IS_EQ(s1, s2) fio_buf_info_is_eq((s1), (s2))
|
|
5065
5328
|
/** Compares two `fio_buf_info_s` objects for content equality. */
|
|
5066
|
-
#define
|
|
5329
|
+
#define FIO_UBUF_INFO_IS_EQ(s1, s2) fio_ubuf_info_is_eq((s1), (s2))
|
|
5330
|
+
#else
|
|
5331
|
+
/** Compares two `fio_buf_info_s` objects for content equality. */
|
|
5332
|
+
#define FIO_BUF_INFO_IS_EQ(s1, s2) FIO_STR_INFO_IS_EQ((s1), (s2))
|
|
5333
|
+
/** Compares two `fio_buf_info_s` objects for content equality. */
|
|
5334
|
+
#define FIO_UBUF_INFO_IS_EQ(s1, s2) FIO_STR_INFO_IS_EQ((s1), (s2))
|
|
5335
|
+
#endif
|
|
5067
5336
|
|
|
5068
5337
|
/** A NULL fio_str_info_s. */
|
|
5069
5338
|
#define FIO_STR_INFO0 ((fio_str_info_s){0})
|
|
@@ -9318,24 +9587,94 @@ SFUNC FIO___ASAN_AVOID size_t fio_strlen(const char *str) {
|
|
|
9318
9587
|
fio_memcmp
|
|
9319
9588
|
***************************************************************************** */
|
|
9320
9589
|
|
|
9321
|
-
|
|
9590
|
+
FIO_SFUNC int fio___memcmp7x(const void *restrict a_,
|
|
9591
|
+
const void *restrict b_,
|
|
9592
|
+
size_t len) {
|
|
9593
|
+
unsigned r = 0;
|
|
9594
|
+
const uint8_t *a = a_, *b = b_;
|
|
9595
|
+
const size_t a4 = (len & 4), a3 = (len & 3);
|
|
9596
|
+
if (a4) {
|
|
9597
|
+
const uint64_t diff = (uint64_t)fio_buf2u32_be(a) - fio_buf2u32_be(b);
|
|
9598
|
+
const uint64_t ndiff = ~diff;
|
|
9599
|
+
r = (int)((ndiff & (ndiff + 1)) >> 63) - (int)(diff >> 63);
|
|
9600
|
+
}
|
|
9601
|
+
if (r | (!a3))
|
|
9602
|
+
return r;
|
|
9603
|
+
a += a4;
|
|
9604
|
+
b += a4;
|
|
9605
|
+
switch (a3) {
|
|
9606
|
+
case 0: return 0;
|
|
9607
|
+
case 1: return (int)((unsigned)*(uint8_t *)a - *(uint8_t *)b);
|
|
9608
|
+
case 2: return (int)((unsigned)fio_buf2u16_be(a) - fio_buf2u16_be(b));
|
|
9609
|
+
case 3: return (int)(fio_buf2u24_be(a) - fio_buf2u24_be(b)); ;
|
|
9610
|
+
}
|
|
9611
|
+
return (int)r;
|
|
9612
|
+
}
|
|
9613
|
+
|
|
9322
9614
|
SFUNC int fio_memcmp(const void *a_, const void *b_, size_t len) {
|
|
9323
|
-
|
|
9324
|
-
|
|
9325
|
-
|
|
9326
|
-
|
|
9327
|
-
|
|
9328
|
-
|
|
9329
|
-
|
|
9330
|
-
|
|
9331
|
-
|
|
9332
|
-
|
|
9333
|
-
|
|
9334
|
-
if (
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
|
|
9338
|
-
|
|
9615
|
+
unsigned r = 0;
|
|
9616
|
+
if (!len)
|
|
9617
|
+
return r;
|
|
9618
|
+
if (a_ == b_)
|
|
9619
|
+
return r;
|
|
9620
|
+
const uint8_t *a = a_, *b = b_;
|
|
9621
|
+
uint64_t la, lb;
|
|
9622
|
+
r = *a - *b;
|
|
9623
|
+
if (r)
|
|
9624
|
+
return (int)r;
|
|
9625
|
+
|
|
9626
|
+
if (len > 255)
|
|
9627
|
+
while (len > 127) {
|
|
9628
|
+
uint64_t wa[16], wb[16], diff = 0;
|
|
9629
|
+
fio_memcpy128(wa, a);
|
|
9630
|
+
fio_memcpy128(wb, b);
|
|
9631
|
+
for (size_t i = 0; i < 16; ++i)
|
|
9632
|
+
diff |= (wa[i] ^ wb[i]);
|
|
9633
|
+
if (diff)
|
|
9634
|
+
goto stop;
|
|
9635
|
+
len -= 128;
|
|
9636
|
+
a += 128;
|
|
9637
|
+
b += 128;
|
|
9638
|
+
}
|
|
9639
|
+
|
|
9640
|
+
#define fio___memcmp_tst(bytes) \
|
|
9641
|
+
do \
|
|
9642
|
+
if ((len & bytes)) { \
|
|
9643
|
+
uint64_t a1[(bytes / 8)], b1[(bytes / 8)]; \
|
|
9644
|
+
for (size_t rounds = (len == bytes); 1; ++rounds) { \
|
|
9645
|
+
uint64_t tst = 0; \
|
|
9646
|
+
fio_memcpy##bytes(a1, a); \
|
|
9647
|
+
fio_memcpy##bytes(b1, b); \
|
|
9648
|
+
for (size_t j = 0; j < (sizeof(a1) / sizeof(a1[0])); ++j) { \
|
|
9649
|
+
a1[j] ^= b1[j]; \
|
|
9650
|
+
tst |= a1[j]; \
|
|
9651
|
+
} \
|
|
9652
|
+
if (tst) { \
|
|
9653
|
+
goto stop; \
|
|
9654
|
+
} \
|
|
9655
|
+
if (rounds) \
|
|
9656
|
+
return 0; \
|
|
9657
|
+
a += (len & (bytes - 1)); \
|
|
9658
|
+
b += (len & (bytes - 1)); \
|
|
9659
|
+
} \
|
|
9660
|
+
} \
|
|
9661
|
+
while (0)
|
|
9662
|
+
|
|
9663
|
+
fio___memcmp_tst(128);
|
|
9664
|
+
fio___memcmp_tst(64);
|
|
9665
|
+
fio___memcmp_tst(32);
|
|
9666
|
+
fio___memcmp_tst(16);
|
|
9667
|
+
fio___memcmp_tst(8);
|
|
9668
|
+
return fio___memcmp7x(a, b, len);
|
|
9669
|
+
|
|
9670
|
+
stop:
|
|
9671
|
+
while ((la = fio_buf2u64u(a)) == (lb = fio_buf2u64u(b))) {
|
|
9672
|
+
a += 8;
|
|
9673
|
+
b += 8;
|
|
9674
|
+
}
|
|
9675
|
+
la = fio_lton64(la);
|
|
9676
|
+
lb = fio_lton64(lb);
|
|
9677
|
+
return (int)(la > lb) - (la < lb);
|
|
9339
9678
|
}
|
|
9340
9679
|
|
|
9341
9680
|
/* *****************************************************************************
|
|
@@ -29695,7 +30034,7 @@ FIO_SFUNC int fio_bstr_is_greater(const char *a, const char *b) {
|
|
|
29695
30034
|
FIO_SFUNC int fio_bstr_is_eq(const char *a_, const char *b_) {
|
|
29696
30035
|
fio_buf_info_s a = fio_bstr_buf(a_);
|
|
29697
30036
|
fio_buf_info_s b = fio_bstr_buf(b_);
|
|
29698
|
-
return
|
|
30037
|
+
return FIO_BUF_INFO_IS_EQ(a, b);
|
|
29699
30038
|
}
|
|
29700
30039
|
|
|
29701
30040
|
/** Compares to see if fio_bstr a is equal to another String. */
|
|
@@ -54817,12 +55156,13 @@ FIO_IFUNC int fio___p256_scalar_gte_n(const fio___p256_scalar_s a) {
|
|
|
54817
55156
|
|
|
54818
55157
|
/** Secret-safe check: returns 1 if scalar >= n (curve order). */
|
|
54819
55158
|
FIO_IFUNC int fio___p256_scalar_ct_gte_n(const fio___p256_scalar_s a) {
|
|
54820
|
-
uint64_t borrow = 0;
|
|
54821
|
-
|
|
54822
|
-
|
|
54823
|
-
|
|
54824
|
-
|
|
55159
|
+
uint64_t borrow = 0, ignr;
|
|
55160
|
+
ignr = fio_math_subc64(a[0], FIO___P256_N[0], 0, &borrow);
|
|
55161
|
+
ignr = fio_math_subc64(a[1], FIO___P256_N[1], borrow, &borrow);
|
|
55162
|
+
ignr = fio_math_subc64(a[2], FIO___P256_N[2], borrow, &borrow);
|
|
55163
|
+
ignr = fio_math_subc64(a[3], FIO___P256_N[3], borrow, &borrow);
|
|
54825
55164
|
return (int)(borrow ^ 1);
|
|
55165
|
+
(void)ignr;
|
|
54826
55166
|
}
|
|
54827
55167
|
|
|
54828
55168
|
/** Secret-safe conditional scalar subtraction: a = cond ? a - n : a. */
|
|
@@ -58997,7 +59337,7 @@ FIO_SFUNC void fio___rsa_mul_mod(uint64_t *result,
|
|
|
58997
59337
|
FIO_SFUNC uint64_t fio___rsa_ct_lt(const uint64_t *a,
|
|
58998
59338
|
const uint64_t *b,
|
|
58999
59339
|
size_t word_count) {
|
|
59000
|
-
uint64_t lt = 0;
|
|
59340
|
+
uint64_t lt = 0, ignr;
|
|
59001
59341
|
uint64_t eq = (uint64_t)0 - 1; /* ~0 */
|
|
59002
59342
|
for (size_t i = word_count; i > 0;) {
|
|
59003
59343
|
--i;
|
|
@@ -59005,11 +59345,12 @@ FIO_SFUNC uint64_t fio___rsa_ct_lt(const uint64_t *a,
|
|
|
59005
59345
|
uint64_t b_i = b[i];
|
|
59006
59346
|
uint64_t diff = a_i ^ b_i;
|
|
59007
59347
|
uint64_t borrow = 0;
|
|
59008
|
-
|
|
59348
|
+
ignr = fio_math_subc64(a_i, b_i, 0, &borrow); /* borrow=1 iff a_i < b_i */
|
|
59009
59349
|
lt |= (eq & borrow);
|
|
59010
59350
|
eq &= (uint64_t)0 - (diff == 0);
|
|
59011
59351
|
}
|
|
59012
59352
|
return lt & 1;
|
|
59353
|
+
(void)ignr;
|
|
59013
59354
|
}
|
|
59014
59355
|
|
|
59015
59356
|
/**
|
|
@@ -59037,15 +59378,15 @@ FIO_SFUNC void fio___rsa_reduce_mod(uint64_t *out,
|
|
|
59037
59378
|
size_t high_words = full_word_count - mod_word_count;
|
|
59038
59379
|
if (high_words > mod_word_count)
|
|
59039
59380
|
high_words = mod_word_count;
|
|
59040
|
-
FIO_MEMCPY(m_high, m_full + mod_word_count,
|
|
59041
|
-
high_words * sizeof(uint64_t));
|
|
59381
|
+
FIO_MEMCPY(m_high, m_full + mod_word_count, high_words * sizeof(uint64_t));
|
|
59042
59382
|
}
|
|
59043
59383
|
|
|
59044
59384
|
/* Montgomery multiplication below expects operands in normal form (< mod).
|
|
59045
59385
|
* Since mod has its top bit set for RSA primes, m_high < R < 2*mod, so one
|
|
59046
59386
|
* branchless conditional subtraction is sufficient. */
|
|
59047
59387
|
uint64_t m_high_sub[FIO_RSA_MAX_WORDS];
|
|
59048
|
-
uint64_t m_high_borrow =
|
|
59388
|
+
uint64_t m_high_borrow =
|
|
59389
|
+
fio_math_sub(m_high_sub, m_high, mod, mod_word_count);
|
|
59049
59390
|
uint64_t use_m_high_sub = (uint64_t)0 - (m_high_borrow ^ 1);
|
|
59050
59391
|
uint64_t use_m_high = (uint64_t)0 - m_high_borrow;
|
|
59051
59392
|
for (size_t i = 0; i < mod_word_count; ++i)
|
|
@@ -59072,7 +59413,7 @@ FIO_SFUNC void fio___rsa_reduce_mod(uint64_t *out,
|
|
|
59072
59413
|
uint64_t carry_add[FIO_RSA_MAX_WORDS];
|
|
59073
59414
|
for (size_t i = 0; i < mod_word_count; ++i)
|
|
59074
59415
|
carry_add[i] = R_mod_mod[i] & carry_mask;
|
|
59075
|
-
|
|
59416
|
+
uint64_t ignr_ = fio_math_add(out, out, carry_add, mod_word_count);
|
|
59076
59417
|
|
|
59077
59418
|
/* For RSA primes R < 2*mod, so the value is < 2*mod after carry handling.
|
|
59078
59419
|
* Two conditional subtractions are kept for conservative normalization. */
|
|
@@ -59092,6 +59433,7 @@ FIO_SFUNC void fio___rsa_reduce_mod(uint64_t *out,
|
|
|
59092
59433
|
fio_secure_zero(m_high, sizeof(m_high));
|
|
59093
59434
|
fio_secure_zero(m_high_sub, sizeof(m_high_sub));
|
|
59094
59435
|
fio_secure_zero(carry_add, sizeof(carry_add));
|
|
59436
|
+
(void)ignr_;
|
|
59095
59437
|
}
|
|
59096
59438
|
|
|
59097
59439
|
/**
|
|
@@ -59179,11 +59521,11 @@ FIO_SFUNC void fio___rsa_mul_mod(uint64_t *result,
|
|
|
59179
59521
|
* where R = 2^(64 * word_count).
|
|
59180
59522
|
*/
|
|
59181
59523
|
FIO_SFUNC void fio___rsa_mont_mul(uint64_t *result,
|
|
59182
|
-
|
|
59183
|
-
|
|
59184
|
-
|
|
59185
|
-
|
|
59186
|
-
|
|
59524
|
+
const uint64_t *a,
|
|
59525
|
+
const uint64_t *b,
|
|
59526
|
+
const uint64_t *n,
|
|
59527
|
+
const uint64_t *n_prime,
|
|
59528
|
+
size_t word_count) {
|
|
59187
59529
|
uint64_t t[FIO_RSA_MAX_WORDS * 2];
|
|
59188
59530
|
uint64_t m_full[FIO_RSA_MAX_WORDS * 2];
|
|
59189
59531
|
uint64_t mn[FIO_RSA_MAX_WORDS * 2];
|
|
@@ -59221,9 +59563,9 @@ FIO_SFUNC void fio___rsa_mont_mul(uint64_t *result,
|
|
|
59221
59563
|
* r2modn is R^2 mod n.
|
|
59222
59564
|
*/
|
|
59223
59565
|
FIO_SFUNC void fio___rsa_mont_setup(const uint64_t *n,
|
|
59224
|
-
|
|
59225
|
-
|
|
59226
|
-
|
|
59566
|
+
size_t word_count,
|
|
59567
|
+
uint64_t *n_prime,
|
|
59568
|
+
uint64_t *r2modn) {
|
|
59227
59569
|
uint64_t n_ext[FIO_RSA_MAX_WORDS * 2];
|
|
59228
59570
|
uint64_t tmp[FIO_RSA_MAX_WORDS * 2];
|
|
59229
59571
|
uint64_t prod[FIO_RSA_MAX_WORDS * 2];
|
|
@@ -59234,7 +59576,8 @@ FIO_SFUNC void fio___rsa_mont_setup(const uint64_t *n,
|
|
|
59234
59576
|
n_prime[0] = (uint64_t)0 - n0_inv;
|
|
59235
59577
|
|
|
59236
59578
|
for (int iter = 0; iter < 16; ++iter) {
|
|
59237
|
-
/* prod = n * n_prime + 2 (Newton step for n' satisfying n*n' == -1 mod R)
|
|
59579
|
+
/* prod = n * n_prime + 2 (Newton step for n' satisfying n*n' == -1 mod R)
|
|
59580
|
+
*/
|
|
59238
59581
|
fio_math_mul(prod, n, n_prime, word_count);
|
|
59239
59582
|
uint64_t c = 0;
|
|
59240
59583
|
prod[0] = fio_math_addc64(prod[0], 2, 0, &c);
|
|
@@ -59786,6 +60129,7 @@ FIO_SFUNC int fio___rsa_private_op_crt(uint64_t *result_words,
|
|
|
59786
60129
|
const uint64_t *m_words,
|
|
59787
60130
|
const fio_rsa_privkey_s *key,
|
|
59788
60131
|
size_t word_count) {
|
|
60132
|
+
uint64_t ignr_ = 0;
|
|
59789
60133
|
const uint8_t *n_be = key->n;
|
|
59790
60134
|
const uint8_t *p_be = key->p;
|
|
59791
60135
|
const uint8_t *q_be = key->q;
|
|
@@ -59811,8 +60155,8 @@ FIO_SFUNC int fio___rsa_private_op_crt(uint64_t *result_words,
|
|
|
59811
60155
|
size_t p_word_count = (p_len + 7) / 8;
|
|
59812
60156
|
size_t q_word_count = (q_len + 7) / 8;
|
|
59813
60157
|
|
|
59814
|
-
if (!p_word_count || p_word_count > FIO_RSA_MAX_WORDS / 2 ||
|
|
59815
|
-
|
|
60158
|
+
if (!p_word_count || p_word_count > FIO_RSA_MAX_WORDS / 2 || !q_word_count ||
|
|
60159
|
+
q_word_count > FIO_RSA_MAX_WORDS / 2)
|
|
59816
60160
|
return -1;
|
|
59817
60161
|
|
|
59818
60162
|
uint64_t n_words[FIO_RSA_MAX_WORDS];
|
|
@@ -59881,10 +60225,10 @@ FIO_SFUNC int fio___rsa_private_op_crt(uint64_t *result_words,
|
|
|
59881
60225
|
FIO_MEMSET(q_minus_2, 0, sizeof(q_minus_2));
|
|
59882
60226
|
FIO_MEMCPY(p_minus_2, p, p_word_count * sizeof(uint64_t));
|
|
59883
60227
|
FIO_MEMCPY(q_minus_2, q, q_word_count * sizeof(uint64_t));
|
|
59884
|
-
|
|
59885
|
-
|
|
59886
|
-
|
|
59887
|
-
|
|
60228
|
+
ignr_ = fio_math_sub(p_minus_2, p_minus_2, one, p_word_count); /* p-1 */
|
|
60229
|
+
ignr_ = fio_math_sub(p_minus_2, p_minus_2, one, p_word_count); /* p-2 */
|
|
60230
|
+
ignr_ = fio_math_sub(q_minus_2, q_minus_2, one, q_word_count); /* q-1 */
|
|
60231
|
+
ignr_ = fio_math_sub(q_minus_2, q_minus_2, one, q_word_count); /* q-2 */
|
|
59888
60232
|
|
|
59889
60233
|
uint64_t r_inv_p[FIO_RSA_MAX_WORDS];
|
|
59890
60234
|
uint64_t r_inv_q[FIO_RSA_MAX_WORDS];
|
|
@@ -59904,7 +60248,7 @@ FIO_SFUNC int fio___rsa_private_op_crt(uint64_t *result_words,
|
|
|
59904
60248
|
uint64_t use_add = (uint64_t)0 - borrow;
|
|
59905
60249
|
for (size_t i = 0; i < p_word_count; ++i)
|
|
59906
60250
|
p_mask[i] = p[i] & use_add;
|
|
59907
|
-
|
|
60251
|
+
ignr_ = fio_math_add(diff, diff, p_mask, p_word_count);
|
|
59908
60252
|
fio___rsa_mul_mod(h, qInv, diff, p, p_word_count);
|
|
59909
60253
|
|
|
59910
60254
|
/* q * h mod n (zero-extend q and h to word_count) */
|
|
@@ -59920,7 +60264,7 @@ FIO_SFUNC int fio___rsa_private_op_crt(uint64_t *result_words,
|
|
|
59920
60264
|
|
|
59921
60265
|
uint64_t qh[FIO_RSA_MAX_WORDS];
|
|
59922
60266
|
fio___rsa_mul_mod(qh, q_ext, h_ext, n_words, word_count);
|
|
59923
|
-
|
|
60267
|
+
ignr_ = fio_math_add(result_words, qh, s_q_ext, word_count);
|
|
59924
60268
|
|
|
59925
60269
|
/* result may be in [0, 2*n); reduce once. */
|
|
59926
60270
|
uint64_t sub_n[FIO_RSA_MAX_WORDS];
|
|
@@ -59960,6 +60304,7 @@ FIO_SFUNC int fio___rsa_private_op_crt(uint64_t *result_words,
|
|
|
59960
60304
|
fio_secure_zero(n_words, sizeof(n_words));
|
|
59961
60305
|
|
|
59962
60306
|
return 0;
|
|
60307
|
+
(void)ignr_;
|
|
59963
60308
|
}
|
|
59964
60309
|
|
|
59965
60310
|
/**
|
|
@@ -60007,9 +60352,9 @@ FIO_SFUNC int fio___rsa_private_op(uint8_t *result,
|
|
|
60007
60352
|
fio___rsa_bytes_to_words(d_words, word_count, d, d_len);
|
|
60008
60353
|
fio___rsa_bytes_to_words(msg_words, word_count, message, msg_len);
|
|
60009
60354
|
|
|
60010
|
-
int have_crt = (key->p && key->p_len && key->q && key->q_len &&
|
|
60011
|
-
key->
|
|
60012
|
-
key->
|
|
60355
|
+
int have_crt = (key->p && key->p_len && key->q && key->q_len && key->dP &&
|
|
60356
|
+
key->dP_len && key->dQ && key->dQ_len && key->qInv &&
|
|
60357
|
+
key->qInv_len && key->e && key->e_len);
|
|
60013
60358
|
int rc = -1;
|
|
60014
60359
|
|
|
60015
60360
|
/* Verify message < modulus (constant-time). */
|
|
@@ -60022,8 +60367,11 @@ FIO_SFUNC int fio___rsa_private_op(uint8_t *result,
|
|
|
60022
60367
|
/* No CRT parameters: fall back to the plain constant-time Montgomery
|
|
60023
60368
|
* ladder. Production signing keys should supply CRT parameters so the
|
|
60024
60369
|
* CRT+blinding path above is used. */
|
|
60025
|
-
rc = fio___rsa_private_op_non_crt(
|
|
60026
|
-
|
|
60370
|
+
rc = fio___rsa_private_op_non_crt(result_words,
|
|
60371
|
+
msg_words,
|
|
60372
|
+
d_words,
|
|
60373
|
+
n_words,
|
|
60374
|
+
word_count);
|
|
60027
60375
|
}
|
|
60028
60376
|
|
|
60029
60377
|
if (rc == 0)
|
|
@@ -60186,8 +60534,12 @@ SFUNC int fio_rsa_sign_pss(uint8_t *signature,
|
|
|
60186
60534
|
|
|
60187
60535
|
/* Step 1: EMSA-PSS-ENCODE */
|
|
60188
60536
|
uint8_t em[FIO_RSA_MAX_BYTES];
|
|
60189
|
-
if (fio___rsa_emsa_pss_encode(
|
|
60190
|
-
|
|
60537
|
+
if (fio___rsa_emsa_pss_encode(em,
|
|
60538
|
+
n_len,
|
|
60539
|
+
msg_hash,
|
|
60540
|
+
hash_len,
|
|
60541
|
+
hash_alg,
|
|
60542
|
+
top_mask) != 0) {
|
|
60191
60543
|
return -1;
|
|
60192
60544
|
}
|
|
60193
60545
|
|
|
@@ -62255,6 +62607,7 @@ no memcmp, no call) after building the value once with fio___der_oid_value.
|
|
|
62255
62607
|
Generated by `bun ./ai-tools/oid-table.js c` - do not edit by hand.
|
|
62256
62608
|
***************************************************************************** */
|
|
62257
62609
|
|
|
62610
|
+
/* clang-format off */
|
|
62258
62611
|
/* Signature Algorithms */
|
|
62259
62612
|
#define FIO_X509_OID_SHA256_WITH_RSA \
|
|
62260
62613
|
((fio_u128){.u8 = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, [15] = 9}}) /* 1.2.840.113549.1.1.11 */
|
|
@@ -62331,6 +62684,8 @@ Generated by `bun ./ai-tools/oid-table.js c` - do not edit by hand.
|
|
|
62331
62684
|
#define FIO_X509_OID_ORG_UNIT \
|
|
62332
62685
|
((fio_u128){.u8 = {0x55, 0x04, 0x0B, [15] = 3}}) /* 2.5.4.11 */
|
|
62333
62686
|
|
|
62687
|
+
/* clang-format on */
|
|
62688
|
+
|
|
62334
62689
|
/* *****************************************************************************
|
|
62335
62690
|
X.509 Parser API
|
|
62336
62691
|
***************************************************************************** */
|
|
@@ -62544,9 +62899,9 @@ typedef struct {
|
|
|
62544
62899
|
int64_t not_before; /**< Validity start (Unix timestamp, 0 = now) */
|
|
62545
62900
|
int64_t not_after; /**< Validity end (Unix timestamp, 0 = +1 year) */
|
|
62546
62901
|
const fio_buf_info_s *san_dns; /**< Subject Alternative Names (DNS) */
|
|
62547
|
-
size_t san_dns_count;
|
|
62548
|
-
int is_ca;
|
|
62549
|
-
uint16_t key_usage;
|
|
62902
|
+
size_t san_dns_count; /**< Number of SAN DNS entries */
|
|
62903
|
+
int is_ca; /**< Set CA:TRUE in BasicConstraints */
|
|
62904
|
+
uint16_t key_usage; /**< Key Usage bits (0 = default for type) */
|
|
62550
62905
|
} fio_x509_cert_options_s;
|
|
62551
62906
|
|
|
62552
62907
|
/**
|
|
@@ -63244,9 +63599,7 @@ SFUNC int fio_x509_match_hostname(const fio_x509_cert_s *cert,
|
|
|
63244
63599
|
cert->san_ext.len);
|
|
63245
63600
|
/* Re-parse the SAN extension to iterate through all DNS names */
|
|
63246
63601
|
fio_der_element_s san_seq;
|
|
63247
|
-
if (fio_der_parse(&san_seq,
|
|
63248
|
-
cert->san_ext.buf,
|
|
63249
|
-
cert->san_ext.len)) {
|
|
63602
|
+
if (fio_der_parse(&san_seq, cert->san_ext.buf, cert->san_ext.len)) {
|
|
63250
63603
|
if (fio_der_is_tag(&san_seq, FIO_DER_SEQUENCE)) {
|
|
63251
63604
|
fio_der_iterator_s san_it;
|
|
63252
63605
|
fio_der_element_s gn;
|
|
@@ -63497,12 +63850,12 @@ SFUNC int fio_x509_is_trusted(const fio_x509_cert_s *cert,
|
|
|
63497
63850
|
continue;
|
|
63498
63851
|
|
|
63499
63852
|
/* Compare subject DNs (the cert's issuer should match root's subject) */
|
|
63500
|
-
if (
|
|
63853
|
+
if (FIO_UBUF_INFO_IS_EQ(cert->issuer, root.subject)) {
|
|
63501
63854
|
return 0; /* Found trusted root */
|
|
63502
63855
|
}
|
|
63503
63856
|
|
|
63504
63857
|
/* Also check if the cert itself is a trusted root */
|
|
63505
|
-
if (
|
|
63858
|
+
if (FIO_UBUF_INFO_IS_EQ(cert->subject, root.subject)) {
|
|
63506
63859
|
return 0; /* Cert is in trust store */
|
|
63507
63860
|
}
|
|
63508
63861
|
}
|
|
@@ -63533,7 +63886,7 @@ FIO_SFUNC int fio___x509_find_issuer_in_trust_store(
|
|
|
63533
63886
|
continue;
|
|
63534
63887
|
|
|
63535
63888
|
/* Check if this root's subject matches cert's issuer */
|
|
63536
|
-
if (
|
|
63889
|
+
if (FIO_UBUF_INFO_IS_EQ(cert->issuer, issuer->subject)) {
|
|
63537
63890
|
return 0; /* Found issuer */
|
|
63538
63891
|
}
|
|
63539
63892
|
}
|
|
@@ -63591,7 +63944,7 @@ SFUNC int fio_x509_verify_chain(const fio_ubuf_info_s *certs,
|
|
|
63591
63944
|
/* Verify chain signatures and issuer relationships */
|
|
63592
63945
|
for (size_t i = 0; i < cert_count - 1; ++i) {
|
|
63593
63946
|
/* Verify issuer DN of cert[i] matches subject DN of cert[i+1] */
|
|
63594
|
-
if (!
|
|
63947
|
+
if (!FIO_UBUF_INFO_IS_EQ(chain[i].issuer, chain[i + 1].subject)) {
|
|
63595
63948
|
FIO_LOG_DEBUG("X.509 chain: issuer mismatch at position %zu", i);
|
|
63596
63949
|
return FIO_X509_ERR_ISSUER_MISMATCH;
|
|
63597
63950
|
}
|
|
@@ -63600,7 +63953,7 @@ SFUNC int fio_x509_verify_chain(const fio_ubuf_info_s *certs,
|
|
|
63600
63953
|
if (!chain[i + 1].is_ca) {
|
|
63601
63954
|
/* Check if it's a self-signed root (may not have BasicConstraints) */
|
|
63602
63955
|
int is_self_signed =
|
|
63603
|
-
|
|
63956
|
+
FIO_UBUF_INFO_IS_EQ(chain[i + 1].issuer, chain[i + 1].subject);
|
|
63604
63957
|
/* Allow self-signed certs even without CA flag for compatibility */
|
|
63605
63958
|
if (!is_self_signed) {
|
|
63606
63959
|
FIO_LOG_DEBUG("X.509 chain: certificate %zu is not a CA", i + 1);
|
|
@@ -63620,7 +63973,7 @@ SFUNC int fio_x509_verify_chain(const fio_ubuf_info_s *certs,
|
|
|
63620
63973
|
|
|
63621
63974
|
/* Check if the last certificate is self-signed */
|
|
63622
63975
|
int is_self_signed =
|
|
63623
|
-
|
|
63976
|
+
FIO_UBUF_INFO_IS_EQ(chain[last].issuer, chain[last].subject);
|
|
63624
63977
|
|
|
63625
63978
|
if (is_self_signed) {
|
|
63626
63979
|
/* Self-signed: verify its own signature (well-formedness check) */
|
|
@@ -63824,8 +64177,7 @@ FIO_SFUNC size_t fio___x509_encode_name(uint8_t *buf,
|
|
|
63824
64177
|
|
|
63825
64178
|
/* Organizational Unit (OU) */
|
|
63826
64179
|
if (opts->ou.len)
|
|
63827
|
-
content_len +=
|
|
63828
|
-
fio___x509_encode_rdn(NULL, FIO_X509_OID_ORG_UNIT, opts->ou);
|
|
64180
|
+
content_len += fio___x509_encode_rdn(NULL, FIO_X509_OID_ORG_UNIT, opts->ou);
|
|
63829
64181
|
|
|
63830
64182
|
/* Common Name (CN) - required */
|
|
63831
64183
|
content_len +=
|
|
@@ -63943,8 +64295,7 @@ FIO_SFUNC size_t fio___x509_encode_ext_basic_constraints(uint8_t *buf,
|
|
|
63943
64295
|
int is_ca) {
|
|
63944
64296
|
/* BasicConstraints ::= SEQUENCE { cA BOOLEAN DEFAULT FALSE } */
|
|
63945
64297
|
size_t bc_content = is_ca ? fio_der_encode_boolean(NULL, 1) : 0;
|
|
63946
|
-
size_t bc_len =
|
|
63947
|
-
fio_der_encode_sequence_header(NULL, bc_content) + bc_content;
|
|
64298
|
+
size_t bc_len = fio_der_encode_sequence_header(NULL, bc_content) + bc_content;
|
|
63948
64299
|
|
|
63949
64300
|
/* Wrap in OCTET STRING */
|
|
63950
64301
|
size_t octet_len = fio_der_encode_octet_string(NULL, NULL, bc_len);
|
|
@@ -64073,8 +64424,7 @@ FIO_SFUNC size_t fio___x509_encode_ext_san(uint8_t *buf,
|
|
|
64073
64424
|
offset += fio___der_encode_oid(buf + offset, FIO_X509_OID_SUBJECT_ALT_NAME);
|
|
64074
64425
|
|
|
64075
64426
|
/* OCTET STRING containing SAN */
|
|
64076
|
-
size_t octet_hdr =
|
|
64077
|
-
fio_der_encode_octet_string(buf + offset, NULL, san_len);
|
|
64427
|
+
size_t octet_hdr = fio_der_encode_octet_string(buf + offset, NULL, san_len);
|
|
64078
64428
|
uint8_t *san_buf = buf + offset + octet_hdr - san_len;
|
|
64079
64429
|
size_t san_off = 0;
|
|
64080
64430
|
san_off += fio_der_encode_sequence_header(san_buf + san_off, san_content);
|
|
@@ -64125,8 +64475,7 @@ FIO_SFUNC size_t fio___x509_encode_ext_eku(uint8_t *buf, int is_ca) {
|
|
|
64125
64475
|
offset += fio___der_encode_oid(buf + offset, FIO_X509_OID_EXT_KEY_USAGE);
|
|
64126
64476
|
|
|
64127
64477
|
/* OCTET STRING containing EKU SEQUENCE */
|
|
64128
|
-
size_t octet_hdr =
|
|
64129
|
-
fio_der_encode_octet_string(buf + offset, NULL, eku_len);
|
|
64478
|
+
size_t octet_hdr = fio_der_encode_octet_string(buf + offset, NULL, eku_len);
|
|
64130
64479
|
uint8_t *eku_buf = buf + offset + octet_hdr - eku_len;
|
|
64131
64480
|
size_t eku_off = 0;
|
|
64132
64481
|
eku_off += fio_der_encode_sequence_header(eku_buf + eku_off, eku_content);
|
|
@@ -64182,8 +64531,7 @@ fio___x509_encode_extensions(uint8_t *buf,
|
|
|
64182
64531
|
fio_der_encode_sequence_header(NULL, ext_content) + ext_content;
|
|
64183
64532
|
|
|
64184
64533
|
/* Wrap in context tag [3] */
|
|
64185
|
-
size_t total =
|
|
64186
|
-
fio_der_encode_context_header(NULL, 3, exts_len, 1) + exts_len;
|
|
64534
|
+
size_t total = fio_der_encode_context_header(NULL, 3, exts_len, 1) + exts_len;
|
|
64187
64535
|
|
|
64188
64536
|
if (buf) {
|
|
64189
64537
|
size_t offset = 0;
|
|
@@ -64205,8 +64553,8 @@ fio___x509_encode_extensions(uint8_t *buf,
|
|
|
64205
64553
|
}
|
|
64206
64554
|
|
|
64207
64555
|
/** Helper: encode AlgorithmIdentifier for signature */
|
|
64208
|
-
FIO_SFUNC size_t
|
|
64209
|
-
|
|
64556
|
+
FIO_SFUNC size_t
|
|
64557
|
+
fio___x509_encode_signature_algo(uint8_t *buf, fio_x509_keypair_type_e type) {
|
|
64210
64558
|
fio_u128 oid;
|
|
64211
64559
|
int has_params;
|
|
64212
64560
|
|
|
@@ -64277,7 +64625,8 @@ SFUNC size_t fio_x509_self_signed_cert(uint8_t *buf,
|
|
|
64277
64625
|
tbs_content += serial_len;
|
|
64278
64626
|
|
|
64279
64627
|
/* Signature algorithm */
|
|
64280
|
-
size_t signature_algo_len =
|
|
64628
|
+
size_t signature_algo_len =
|
|
64629
|
+
fio___x509_encode_signature_algo(NULL, keypair->type);
|
|
64281
64630
|
tbs_content += signature_algo_len;
|
|
64282
64631
|
|
|
64283
64632
|
/* Issuer (same as subject for self-signed) */
|
|
@@ -64314,7 +64663,8 @@ SFUNC size_t fio_x509_self_signed_cert(uint8_t *buf,
|
|
|
64314
64663
|
fio_der_encode_sequence_header(NULL, tbs_content) + tbs_content;
|
|
64315
64664
|
|
|
64316
64665
|
/* Signature algorithm (again, in outer Certificate) */
|
|
64317
|
-
size_t outer_signature_algo_len =
|
|
64666
|
+
size_t outer_signature_algo_len =
|
|
64667
|
+
fio___x509_encode_signature_algo(NULL, keypair->type);
|
|
64318
64668
|
|
|
64319
64669
|
/* Signature value (BIT STRING) */
|
|
64320
64670
|
size_t sig_value_len;
|
|
@@ -64357,8 +64707,7 @@ SFUNC size_t fio_x509_self_signed_cert(uint8_t *buf,
|
|
|
64357
64707
|
|
|
64358
64708
|
/* We need to encode TBS first to sign it, but we don't know the final
|
|
64359
64709
|
* certificate length yet. Encode TBS to a temporary location. */
|
|
64360
|
-
uint8_t *tbs_start =
|
|
64361
|
-
buf + fio_der_encode_sequence_header(NULL, cert_content);
|
|
64710
|
+
uint8_t *tbs_start = buf + fio_der_encode_sequence_header(NULL, cert_content);
|
|
64362
64711
|
|
|
64363
64712
|
/* Encode TBSCertificate */
|
|
64364
64713
|
size_t tbs_offset = 0;
|
|
@@ -108861,6 +109210,32 @@ SFUNC void fio_ipc_cluster_connect(const char *url);
|
|
|
108861
109210
|
* */
|
|
108862
109211
|
SFUNC uint16_t fio_ipc_cluster_port(void);
|
|
108863
109212
|
|
|
109213
|
+
/* At most 32 independent lifecycle subscriptions per process. */
|
|
109214
|
+
#define FIO_IPC_CLUSTER_PEER_MAX_SUBSCRIBERS 32
|
|
109215
|
+
|
|
109216
|
+
/** Lifecycle events are synthetic, reference-counted fio_ipc_s objects.
|
|
109217
|
+
* data[0..15] contains the peer UUID in UDP-discovery byte order. The
|
|
109218
|
+
* attached event owns a reference to the peer IO in event->from; the detached
|
|
109219
|
+
* event has from == NULL. Never reply to or send an event itself. Instead,
|
|
109220
|
+
* author a normal opcode message and fio_ipc_send_to(event->from, message)
|
|
109221
|
+
* during on_attached. Callbacks borrow each event; fio_ipc_dup retains it.
|
|
109222
|
+
* Retaining attached events may delay on_detached until their IO is freed.
|
|
109223
|
+
* udata is borrowed and must outlive all callbacks using it.
|
|
109224
|
+
*/
|
|
109225
|
+
typedef struct fio_ipc_cluster_on_peer_s {
|
|
109226
|
+
void (*on_attached)(fio_ipc_s *event); /* optional */
|
|
109227
|
+
void (*on_detached)(fio_ipc_s *event); /* optional */
|
|
109228
|
+
void *udata; /* callback context; borrowed */
|
|
109229
|
+
} fio_ipc_cluster_on_peer_s;
|
|
109230
|
+
|
|
109231
|
+
/** Append a subscriber on the master before fio_io_start. At least one
|
|
109232
|
+
* callback is required. Returns 0 on success, -1 for invalid callbacks,
|
|
109233
|
+
* worker/running IO, or exhausted capacity. No partial registration occurs.
|
|
109234
|
+
*/
|
|
109235
|
+
SFUNC int fio_ipc_cluster_on_peer(fio_ipc_cluster_on_peer_s args);
|
|
109236
|
+
#define fio_ipc_cluster_on_peer(...) \
|
|
109237
|
+
fio_ipc_cluster_on_peer((fio_ipc_cluster_on_peer_s){__VA_ARGS__})
|
|
109238
|
+
|
|
108864
109239
|
/* *****************************************************************************
|
|
108865
109240
|
IPC Flags - Used for message routing, settable in routing_flags
|
|
108866
109241
|
|
|
@@ -109027,6 +109402,8 @@ static struct {
|
|
|
109027
109402
|
fio___ipc_cluster_filter_s received; /* messages recently received */
|
|
109028
109403
|
fio___ipc_cluster_filter_s peers; /* connected peers */
|
|
109029
109404
|
fio_u128 uuid; /* instance ID peers */
|
|
109405
|
+
fio_ipc_cluster_on_peer_s on_peer[FIO_IPC_CLUSTER_PEER_MAX_SUBSCRIBERS];
|
|
109406
|
+
size_t on_peer_count;
|
|
109030
109407
|
uint16_t cluster_port; /* last port number in cluster_listen */
|
|
109031
109408
|
char ipc_url[FIO_IPC_URL_MAX_LENGTH]; /* IPC socket path */
|
|
109032
109409
|
} FIO___IPC;
|
|
@@ -109556,11 +109933,12 @@ typedef struct {
|
|
|
109556
109933
|
char buffer[]; /* FIO_IPC_BUFFER_LEN for small messages */
|
|
109557
109934
|
} fio___ipc_parser_s;
|
|
109558
109935
|
|
|
109559
|
-
|
|
109560
|
-
|
|
109936
|
+
/* The IO buffer need not have fio_u128's 16-byte alignment. */
|
|
109937
|
+
FIO_IFUNC uint8_t *fio___ipc_cluster_uuid(fio_io_s *io) {
|
|
109938
|
+
return (uint8_t *)fio_io_buffer(io);
|
|
109561
109939
|
}
|
|
109562
109940
|
FIO_IFUNC fio___ipc_parser_s *fio___ipc_cluster_parser(fio_io_s *io) {
|
|
109563
|
-
return (fio___ipc_parser_s *)(fio___ipc_cluster_uuid(io) +
|
|
109941
|
+
return (fio___ipc_parser_s *)(fio___ipc_cluster_uuid(io) + 16);
|
|
109564
109942
|
}
|
|
109565
109943
|
|
|
109566
109944
|
/** Get parser from IO buffer */
|
|
@@ -109721,30 +110099,70 @@ decrypt_error:
|
|
|
109721
110099
|
fio___ipc_free(ipc);
|
|
109722
110100
|
}
|
|
109723
110101
|
|
|
110102
|
+
/* Allocate a separate borrowed event per subscriber: retaining one event
|
|
110103
|
+
* must not change another subscriber's callback context or ownership. */
|
|
110104
|
+
FIO_SFUNC void fio___ipc_lifecycle_emit(fio_io_s *io,
|
|
110105
|
+
const fio_u128 *uuid,
|
|
110106
|
+
bool attached) {
|
|
110107
|
+
if (!fio_io_is_master())
|
|
110108
|
+
return;
|
|
110109
|
+
for (size_t i = 0; i < FIO___IPC.on_peer_count; ++i) {
|
|
110110
|
+
const fio_ipc_cluster_on_peer_s *sub = &FIO___IPC.on_peer[i];
|
|
110111
|
+
void (*fn)(fio_ipc_s *) = attached ? sub->on_attached : sub->on_detached;
|
|
110112
|
+
if (!fn)
|
|
110113
|
+
continue;
|
|
110114
|
+
fio_ipc_s *event =
|
|
110115
|
+
fio_ipc_new(.data = FIO_IPC_DATA(FIO_BUF_INFO2((char *)uuid->u8, 16)));
|
|
110116
|
+
if (!event) {
|
|
110117
|
+
FIO_LOG_ERROR("(%d) couldn't allocate IPC peer lifecycle event",
|
|
110118
|
+
fio_io_pid());
|
|
110119
|
+
continue;
|
|
110120
|
+
}
|
|
110121
|
+
event->from = attached ? fio_io_dup(io) : NULL;
|
|
110122
|
+
event->udata = sub->udata;
|
|
110123
|
+
fn(event);
|
|
110124
|
+
fio_ipc_free(event);
|
|
110125
|
+
}
|
|
110126
|
+
}
|
|
110127
|
+
|
|
110128
|
+
void fio_ipc_cluster_on_peer___(void); /* IDE marker */
|
|
110129
|
+
SFUNC int fio_ipc_cluster_on_peer FIO_NOOP(fio_ipc_cluster_on_peer_s args) {
|
|
110130
|
+
if (!fio_io_is_master() || fio_io_is_running() ||
|
|
110131
|
+
(!args.on_attached && !args.on_detached) ||
|
|
110132
|
+
FIO___IPC.on_peer_count >= FIO_IPC_CLUSTER_PEER_MAX_SUBSCRIBERS)
|
|
110133
|
+
return -1;
|
|
110134
|
+
FIO___IPC.on_peer[FIO___IPC.on_peer_count++] = args;
|
|
110135
|
+
return 0;
|
|
110136
|
+
}
|
|
110137
|
+
|
|
109724
110138
|
/** Wrapper that manages request vs response states */
|
|
110139
|
+
|
|
109725
110140
|
FIO_SFUNC void fio___ipc_on_rpc_master(void *ipc_, void *io_) {
|
|
109726
110141
|
fio_ipc_s *ipc = (fio_ipc_s *)ipc_;
|
|
109727
110142
|
ipc->from = io_;
|
|
109728
|
-
|
|
110143
|
+
uint8_t *uuid = fio___ipc_cluster_uuid(io_);
|
|
109729
110144
|
fio_u128 peer_uuid = {0};
|
|
110145
|
+
fio_u128 old_uuid;
|
|
110146
|
+
fio_memcpy16(old_uuid.u8, uuid);
|
|
109730
110147
|
|
|
109731
110148
|
if (fio_ipc_decrypt(ipc))
|
|
109732
110149
|
goto peer_error;
|
|
109733
|
-
/* Handle internal ping/pong for cluster connections */
|
|
109734
|
-
if (fio___ipc_handle_ping(ipc, fio___ipc_cluster_parser(io_)))
|
|
109735
|
-
return;
|
|
109736
110150
|
if (!FIO_IPC_FLAG_TEST(ipc, FIO_IPC_FLAG_CLUSTER) ||
|
|
109737
110151
|
!FIO_IPC_FLAG_TEST(ipc, FIO_IPC_FLAG_OPCODE))
|
|
109738
110152
|
goto peer_error;
|
|
109739
|
-
|
|
110153
|
+
/* Nothing, not even a ping, is dispatched before a validated handshake. */
|
|
110154
|
+
if (ipc->opcode == (uint32_t)0xFFFFFFFF)
|
|
110155
|
+
goto uuid_msg;
|
|
110156
|
+
if (!old_uuid.u64[0] && !old_uuid.u64[1])
|
|
110157
|
+
goto peer_error;
|
|
109740
110158
|
if (fio___ipc_cluster_filter_window(fio_ltole64(ipc->timestamp)) ||
|
|
109741
110159
|
fio___ipc_cluster_filter(&FIO___IPC.received,
|
|
109742
110160
|
fio_ltole64(ipc->timestamp),
|
|
109743
110161
|
ipc->id))
|
|
109744
110162
|
goto filtered;
|
|
109745
|
-
|
|
109746
|
-
if (ipc
|
|
109747
|
-
|
|
110163
|
+
/* Handle internal ping/pong for established cluster connections. */
|
|
110164
|
+
if (fio___ipc_handle_ping(ipc, fio___ipc_cluster_parser(io_)))
|
|
110165
|
+
return;
|
|
109748
110166
|
|
|
109749
110167
|
if (FIO_IPC_FLAG_TEST(ipc, FIO_IPC_FLAG_WORKERS)) {
|
|
109750
110168
|
fio_ipc_send(ipc);
|
|
@@ -109754,8 +110172,15 @@ FIO_SFUNC void fio___ipc_on_rpc_master(void *ipc_, void *io_) {
|
|
|
109754
110172
|
return;
|
|
109755
110173
|
|
|
109756
110174
|
uuid_msg:
|
|
109757
|
-
if (
|
|
109758
|
-
|
|
110175
|
+
if (old_uuid.u64[0] || old_uuid.u64[1] || ipc->len ||
|
|
110176
|
+
FIO_IPC_FLAG_TEST(ipc, FIO_IPC_FLAG_REPLY) ||
|
|
110177
|
+
FIO_IPC_FLAG_TEST(ipc, FIO_IPC_FLAG_PING))
|
|
110178
|
+
goto peer_error;
|
|
110179
|
+
if (fio___ipc_cluster_filter_window(fio_ltole64(ipc->timestamp)) ||
|
|
110180
|
+
fio___ipc_cluster_filter(&FIO___IPC.received,
|
|
110181
|
+
fio_ltole64(ipc->timestamp),
|
|
110182
|
+
ipc->id))
|
|
110183
|
+
goto filtered;
|
|
109759
110184
|
if (sizeof(ipc->on_reply) >= 8) {
|
|
109760
110185
|
fio_memcpy8(&peer_uuid, (char *)(void *)(&ipc->on_reply));
|
|
109761
110186
|
fio_memcpy8(&peer_uuid.u8[8], (char *)(void *)(&ipc->on_done));
|
|
@@ -109763,13 +110188,18 @@ uuid_msg:
|
|
|
109763
110188
|
fio_memcpy4(&peer_uuid, (char *)(void *)(&ipc->on_reply));
|
|
109764
110189
|
fio_memcpy4(&peer_uuid.u8[4], (char *)(void *)(&ipc->on_done));
|
|
109765
110190
|
}
|
|
110191
|
+
/* Reject self, zero and duplicate identities before announcing this peer. */
|
|
110192
|
+
if (!peer_uuid.u64[0] || !peer_uuid.u64[1] ||
|
|
110193
|
+
FIO_MEMCMP(peer_uuid.u8, FIO___IPC.uuid.u8, 16) == 0)
|
|
110194
|
+
goto peer_error;
|
|
109766
110195
|
/* test if we already connected to peer previously */
|
|
109767
110196
|
if (fio___ipc_cluster_filter(&FIO___IPC.peers,
|
|
109768
110197
|
peer_uuid.u64[0],
|
|
109769
110198
|
peer_uuid.u64[1]))
|
|
109770
110199
|
goto peer_error;
|
|
109771
110200
|
/* set peer uuid */
|
|
109772
|
-
|
|
110201
|
+
fio_memcpy16(uuid, peer_uuid.u8);
|
|
110202
|
+
fio___ipc_lifecycle_emit(io_, &peer_uuid, true);
|
|
109773
110203
|
fio___ipc_free(ipc);
|
|
109774
110204
|
return;
|
|
109775
110205
|
peer_error:
|
|
@@ -110101,12 +110531,12 @@ FIO_SFUNC void fio___ipc_udp_broadcast_task_done(void *io_, void *ignr_) {
|
|
|
110101
110531
|
FIO_SFUNC void fio___ipc_udp_on_attach(fio_io_s *io) {
|
|
110102
110532
|
/* Send initial broadcast */
|
|
110103
110533
|
fio___ipc_udp_broadcast_hello(io);
|
|
110104
|
-
/* Schedule periodic broadcasts (every
|
|
110534
|
+
/* Schedule periodic broadcasts (every 4-5 seconds with jitter) */
|
|
110105
110535
|
fio_io_run_every(.fn = fio___ipc_udp_broadcast_task,
|
|
110106
110536
|
.udata1 = fio_io_dup(io),
|
|
110107
|
-
.every = (uint32_t)(
|
|
110537
|
+
.every = (uint32_t)(4096 | (1023 & FIO___IPC.uuid.u64[0])),
|
|
110108
110538
|
.on_finish = fio___ipc_udp_broadcast_task_done,
|
|
110109
|
-
.repetitions =
|
|
110539
|
+
.repetitions = -1); /* Repeat indefinitely */
|
|
110110
110540
|
}
|
|
110111
110541
|
|
|
110112
110542
|
/** Called when UDP socket is closed */
|
|
@@ -110247,7 +110677,7 @@ FIO_ASSERT_STATIC((sizeof(void (*)(void *)) >= 4),
|
|
|
110247
110677
|
"function pointers MUST be 4 bytes or more");
|
|
110248
110678
|
SFUNC void fio___ipc_on_attach_cluster(fio_io_s *io) {
|
|
110249
110679
|
/* set peer UUID to zero and initialize parser */
|
|
110250
|
-
|
|
110680
|
+
FIO_MEMSET(fio___ipc_cluster_uuid(io), 0, 16);
|
|
110251
110681
|
fio___ipc_parser_init(fio___ipc_cluster_parser(io));
|
|
110252
110682
|
/* inform peer about our UUID */
|
|
110253
110683
|
fio_ipc_s *ipc = fio_ipc_new(0);
|
|
@@ -110268,13 +110698,16 @@ SFUNC void fio___ipc_on_attach_cluster(fio_io_s *io) {
|
|
|
110268
110698
|
|
|
110269
110699
|
/** Called when IPC socket is closed */
|
|
110270
110700
|
FIO_SFUNC void fio___ipc_on_close_cluster(void *buffer, void *udata) {
|
|
110271
|
-
fio___ipc_parser_s *p =
|
|
110272
|
-
(fio___ipc_parser_s *)((char *)buffer + sizeof(fio_u128));
|
|
110701
|
+
fio___ipc_parser_s *p = (fio___ipc_parser_s *)((char *)buffer + 16);
|
|
110273
110702
|
fio___ipc_parser_destroy(p);
|
|
110274
|
-
|
|
110275
|
-
|
|
110276
|
-
|
|
110277
|
-
|
|
110703
|
+
fio_u128 uuid;
|
|
110704
|
+
fio_memcpy16(uuid.u8, buffer);
|
|
110705
|
+
if (fio_io_is_master() && uuid.u64[0] && uuid.u64[1]) {
|
|
110706
|
+
fio___ipc_cluster_filter_remove(
|
|
110707
|
+
&FIO___IPC.peers,
|
|
110708
|
+
(fio___ipc_msg_id_s){uuid.u64[0], uuid.u64[1]});
|
|
110709
|
+
fio___ipc_lifecycle_emit(NULL, &uuid, false);
|
|
110710
|
+
}
|
|
110278
110711
|
(void)udata;
|
|
110279
110712
|
}
|
|
110280
110713
|
|
|
@@ -110374,6 +110807,8 @@ FIO_SFUNC void fio___ipc_destroy(void *ignr_) {
|
|
|
110374
110807
|
fio___ipc_cluster_filter_destroy(&FIO___IPC.received);
|
|
110375
110808
|
fio___ipc_cluster_filter_destroy(&FIO___IPC.peers);
|
|
110376
110809
|
fio___ipc_cluster_ops_destroy(&FIO___IPC.opcodes);
|
|
110810
|
+
FIO_MEMSET(FIO___IPC.on_peer, 0, sizeof(FIO___IPC.on_peer));
|
|
110811
|
+
FIO___IPC.on_peer_count = 0;
|
|
110377
110812
|
(void)ignr_;
|
|
110378
110813
|
}
|
|
110379
110814
|
|
|
@@ -110383,6 +110818,9 @@ FIO_SFUNC void fio___ipc_on_fork(void *ignr_) {
|
|
|
110383
110818
|
/* Cleanup master's resources - except opcodes (clients may use) */
|
|
110384
110819
|
fio___ipc_cluster_filter_destroy(&FIO___IPC.received);
|
|
110385
110820
|
fio___ipc_cluster_filter_destroy(&FIO___IPC.peers);
|
|
110821
|
+
/* Child never owns master's lifecycle subscriptions or their udata. */
|
|
110822
|
+
FIO_MEMSET(FIO___IPC.on_peer, 0, sizeof(FIO___IPC.on_peer));
|
|
110823
|
+
FIO___IPC.on_peer_count = 0;
|
|
110386
110824
|
|
|
110387
110825
|
FIO___IPC.protocol_ipc.on_data = fio___ipc_on_data_worker;
|
|
110388
110826
|
FIO___IPC.protocol_ipc.on_shutdown = fio___ipc_on_shutdown_worker;
|
|
@@ -110419,13 +110857,14 @@ FIO_CONSTRUCTOR(fio___ipc_init) {
|
|
|
110419
110857
|
.on_data = fio___ipc_on_data_cluster,
|
|
110420
110858
|
.on_close = fio___ipc_on_close_cluster,
|
|
110421
110859
|
.on_timeout = fio___ipc_on_timeout_rpc,
|
|
110422
|
-
.buffer_size =
|
|
110423
|
-
sizeof(fio_u128) + sizeof(fio___ipc_parser_s) + FIO_IPC_BUFFER_LEN,
|
|
110860
|
+
.buffer_size = 16 + sizeof(fio___ipc_parser_s) + FIO_IPC_BUFFER_LEN,
|
|
110424
110861
|
.timeout = (55 * 1024), /* RPC (remote) timeout: ~55 sec */
|
|
110425
110862
|
};
|
|
110426
110863
|
fio_io_protocol_set(NULL, &FIO___IPC.protocol_ipc); /* initialize - safety */
|
|
110427
110864
|
fio_io_protocol_set(NULL, &FIO___IPC.protocol_rpc); /* initialize - safety */
|
|
110428
|
-
|
|
110865
|
+
do {
|
|
110866
|
+
FIO___IPC.uuid = fio_rand128();
|
|
110867
|
+
} while (!FIO___IPC.uuid.u64[0] || !FIO___IPC.uuid.u64[1]);
|
|
110429
110868
|
fio_ipc_url_set(NULL);
|
|
110430
110869
|
fio_state_callback_add(FIO_CALL_BEFORE_FORK, fio___ipc_listen, NULL);
|
|
110431
110870
|
fio_state_callback_add(FIO_CALL_IN_CHILD, fio___ipc_on_fork, NULL);
|
|
@@ -110784,7 +111223,7 @@ static X509 *fio_io_tls_create_self_signed(const char *server_name) {
|
|
|
110784
111223
|
}
|
|
110785
111224
|
|
|
110786
111225
|
/* Set subject name with Organization and Common Name */
|
|
110787
|
-
name = X509_get_subject_name(cert);
|
|
111226
|
+
name = (X509_NAME *)X509_get_subject_name(cert);
|
|
110788
111227
|
if (!name) {
|
|
110789
111228
|
FIO_LOG_ERROR("OpenSSL: X509_get_subject_name failed");
|
|
110790
111229
|
goto error;
|
|
@@ -118851,6 +119290,7 @@ HTTP Handle Settings
|
|
|
118851
119290
|
#endif
|
|
118852
119291
|
|
|
118853
119292
|
#ifndef FIO_HTTP_LOG_X_REQUEST_START
|
|
119293
|
+
/** Logs request wait time using x-request-start header */
|
|
118854
119294
|
#define FIO_HTTP_LOG_X_REQUEST_START 1
|
|
118855
119295
|
#endif
|
|
118856
119296
|
|
|
@@ -119041,11 +119481,12 @@ typedef struct fio_http_settings_s {
|
|
|
119041
119481
|
* recommended.
|
|
119042
119482
|
*
|
|
119043
119483
|
* Note: per-route (read from the matching route's settings; routes
|
|
119044
|
-
* inherit the listener's root value at route-creation).
|
|
119045
|
-
*
|
|
119046
|
-
*
|
|
119047
|
-
*
|
|
119048
|
-
*
|
|
119484
|
+
* inherit the listener's root value at route-creation). Handles without
|
|
119485
|
+
* settings (created with `fio_http_new`) never create variants.
|
|
119486
|
+
*
|
|
119487
|
+
* Note: on-demand creation disables itself (the value drops to 0) after
|
|
119488
|
+
* repeated failures or a filesystem-full / permission error, until the
|
|
119489
|
+
* settings are re-applied.
|
|
119049
119490
|
*/
|
|
119050
119491
|
uint8_t compress_static;
|
|
119051
119492
|
/**
|
|
@@ -119294,7 +119735,7 @@ FIO_IFUNC void *fio_http_udata2_set(fio_http_s *, void *);
|
|
|
119294
119735
|
/** Gets the HTTP Controller associated with the HTTP handle. */
|
|
119295
119736
|
FIO_IFUNC fio_http_controller_s *fio_http_controller(fio_http_s *h);
|
|
119296
119737
|
|
|
119297
|
-
/**
|
|
119738
|
+
/** Sets the HTTP Controller associated with the HTTP handle. */
|
|
119298
119739
|
FIO_IFUNC fio_http_controller_s *fio_http_controller_set(
|
|
119299
119740
|
fio_http_s *h,
|
|
119300
119741
|
fio_http_controller_s *controller);
|
|
@@ -119318,6 +119759,43 @@ SFUNC size_t fio_http_status_set(fio_http_s *, size_t status);
|
|
|
119318
119759
|
/** Gets the method information associated with the HTTP handle. */
|
|
119319
119760
|
SFUNC fio_str_info_s fio_http_method(fio_http_s *);
|
|
119320
119761
|
|
|
119762
|
+
/** Tests for GET, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119763
|
+
SFUNC int fio_http_method_is_get(fio_http_s *h);
|
|
119764
|
+
/** Tests for HEAD, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119765
|
+
SFUNC int fio_http_method_is_head(fio_http_s *h);
|
|
119766
|
+
/** Tests for POST, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119767
|
+
SFUNC int fio_http_method_is_post(fio_http_s *h);
|
|
119768
|
+
/** Tests for PUT, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119769
|
+
SFUNC int fio_http_method_is_put(fio_http_s *h);
|
|
119770
|
+
/** Tests for DELETE, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119771
|
+
SFUNC int fio_http_method_is_delete(fio_http_s *h);
|
|
119772
|
+
/** Tests for CONNECT, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119773
|
+
SFUNC int fio_http_method_is_connect(fio_http_s *h);
|
|
119774
|
+
/** Tests for OPTIONS, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119775
|
+
SFUNC int fio_http_method_is_options(fio_http_s *h);
|
|
119776
|
+
/** Tests for TRACE, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119777
|
+
SFUNC int fio_http_method_is_trace(fio_http_s *h);
|
|
119778
|
+
/** Tests for PATCH, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119779
|
+
SFUNC int fio_http_method_is_patch(fio_http_s *h);
|
|
119780
|
+
/** Tests for QUERY, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119781
|
+
SFUNC int fio_http_method_is_query(fio_http_s *h);
|
|
119782
|
+
/** Tests for PROPFIND, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119783
|
+
SFUNC int fio_http_method_is_propfind(fio_http_s *h);
|
|
119784
|
+
/** Tests for PROPPATCH, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119785
|
+
SFUNC int fio_http_method_is_proppatch(fio_http_s *h);
|
|
119786
|
+
/** Tests for MKCOL, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119787
|
+
SFUNC int fio_http_method_is_mkcol(fio_http_s *h);
|
|
119788
|
+
/** Tests for COPY, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119789
|
+
SFUNC int fio_http_method_is_copy(fio_http_s *h);
|
|
119790
|
+
/** Tests for MOVE, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119791
|
+
SFUNC int fio_http_method_is_move(fio_http_s *h);
|
|
119792
|
+
/** Tests for LOCK, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119793
|
+
SFUNC int fio_http_method_is_lock(fio_http_s *h);
|
|
119794
|
+
/** Tests for UNLOCK, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119795
|
+
SFUNC int fio_http_method_is_unlock(fio_http_s *h);
|
|
119796
|
+
/** Tests for SEARCH, case-insensitively; requires a non-NULL HTTP handle. */
|
|
119797
|
+
SFUNC int fio_http_method_is_search(fio_http_s *h);
|
|
119798
|
+
|
|
119321
119799
|
/** Sets the method information associated with the HTTP handle. */
|
|
119322
119800
|
SFUNC fio_str_info_s fio_http_method_set(fio_http_s *, fio_str_info_s);
|
|
119323
119801
|
|
|
@@ -119908,9 +120386,8 @@ SFUNC int fio_http_etag_is_match(fio_http_s *h);
|
|
|
119908
120386
|
*
|
|
119909
120387
|
* Pre-compressed variants (`file.br`, `file.zstd`, `file.gz`, `file.zip`,
|
|
119910
120388
|
* in this preference order) are served when accepted by the client,
|
|
119911
|
-
* present on disk, and fresh; with `compress_static` enabled
|
|
119912
|
-
* route's settings,
|
|
119913
|
-
* detached handles), missing `.br` / `.gz` variants are also created on
|
|
120389
|
+
* present on disk, and fresh; with `compress_static` enabled in the matching
|
|
120390
|
+
* route's settings, missing `.br` / `.gz` variants are also created on
|
|
119914
120391
|
* demand.
|
|
119915
120392
|
*
|
|
119916
120393
|
* On success the response is complete and 0 is returned. On failure -1 is
|
|
@@ -119952,7 +120429,7 @@ The HTTP Controller
|
|
|
119952
120429
|
* order for HTTP responses and requests to be sent.
|
|
119953
120430
|
*/
|
|
119954
120431
|
struct fio_http_controller_s {
|
|
119955
|
-
|
|
120432
|
+
/** Reserved. MUST be initialized to zero. */
|
|
119956
120433
|
uintptr_t private_flags;
|
|
119957
120434
|
/** Called when an HTTP handle is freed. */
|
|
119958
120435
|
void (*on_destroyed)(fio_http_s *h);
|
|
@@ -119996,23 +120473,6 @@ SFUNC void fio_http_upgrade_sse(fio_http_s *);
|
|
|
119996
120473
|
/** Sets request data to request an EventSource (SSE) Upgrade.*/
|
|
119997
120474
|
SFUNC void fio_http_sse_set_request(fio_http_s *);
|
|
119998
120475
|
|
|
119999
|
-
/* *****************************************************************************
|
|
120000
|
-
HTTP Handle State and Controller Flags
|
|
120001
|
-
***************************************************************************** */
|
|
120002
|
-
|
|
120003
|
-
#define FIO_HTTP_STATE_STREAMING 1
|
|
120004
|
-
#define FIO_HTTP_STATE_FINISHED 2
|
|
120005
|
-
#define FIO_HTTP_STATE_UPGRADED 4
|
|
120006
|
-
#define FIO_HTTP_STATE_WEBSOCKET 8
|
|
120007
|
-
#define FIO_HTTP_STATE_SSE 16
|
|
120008
|
-
#define FIO_HTTP_STATE_COOKIES_PARSED 32
|
|
120009
|
-
#define FIO_HTTP_STATE_FREEING 64
|
|
120010
|
-
|
|
120011
|
-
/** Controller flags (cflags) for opt-in compression features. */
|
|
120012
|
-
#define FIO_HTTP_CFLAG_COMPRESS_DYNAMIC 1
|
|
120013
|
-
#define FIO_HTTP_CFLAG_COMPRESS_WS 2
|
|
120014
|
-
#define FIO_HTTP_CFLAG_COMPRESS_STATIC 4
|
|
120015
|
-
|
|
120016
120476
|
/* *****************************************************************************
|
|
120017
120477
|
WebSocket Helpers - HTTP Upgraded Connections
|
|
120018
120478
|
***************************************************************************** */
|
|
@@ -120072,6 +120532,24 @@ HTTP Settings Resolver
|
|
|
120072
120532
|
SFUNC fio_http_settings_s *fio_http_settings(fio_http_s *);
|
|
120073
120533
|
|
|
120074
120534
|
/* *****************************************************************************
|
|
120535
|
+
|
|
120536
|
+
|
|
120537
|
+
|
|
120538
|
+
|
|
120539
|
+
|
|
120540
|
+
|
|
120541
|
+
|
|
120542
|
+
Inline / Macro Implementations
|
|
120543
|
+
|
|
120544
|
+
|
|
120545
|
+
|
|
120546
|
+
|
|
120547
|
+
|
|
120548
|
+
|
|
120549
|
+
|
|
120550
|
+
***************************************************************************** */
|
|
120551
|
+
|
|
120552
|
+
/* *****************************************************************************
|
|
120075
120553
|
Header Value / Property Iterator - Inline Implementation
|
|
120076
120554
|
***************************************************************************** */
|
|
120077
120555
|
|
|
@@ -120239,47 +120717,16 @@ fio_http_header_each_property_first(const fio_buf_info_s *properties) {
|
|
|
120239
120717
|
return pos;
|
|
120240
120718
|
}
|
|
120241
120719
|
|
|
120242
|
-
/* *****************************************************************************
|
|
120243
|
-
HTTP API Finish
|
|
120244
|
-
***************************************************************************** */
|
|
120245
|
-
#endif /* FIO_HTTP */
|
|
120246
|
-
/* ************************************************************************* */
|
|
120247
|
-
#if !defined(FIO_INCLUDE_FILE) /* Dev test - ignore line */
|
|
120248
|
-
#define FIO___DEV___ /* Development inclusion - ignore line */
|
|
120249
|
-
#define FIO_HTTP /* Development inclusion - ignore line */
|
|
120250
|
-
#include "./include.h" /* Development inclusion - ignore line */
|
|
120251
|
-
#endif /* Development inclusion - ignore line */
|
|
120252
|
-
/* *****************************************************************************
|
|
120253
|
-
|
|
120254
|
-
|
|
120255
|
-
|
|
120256
|
-
|
|
120257
|
-
HTTP Types - Internal Types, Handle and Core Implementation
|
|
120258
|
-
|
|
120259
|
-
See also:
|
|
120260
|
-
https://www.rfc-editor.org/rfc/rfc9110.html
|
|
120261
|
-
|
|
120262
|
-
|
|
120263
|
-
|
|
120264
|
-
Copyright and License: see header file (000 copyright.h) or top of file
|
|
120265
|
-
***************************************************************************** */
|
|
120266
|
-
#if defined(FIO_HTTP) && !defined(FIO___RECURSIVE_INCLUDE) && \
|
|
120267
|
-
!defined(H___FIO_HTTP_TYPES___H) && \
|
|
120268
|
-
(defined(FIO_EXTERN_COMPLETE) || !defined(FIO_EXTERN))
|
|
120269
|
-
#define H___FIO_HTTP_TYPES___H
|
|
120270
|
-
|
|
120271
120720
|
/* *****************************************************************************
|
|
120272
120721
|
HTTP Handle Implementation - inlined static functions
|
|
120273
120722
|
***************************************************************************** */
|
|
120274
120723
|
|
|
120275
120724
|
#define FIO___HTTP_GETSET_PTR(type, name, index_, pre_set_code) \
|
|
120276
|
-
/**
|
|
120277
|
-
*/ \
|
|
120725
|
+
/** Get the name property at its known pointer index. */ \
|
|
120278
120726
|
FIO_IFUNC type *fio_http_##name(fio_http_s *h) { \
|
|
120279
120727
|
return ((type **)h)[index_]; \
|
|
120280
120728
|
} \
|
|
120281
|
-
/**
|
|
120282
|
-
*/ \
|
|
120729
|
+
/** Set the name property at its known pointer index. */ \
|
|
120283
120730
|
FIO_IFUNC type *fio_http_##name##_set(fio_http_s *h, type *ptr) { \
|
|
120284
120731
|
pre_set_code; \
|
|
120285
120732
|
return (((type **)h)[index_] = ptr); \
|
|
@@ -120288,28 +120735,19 @@ HTTP Handle Implementation - inlined static functions
|
|
|
120288
120735
|
SFUNC fio_http_controller_s *fio___http_controller_validate(
|
|
120289
120736
|
fio_http_controller_s *c);
|
|
120290
120737
|
|
|
120291
|
-
|
|
120738
|
+
/** fio_http_udata / fio_http_udata_set */
|
|
120292
120739
|
FIO___HTTP_GETSET_PTR(void, udata, 0, (void)0)
|
|
120293
|
-
|
|
120740
|
+
/** fio_http_udata2 / fio_http_udata2_set */
|
|
120294
120741
|
FIO___HTTP_GETSET_PTR(void, udata2, 1, (void)0)
|
|
120295
|
-
|
|
120742
|
+
/** fio_http_cdata / fio_http_cdata_set */
|
|
120296
120743
|
FIO___HTTP_GETSET_PTR(void, cdata, 2, (void)0)
|
|
120297
|
-
|
|
120744
|
+
/** fio_http_controller / fio_http_controller_set */
|
|
120298
120745
|
FIO___HTTP_GETSET_PTR(fio_http_controller_s,
|
|
120299
120746
|
controller,
|
|
120300
120747
|
3,
|
|
120301
120748
|
ptr = fio___http_controller_validate(ptr))
|
|
120302
120749
|
|
|
120303
120750
|
#undef FIO___HTTP_GETSET_PTR
|
|
120304
|
-
/*
|
|
120305
|
-
REMEMBER:
|
|
120306
|
-
========
|
|
120307
|
-
|
|
120308
|
-
All memory allocations should use:
|
|
120309
|
-
* FIO_MEM_REALLOC_(ptr, old_size, new_size, copy_len)
|
|
120310
|
-
* FIO_MEM_FREE_(ptr, size)
|
|
120311
|
-
|
|
120312
|
-
*/
|
|
120313
120751
|
|
|
120314
120752
|
/* *****************************************************************************
|
|
120315
120753
|
Path Section Looping
|
|
@@ -120435,6 +120873,35 @@ FIO_IFUNC fio_http_resource_action_e fio_http_resource_action(fio_http_s *h) {
|
|
|
120435
120873
|
return r;
|
|
120436
120874
|
}
|
|
120437
120875
|
|
|
120876
|
+
/* *****************************************************************************
|
|
120877
|
+
HTTP API Finish
|
|
120878
|
+
***************************************************************************** */
|
|
120879
|
+
#endif /* FIO_HTTP */
|
|
120880
|
+
/* ************************************************************************* */
|
|
120881
|
+
#if !defined(FIO_INCLUDE_FILE) /* Dev test - ignore line */
|
|
120882
|
+
#define FIO___DEV___ /* Development inclusion - ignore line */
|
|
120883
|
+
#define FIO_HTTP /* Development inclusion - ignore line */
|
|
120884
|
+
#include "./include.h" /* Development inclusion - ignore line */
|
|
120885
|
+
#endif /* Development inclusion - ignore line */
|
|
120886
|
+
/* *****************************************************************************
|
|
120887
|
+
|
|
120888
|
+
|
|
120889
|
+
|
|
120890
|
+
|
|
120891
|
+
HTTP Types - Internal Types, Handle and Core Implementation
|
|
120892
|
+
|
|
120893
|
+
See also:
|
|
120894
|
+
https://www.rfc-editor.org/rfc/rfc9110.html
|
|
120895
|
+
|
|
120896
|
+
|
|
120897
|
+
|
|
120898
|
+
Copyright and License: see header file (000 copyright.h) or top of file
|
|
120899
|
+
***************************************************************************** */
|
|
120900
|
+
#if defined(FIO_HTTP) && !defined(FIO___RECURSIVE_INCLUDE) && \
|
|
120901
|
+
!defined(H___FIO_HTTP_TYPES___H) && \
|
|
120902
|
+
(defined(FIO_EXTERN_COMPLETE) || !defined(FIO_EXTERN))
|
|
120903
|
+
#define H___FIO_HTTP_TYPES___H
|
|
120904
|
+
|
|
120438
120905
|
/*
|
|
120439
120906
|
REMEMBER:
|
|
120440
120907
|
========
|
|
@@ -120445,6 +120912,23 @@ All memory allocations should use:
|
|
|
120445
120912
|
|
|
120446
120913
|
*/
|
|
120447
120914
|
|
|
120915
|
+
/* *****************************************************************************
|
|
120916
|
+
HTTP Handle State and Controller Flags
|
|
120917
|
+
***************************************************************************** */
|
|
120918
|
+
|
|
120919
|
+
#define FIO___HTTP_STATE_STREAMING 1
|
|
120920
|
+
#define FIO___HTTP_STATE_FINISHED 2
|
|
120921
|
+
#define FIO___HTTP_STATE_UPGRADED 4
|
|
120922
|
+
#define FIO___HTTP_STATE_WEBSOCKET 8
|
|
120923
|
+
#define FIO___HTTP_STATE_SSE 16
|
|
120924
|
+
#define FIO___HTTP_STATE_COOKIES_PARSED 32
|
|
120925
|
+
#define FIO___HTTP_STATE_FREEING 64
|
|
120926
|
+
|
|
120927
|
+
/** Controller flags (cflags) for opt-in compression features. */
|
|
120928
|
+
#define FIO___HTTP_CFLAG_COMPRESS_DYNAMIC 1
|
|
120929
|
+
#define FIO___HTTP_CFLAG_COMPRESS_WS 2
|
|
120930
|
+
#define FIO___HTTP_CFLAG_COMPRESS_STATIC 4
|
|
120931
|
+
|
|
120448
120932
|
/* *****************************************************************************
|
|
120449
120933
|
HTTP Settings Validation
|
|
120450
120934
|
***************************************************************************** */
|
|
@@ -121550,10 +122034,9 @@ struct fio_http_s {
|
|
|
121550
122034
|
int (*writer)(fio_http_s *, fio_http_write_args_s *);
|
|
121551
122035
|
int64_t received_at;
|
|
121552
122036
|
size_t sent;
|
|
122037
|
+
uint32_t cflags;
|
|
121553
122038
|
uint16_t state;
|
|
121554
122039
|
uint16_t status;
|
|
121555
|
-
uint16_t cflags;
|
|
121556
|
-
uint16_t uflags;
|
|
121557
122040
|
fio_keystr_s method;
|
|
121558
122041
|
fio_keystr_s opath;
|
|
121559
122042
|
fio_keystr_s path;
|
|
@@ -121582,7 +122065,7 @@ struct fio_http_s {
|
|
|
121582
122065
|
SFUNC fio_http_s *fio_http_destroy(fio_http_s *h) {
|
|
121583
122066
|
if (!h)
|
|
121584
122067
|
return h;
|
|
121585
|
-
h->state |=
|
|
122068
|
+
h->state |= FIO___HTTP_STATE_FREEING;
|
|
121586
122069
|
h->controller->on_destroyed(h);
|
|
121587
122070
|
|
|
121588
122071
|
fio_keystr_destroy(&h->method, fio___http_keystr_free);
|
|
@@ -121676,12 +122159,16 @@ Simple Property Set / Get
|
|
|
121676
122159
|
#define FIO___HTTP_MAKE_GET_SET(property) \
|
|
121677
122160
|
SFUNC fio_str_info_s fio_http_##property(fio_http_s *h) { \
|
|
121678
122161
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
|
|
122162
|
+
if (!h) \
|
|
122163
|
+
return FIO_STR_INFO0; \
|
|
121679
122164
|
return fio_keystr_info(&h->property); \
|
|
121680
122165
|
} \
|
|
121681
122166
|
\
|
|
121682
122167
|
SFUNC fio_str_info_s fio_http_##property##_set(fio_http_s *h, \
|
|
121683
122168
|
fio_str_info_s value) { \
|
|
121684
122169
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
|
|
122170
|
+
if (!h) \
|
|
122171
|
+
return FIO_STR_INFO0; \
|
|
121685
122172
|
fio_keystr_s old = h->property; /* delay destroy in case of copy/edit. */ \
|
|
121686
122173
|
h->property = fio_keystr_init(value, fio___http_keystr_alloc); \
|
|
121687
122174
|
fio_keystr_destroy(&old, fio___http_keystr_free); \
|
|
@@ -121717,32 +122204,43 @@ Controller / User Flags Set / Test / Flip
|
|
|
121717
122204
|
|
|
121718
122205
|
#define FIO___HTTP_MAKE_GET_SET(flags) \
|
|
121719
122206
|
/** Returns all set flags */ \
|
|
121720
|
-
FIO_IFUNC uint16_t
|
|
122207
|
+
FIO_IFUNC uint16_t fio___http_##flags(fio_http_s *h) { \
|
|
121721
122208
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
|
|
121722
122209
|
return h->flags; \
|
|
121723
122210
|
} \
|
|
121724
|
-
FIO_IFUNC uint16_t
|
|
122211
|
+
FIO_IFUNC uint16_t fio___http_##flags##_flip(fio_http_s *h, uint16_t flg) { \
|
|
121725
122212
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
|
|
121726
122213
|
h->flags ^= flg; \
|
|
121727
122214
|
return h->flags & flg; \
|
|
121728
122215
|
} \
|
|
121729
|
-
FIO_IFUNC uint16_t
|
|
122216
|
+
FIO_IFUNC uint16_t fio___http_##flags##_set(fio_http_s *h, uint16_t flg) { \
|
|
121730
122217
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
|
|
121731
122218
|
h->flags |= flg; \
|
|
121732
122219
|
return h->flags & flg; \
|
|
121733
122220
|
} \
|
|
121734
|
-
FIO_IFUNC uint16_t
|
|
122221
|
+
FIO_IFUNC uint16_t fio___http_##flags##_unset(fio_http_s *h, uint16_t flg) { \
|
|
121735
122222
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
|
|
121736
122223
|
h->flags &= ~flg; \
|
|
121737
122224
|
return h->flags & flg; \
|
|
121738
122225
|
} \
|
|
121739
|
-
FIO_IFUNC uint16_t
|
|
122226
|
+
FIO_IFUNC uint16_t fio___http_##flags##_is_set(fio_http_s *h, \
|
|
122227
|
+
uint16_t flg) { \
|
|
121740
122228
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
|
|
121741
122229
|
return h->flags & flg; \
|
|
121742
122230
|
}
|
|
121743
122231
|
|
|
121744
122232
|
FIO___HTTP_MAKE_GET_SET(cflags)
|
|
121745
|
-
|
|
122233
|
+
|
|
122234
|
+
/* Test-only seam for detached handles: production callers configure
|
|
122235
|
+
* compression via listener/route settings, not controller flags. */
|
|
122236
|
+
#if defined(FIO_HTTP_TEST_COMPRESSION_FLAGS)
|
|
122237
|
+
FIO_IFUNC void fio___http_test_enable_compression(fio_http_s *h,
|
|
122238
|
+
int is_static) {
|
|
122239
|
+
fio___http_cflags_set(h,
|
|
122240
|
+
is_static ? FIO___HTTP_CFLAG_COMPRESS_STATIC
|
|
122241
|
+
: FIO___HTTP_CFLAG_COMPRESS_DYNAMIC);
|
|
122242
|
+
}
|
|
122243
|
+
#endif
|
|
121746
122244
|
|
|
121747
122245
|
#undef FIO___HTTP_MAKE_GET_SET
|
|
121748
122246
|
/* *****************************************************************************
|
|
@@ -121751,45 +122249,147 @@ Handler State
|
|
|
121751
122249
|
|
|
121752
122250
|
SFUNC int fio_http_is_clean(fio_http_s *h) {
|
|
121753
122251
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!");
|
|
121754
|
-
return !(h->state & (~
|
|
122252
|
+
return !(h->state & (~FIO___HTTP_STATE_COOKIES_PARSED));
|
|
121755
122253
|
}
|
|
121756
122254
|
|
|
121757
122255
|
/** Returns true if the HTTP handle's response was sent. */
|
|
121758
122256
|
SFUNC int fio_http_is_finished(fio_http_s *h) {
|
|
121759
122257
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!");
|
|
121760
|
-
return (!!(h->state &
|
|
122258
|
+
return (!!(h->state & FIO___HTTP_STATE_FINISHED));
|
|
121761
122259
|
}
|
|
121762
122260
|
|
|
121763
122261
|
/** Returns true if handle is in the process of freeing itself. */
|
|
121764
122262
|
SFUNC int fio_http_is_freeing(fio_http_s *h) {
|
|
121765
122263
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!");
|
|
121766
|
-
return (!!(h->state &
|
|
122264
|
+
return (!!(h->state & FIO___HTTP_STATE_FREEING));
|
|
121767
122265
|
}
|
|
121768
122266
|
|
|
121769
122267
|
/** Returns true if the HTTP handle's response is streaming. */
|
|
121770
122268
|
SFUNC int fio_http_is_streaming(fio_http_s *h) {
|
|
121771
122269
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!");
|
|
121772
|
-
return (!!(h->state &
|
|
122270
|
+
return (!!(h->state & FIO___HTTP_STATE_STREAMING));
|
|
121773
122271
|
}
|
|
121774
122272
|
|
|
121775
122273
|
/** Returns true if the HTTP connection was (or should have been) upgraded. */
|
|
121776
122274
|
SFUNC int fio_http_is_upgraded(fio_http_s *h) {
|
|
121777
122275
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!");
|
|
121778
|
-
return (!!(h->state &
|
|
122276
|
+
return (!!(h->state & FIO___HTTP_STATE_UPGRADED));
|
|
121779
122277
|
}
|
|
121780
122278
|
|
|
121781
122279
|
/** Returns true if the HTTP handle establishes a WebSocket Upgrade. */
|
|
121782
122280
|
SFUNC int fio_http_is_websocket(fio_http_s *h) {
|
|
121783
122281
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!");
|
|
121784
|
-
return (!!(h->state &
|
|
122282
|
+
return (!!(h->state & FIO___HTTP_STATE_WEBSOCKET));
|
|
121785
122283
|
}
|
|
121786
122284
|
|
|
121787
122285
|
/** Returns true if the HTTP handle establishes an EventSource connection. */
|
|
121788
122286
|
SFUNC int fio_http_is_sse(fio_http_s *h) {
|
|
121789
122287
|
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!");
|
|
121790
|
-
return (!!(h->state &
|
|
122288
|
+
return (!!(h->state & FIO___HTTP_STATE_SSE));
|
|
121791
122289
|
}
|
|
121792
122290
|
|
|
122291
|
+
/* *****************************************************************************
|
|
122292
|
+
Method Name Matching
|
|
122293
|
+
***************************************************************************** */
|
|
122294
|
+
|
|
122295
|
+
SFUNC int fio_http_method_is_get(fio_http_s *h); /* IDE Marker*/
|
|
122296
|
+
SFUNC int fio_http_method_is_post(fio_http_s *h); /* IDE Marker*/
|
|
122297
|
+
SFUNC int fio_http_method_is_head(fio_http_s *h); /* IDE Marker*/
|
|
122298
|
+
SFUNC int fio_http_method_is_put(fio_http_s *h); /* IDE Marker*/
|
|
122299
|
+
|
|
122300
|
+
/* Define test for lengths 3 and 4 */
|
|
122301
|
+
#define FIO___HTTP_DEF_METHOD_TEST(m, l) \
|
|
122302
|
+
/** Tests if fio_http_method is m (case insensitive). */ \
|
|
122303
|
+
SFUNC int fio_http_method_is_##m(fio_http_s *h) { \
|
|
122304
|
+
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
|
|
122305
|
+
fio_str_info_s method = fio_http_method(h); \
|
|
122306
|
+
if (method.len != l) \
|
|
122307
|
+
return 0; \
|
|
122308
|
+
const uint32_t tst = fio_buf2u32u(#m) | 0x20202020U; \
|
|
122309
|
+
const uint32_t is = fio_buf2u32u(method.buf) | 0x20202020U; \
|
|
122310
|
+
return (tst == is); \
|
|
122311
|
+
}
|
|
122312
|
+
|
|
122313
|
+
FIO___HTTP_DEF_METHOD_TEST(copy, 4)
|
|
122314
|
+
FIO___HTTP_DEF_METHOD_TEST(get, 3)
|
|
122315
|
+
FIO___HTTP_DEF_METHOD_TEST(head, 4)
|
|
122316
|
+
FIO___HTTP_DEF_METHOD_TEST(lock, 4)
|
|
122317
|
+
FIO___HTTP_DEF_METHOD_TEST(move, 4)
|
|
122318
|
+
FIO___HTTP_DEF_METHOD_TEST(post, 4)
|
|
122319
|
+
FIO___HTTP_DEF_METHOD_TEST(put, 3)
|
|
122320
|
+
|
|
122321
|
+
#undef FIO___HTTP_DEF_METHOD_TEST
|
|
122322
|
+
|
|
122323
|
+
/* Define test for length 5 */
|
|
122324
|
+
#define FIO___HTTP_DEF_METHOD_TEST(m, l) \
|
|
122325
|
+
/** Returns 1 if fio_http_method is m (case insensitive). */ \
|
|
122326
|
+
SFUNC int fio_http_method_is_##m(fio_http_s *h) { \
|
|
122327
|
+
static const char *name = #m; \
|
|
122328
|
+
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
|
|
122329
|
+
fio_str_info_s method = fio_http_method(h); \
|
|
122330
|
+
if (method.len != l) \
|
|
122331
|
+
return 0; \
|
|
122332
|
+
if ((method.buf[0] | 0x20) != name[0]) \
|
|
122333
|
+
return 0; \
|
|
122334
|
+
const uint32_t tst = fio_buf2u32u(name + 1) | 0x20202020U; \
|
|
122335
|
+
const uint32_t is = fio_buf2u32u(method.buf + 1) | 0x20202020U; \
|
|
122336
|
+
return (tst == is); \
|
|
122337
|
+
}
|
|
122338
|
+
|
|
122339
|
+
FIO___HTTP_DEF_METHOD_TEST(patch, 5)
|
|
122340
|
+
FIO___HTTP_DEF_METHOD_TEST(query, 5)
|
|
122341
|
+
FIO___HTTP_DEF_METHOD_TEST(trace, 5)
|
|
122342
|
+
FIO___HTTP_DEF_METHOD_TEST(mkcol, 5)
|
|
122343
|
+
|
|
122344
|
+
#undef FIO___HTTP_DEF_METHOD_TEST
|
|
122345
|
+
|
|
122346
|
+
/* Define test for lengths 5-8 */
|
|
122347
|
+
#define FIO___HTTP_DEF_METHOD_TEST(m, l) \
|
|
122348
|
+
/** Returns 1 if fio_http_method is m (case insensitive). */ \
|
|
122349
|
+
SFUNC int fio_http_method_is_##m(fio_http_s *h) { \
|
|
122350
|
+
static const char *name = #m; \
|
|
122351
|
+
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
|
|
122352
|
+
fio_str_info_s method = fio_http_method(h); \
|
|
122353
|
+
if (method.len != l) \
|
|
122354
|
+
return 0; \
|
|
122355
|
+
const uint32_t tst1 = fio_buf2u32u(name) | 0x20202020U; \
|
|
122356
|
+
const uint32_t is1 = fio_buf2u32u(method.buf) | 0x20202020U; \
|
|
122357
|
+
const uint32_t tst2 = fio_buf2u32u(name + (l - 4)) | 0x20202020U; \
|
|
122358
|
+
const uint32_t is2 = fio_buf2u32u(method.buf + (l - 4)) | 0x20202020U; \
|
|
122359
|
+
return !((tst1 ^ is1) | (tst2 ^ is2)); \
|
|
122360
|
+
}
|
|
122361
|
+
|
|
122362
|
+
FIO___HTTP_DEF_METHOD_TEST(search, 6)
|
|
122363
|
+
FIO___HTTP_DEF_METHOD_TEST(delete, 6)
|
|
122364
|
+
FIO___HTTP_DEF_METHOD_TEST(options, 7)
|
|
122365
|
+
FIO___HTTP_DEF_METHOD_TEST(connect, 7)
|
|
122366
|
+
FIO___HTTP_DEF_METHOD_TEST(unlock, 6)
|
|
122367
|
+
FIO___HTTP_DEF_METHOD_TEST(propfind, 8)
|
|
122368
|
+
|
|
122369
|
+
#undef FIO___HTTP_DEF_METHOD_TEST
|
|
122370
|
+
|
|
122371
|
+
/* Define test for lengths 9-16 */
|
|
122372
|
+
#define FIO___HTTP_DEF_METHOD_TEST(m, l) \
|
|
122373
|
+
/** Returns 1 if fio_http_method is m (case insensitive). */ \
|
|
122374
|
+
SFUNC int fio_http_method_is_##m(fio_http_s *h) { \
|
|
122375
|
+
static const char *name = #m; \
|
|
122376
|
+
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
|
|
122377
|
+
fio_str_info_s method = fio_http_method(h); \
|
|
122378
|
+
if (method.len != l) \
|
|
122379
|
+
return 0; \
|
|
122380
|
+
const uint64_t tst1 = \
|
|
122381
|
+
fio_buf2u64u(name) | (uint64_t)0x2020202020202020ULL; \
|
|
122382
|
+
const uint64_t is1 = \
|
|
122383
|
+
fio_buf2u64u(method.buf) | (uint64_t)0x2020202020202020ULL; \
|
|
122384
|
+
const uint32_t tst2 = fio_buf2u32u(name + (l - 8)) | 0x20202020U; \
|
|
122385
|
+
const uint32_t is2 = fio_buf2u32u(method.buf + (l - 8)) | 0x20202020U; \
|
|
122386
|
+
return !((tst1 ^ is1) | (uint64_t)(tst2 ^ is2)); \
|
|
122387
|
+
}
|
|
122388
|
+
|
|
122389
|
+
FIO___HTTP_DEF_METHOD_TEST(proppatch, 9)
|
|
122390
|
+
|
|
122391
|
+
#undef FIO___HTTP_DEF_METHOD_TEST
|
|
122392
|
+
|
|
121793
122393
|
/* *****************************************************************************
|
|
121794
122394
|
Header Data Management
|
|
121795
122395
|
***************************************************************************** */
|
|
@@ -122017,8 +122617,9 @@ int fio_http_cookie_set___(void); /* IDE Marker */
|
|
|
122017
122617
|
SFUNC int fio_http_cookie_set FIO_NOOP(fio_http_s *h,
|
|
122018
122618
|
fio_http_cookie_args_s cookie) {
|
|
122019
122619
|
FIO_ASSERT_DEBUG(h, "Can't set cookie for NULL HTTP handler!");
|
|
122020
|
-
if (!h ||
|
|
122021
|
-
|
|
122620
|
+
if (!h ||
|
|
122621
|
+
((h->state & (FIO___HTTP_STATE_FINISHED | FIO___HTTP_STATE_STREAMING)) |
|
|
122622
|
+
(h->writer != fio____http_write_start)))
|
|
122022
122623
|
return -1;
|
|
122023
122624
|
/* promises that some warnings print only once. */
|
|
122024
122625
|
static unsigned int warn_illegal = 0;
|
|
@@ -122219,8 +122820,8 @@ SFUNC int fio_http_cookie_set FIO_NOOP(fio_http_s *h,
|
|
|
122219
122820
|
SFUNC fio_str_info_s fio_http_cookie(fio_http_s *h,
|
|
122220
122821
|
const char *name,
|
|
122221
122822
|
size_t name_len) {
|
|
122222
|
-
if (!(fio_atomic_or(&h->state,
|
|
122223
|
-
|
|
122823
|
+
if (!(fio_atomic_or(&h->state, FIO___HTTP_STATE_COOKIES_PARSED) &
|
|
122824
|
+
FIO___HTTP_STATE_COOKIES_PARSED))
|
|
122224
122825
|
fio___http_cookie_collect(h);
|
|
122225
122826
|
fio_str_info_s r =
|
|
122226
122827
|
fio___http_cmap_get(h->cookies, FIO_STR_INFO2((char *)name, name_len));
|
|
@@ -122234,8 +122835,8 @@ SFUNC size_t fio_http_cookie_each(fio_http_s *h,
|
|
|
122234
122835
|
fio_str_info_s value,
|
|
122235
122836
|
void *udata),
|
|
122236
122837
|
void *udata) {
|
|
122237
|
-
if (!(fio_atomic_or(&h->state,
|
|
122238
|
-
|
|
122838
|
+
if (!(fio_atomic_or(&h->state, FIO___HTTP_STATE_COOKIES_PARSED) &
|
|
122839
|
+
FIO___HTTP_STATE_COOKIES_PARSED))
|
|
122239
122840
|
fio___http_cookie_collect(h);
|
|
122240
122841
|
size_t i = 0;
|
|
122241
122842
|
FIO_MAP_EACH(fio___http_cmap, h->cookies, pos) {
|
|
@@ -122485,7 +123086,7 @@ SFUNC fio_str_info_s fio_http_body_read(fio_http_s *h, size_t length) {
|
|
|
122485
123086
|
fio_str_info_s r = {0};
|
|
122486
123087
|
if (h->body.pos == h->body.len)
|
|
122487
123088
|
return r;
|
|
122488
|
-
if (h->body.
|
|
123089
|
+
if (length > h->body.len - h->body.pos)
|
|
122489
123090
|
length = h->body.len - h->body.pos;
|
|
122490
123091
|
r = ((h->body.fd == -1) ? fio___http_body_read_buf
|
|
122491
123092
|
: fio___http_body_read_fd)(h, length);
|
|
@@ -122616,7 +123217,8 @@ FIO_SFUNC int fio____http_write_start(fio_http_s *h,
|
|
|
122616
123217
|
}
|
|
122617
123218
|
#if 1
|
|
122618
123219
|
if (args->finish &&
|
|
122619
|
-
FIO_LIKELY(
|
|
123220
|
+
FIO_LIKELY(
|
|
123221
|
+
fio___http_cflags_is_set(h, FIO___HTTP_CFLAG_COMPRESS_DYNAMIC)) &&
|
|
122620
123222
|
args->len > 1024 && args->buf) {
|
|
122621
123223
|
/* Never double-compress: the application already encoded this response. */
|
|
122622
123224
|
if (fio___http_hmap_get_ptr(hdrs,
|
|
@@ -122735,7 +123337,7 @@ FIO_SFUNC int fio____http_write_start(fio_http_s *h,
|
|
|
122735
123337
|
fio_ltoa10u(v.buf, args->len, v.len);
|
|
122736
123338
|
fio___http_hmap_set2(hdrs, k, v, -1);
|
|
122737
123339
|
} else if (!(h->state & FIO___HTTP_STATE_NO_CONTENT)) {
|
|
122738
|
-
h->state |=
|
|
123340
|
+
h->state |= FIO___HTTP_STATE_STREAMING;
|
|
122739
123341
|
}
|
|
122740
123342
|
}
|
|
122741
123343
|
send_headers:
|
|
@@ -122752,8 +123354,8 @@ FIO_SFUNC int fio____http_write_cont(fio_http_s *h,
|
|
|
122752
123354
|
h->sent += args->len;
|
|
122753
123355
|
}
|
|
122754
123356
|
if (args->finish) {
|
|
122755
|
-
h->state |=
|
|
122756
|
-
h->writer = (h->state &
|
|
123357
|
+
h->state |= FIO___HTTP_STATE_FINISHED;
|
|
123358
|
+
h->writer = (h->state & FIO___HTTP_STATE_UPGRADED)
|
|
122757
123359
|
? fio____http_write_upgraded
|
|
122758
123360
|
: fio____http_write_done;
|
|
122759
123361
|
h->controller->on_finish(h);
|
|
@@ -122791,7 +123393,7 @@ FIO_IFUNC int fio___http_response_etag_if_none_match(fio_http_s *h) {
|
|
|
122791
123393
|
-1);
|
|
122792
123394
|
|
|
122793
123395
|
h->controller->send_headers(h);
|
|
122794
|
-
h->state |=
|
|
123396
|
+
h->state |= FIO___HTTP_STATE_FINISHED;
|
|
122795
123397
|
h->writer = fio____http_write_done;
|
|
122796
123398
|
h->controller->on_finish(h);
|
|
122797
123399
|
return -1;
|
|
@@ -122881,7 +123483,7 @@ SFUNC void fio_http_upgrade_websocket(fio_http_s *h) {
|
|
|
122881
123483
|
accept_val);
|
|
122882
123484
|
}
|
|
122883
123485
|
{ /* finish up */
|
|
122884
|
-
h->state |=
|
|
123486
|
+
h->state |= FIO___HTTP_STATE_UPGRADED | FIO___HTTP_STATE_WEBSOCKET;
|
|
122885
123487
|
fio_http_write_args_s args = {.finish = 1};
|
|
122886
123488
|
fio_http_write FIO_NOOP(h, args);
|
|
122887
123489
|
}
|
|
@@ -122983,8 +123585,8 @@ SFUNC int fio_http_websocket_accepted(fio_http_s *h) {
|
|
|
122983
123585
|
return 0;
|
|
122984
123586
|
}
|
|
122985
123587
|
}
|
|
122986
|
-
h->state |= (
|
|
122987
|
-
|
|
123588
|
+
h->state |= (FIO___HTTP_STATE_UPGRADED | FIO___HTTP_STATE_WEBSOCKET |
|
|
123589
|
+
FIO___HTTP_STATE_FINISHED);
|
|
122988
123590
|
h->writer = fio____http_write_upgraded;
|
|
122989
123591
|
return 1;
|
|
122990
123592
|
}
|
|
@@ -123027,8 +123629,8 @@ SFUNC int fio_http_sse_accepted(fio_http_s *h) {
|
|
|
123027
123629
|
FIO_STR_INFO2((char *)"content-type", 12),
|
|
123028
123630
|
0);
|
|
123029
123631
|
}
|
|
123030
|
-
h->state |=
|
|
123031
|
-
|
|
123632
|
+
h->state |= (FIO___HTTP_STATE_UPGRADED | FIO___HTTP_STATE_SSE |
|
|
123633
|
+
FIO___HTTP_STATE_FINISHED);
|
|
123032
123634
|
h->writer = fio____http_write_upgraded;
|
|
123033
123635
|
FIO_LOG_DDEBUG2("EventSource connection accepted.");
|
|
123034
123636
|
return 1;
|
|
@@ -123047,8 +123649,8 @@ SFUNC void fio_http_upgrade_sse(fio_http_s *h) {
|
|
|
123047
123649
|
fio___http_hmap_remove(HTTP_HDR_RESPONSE(h),
|
|
123048
123650
|
FIO_STR_INFO2((char *)"content-length", 14),
|
|
123049
123651
|
NULL);
|
|
123050
|
-
h->state |=
|
|
123051
|
-
|
|
123652
|
+
h->state |= FIO___HTTP_STATE_FINISHED | FIO___HTTP_STATE_UPGRADED |
|
|
123653
|
+
FIO___HTTP_STATE_SSE;
|
|
123052
123654
|
h->controller->send_headers(h);
|
|
123053
123655
|
h->writer = fio____http_write_upgraded;
|
|
123054
123656
|
h->controller->on_finish(h);
|
|
@@ -124454,7 +125056,7 @@ FIO_SFUNC void fio___http_static_compress_note_result(
|
|
|
124454
125056
|
* EACCES, EROFS, EDQUOT — `value = 0`). Once 0, creation stays disabled
|
|
124455
125057
|
* until the settings are re-applied. Routes inherit the value from the
|
|
124456
125058
|
* listener settings at route-creation. Detached handles (no settings)
|
|
124457
|
-
* gate on the `
|
|
125059
|
+
* gate on the `FIO___HTTP_CFLAG_COMPRESS_STATIC` cflag instead, with no
|
|
124458
125060
|
* memoization state.
|
|
124459
125061
|
*/
|
|
124460
125062
|
SFUNC int fio_http_static_file_response(fio_http_s *h,
|
|
@@ -124577,7 +125179,7 @@ SFUNC int fio_http_static_file_response(fio_http_s *h,
|
|
|
124577
125179
|
int can_create =
|
|
124578
125180
|
have_orig_st &&
|
|
124579
125181
|
(st ? settings_may_compress
|
|
124580
|
-
:
|
|
125182
|
+
: fio___http_cflags_is_set(h, FIO___HTTP_CFLAG_COMPRESS_STATIC)) &&
|
|
124581
125183
|
fio___http_mime_is_compressible(mime_type) &&
|
|
124582
125184
|
(size_t)orig_st.st_size >= 1024 &&
|
|
124583
125185
|
(size_t)orig_st.st_size <= FIO_HTTP_STATIC_FILE_COMPRESS_LIMIT;
|
|
@@ -125591,9 +126193,9 @@ FIO_IFUNC void fio_http1_attach_handle(fio___http_connection_s *c) {
|
|
|
125591
126193
|
fio_http_udata_set(c->h, c->udata);
|
|
125592
126194
|
fio_http_cdata_set(c->h, fio___http_connection_dup(c));
|
|
125593
126195
|
if (c->settings->compress_dynamic)
|
|
125594
|
-
|
|
126196
|
+
fio___http_cflags_set(c->h, FIO___HTTP_CFLAG_COMPRESS_DYNAMIC);
|
|
125595
126197
|
if (c->settings->compress_ws)
|
|
125596
|
-
|
|
126198
|
+
fio___http_cflags_set(c->h, FIO___HTTP_CFLAG_COMPRESS_WS);
|
|
125597
126199
|
}
|
|
125598
126200
|
|
|
125599
126201
|
/** called when a request method is parsed. */
|
|
@@ -125940,7 +126542,7 @@ FIO_SFUNC void fio___http1_send_request(fio_http_s *h) {
|
|
|
125940
126542
|
fio_io_write2(c->io,
|
|
125941
126543
|
.buf = (char *)fio_http_dup(h),
|
|
125942
126544
|
.len = buf.len,
|
|
125943
|
-
.offset = (size_t)((char *)h
|
|
126545
|
+
.offset = (size_t)(buf.buf - (char *)h),
|
|
125944
126546
|
.dealloc = (void (*)(void *))fio_http_free);
|
|
125945
126547
|
} else {
|
|
125946
126548
|
fio_io_write2(c->io,
|
|
@@ -126028,10 +126630,7 @@ FIO_SFUNC void fio___http_controller_http1_send_headers(fio_http_s *h) {
|
|
|
126028
126630
|
FIO_STR_INFO2((char *)"connection", 10),
|
|
126029
126631
|
0)
|
|
126030
126632
|
.buf)
|
|
126031
|
-
fio_string_write(&buf,
|
|
126032
|
-
FIO_STRING_REALLOC,
|
|
126033
|
-
"connection:keep-alive\r\n",
|
|
126034
|
-
23);
|
|
126633
|
+
fio_string_write(&buf, FIO_STRING_REALLOC, "connection:keep-alive\r\n", 23);
|
|
126035
126634
|
fio_string_write(&buf, FIO_STRING_REALLOC, "\r\n", 2);
|
|
126036
126635
|
/* send data (move memory ownership)? */
|
|
126037
126636
|
c->state.http.buf = buf;
|
|
@@ -126677,7 +127276,7 @@ FIO_SFUNC void fio___http_perform_user_upgrade_callback_websocket(void *cb_,
|
|
|
126677
127276
|
if (c->h) /* request after WebSocket Upgrade? an attack vector? */
|
|
126678
127277
|
goto refuse_upgrade;
|
|
126679
127278
|
/* RFC 7692: permessage-deflate extension negotiation (no-takeover only) */
|
|
126680
|
-
if (FIO_LIKELY(
|
|
127279
|
+
if (FIO_LIKELY(fio___http_cflags_is_set(h, FIO___HTTP_CFLAG_COMPRESS_WS))) {
|
|
126681
127280
|
FIO_HTTP_HEADER_EACH_VALUE(
|
|
126682
127281
|
h,
|
|
126683
127282
|
1,
|
|
@@ -126686,9 +127285,8 @@ FIO_SFUNC void fio___http_perform_user_upgrade_callback_websocket(void *cb_,
|
|
|
126686
127285
|
FIO_LOG_DDEBUG2("WebSocket extension requested: %.*s",
|
|
126687
127286
|
(int)val.value.len,
|
|
126688
127287
|
val.value.buf);
|
|
126689
|
-
if (!FIO_BUF_INFO_IS_EQ(
|
|
126690
|
-
|
|
126691
|
-
FIO_BUF_INFO2((char *)"permessage-deflate", 18)))
|
|
127288
|
+
if (!FIO_BUF_INFO_IS_EQ(val.value,
|
|
127289
|
+
FIO_BUF_INFO2((char *)"permessage-deflate", 18)))
|
|
126692
127290
|
continue;
|
|
126693
127291
|
/* Negotiate: ALWAYS force both no_context_takeover flags (persistent
|
|
126694
127292
|
* compression state stays ~0 per connection); honor
|
|
@@ -126698,8 +127296,8 @@ FIO_SFUNC void fio___http_perform_user_upgrade_callback_websocket(void *cb_,
|
|
|
126698
127296
|
size_t ext_len = fio___http_ws_deflate_negotiate(
|
|
126699
127297
|
FIO_STR_INFO2(val.value.buf, val.value.len),
|
|
126700
127298
|
ext_resp,
|
|
126701
|
-
|
|
126702
|
-
|
|
127299
|
+
sizeof(ext_resp),
|
|
127300
|
+
&server_bits);
|
|
126703
127301
|
if (!ext_len)
|
|
126704
127302
|
continue;
|
|
126705
127303
|
fio_http_response_header_set(
|
|
@@ -127305,34 +127903,36 @@ FIO_SFUNC void fio___http_controller_ws_write_body(fio_http_s *h,
|
|
|
127305
127903
|
const size_t framed_len = fio_websocket_write_len(args.len, 1);
|
|
127306
127904
|
char *frame = NULL;
|
|
127307
127905
|
if (args.len <= SIZE_MAX - args.offset && framed_len <= UINT32_MAX &&
|
|
127308
|
-
(args.buf ||
|
|
127309
|
-
|
|
127310
|
-
|
|
127311
|
-
|
|
127312
|
-
|
|
127313
|
-
(uintmax_t)(args.offset + args.len))))
|
|
127906
|
+
(args.buf || ((off_t)args.offset >= 0 &&
|
|
127907
|
+
(uintmax_t)(off_t)args.offset == (uintmax_t)args.offset &&
|
|
127908
|
+
(off_t)(args.offset + args.len) >= 0 &&
|
|
127909
|
+
(uintmax_t)(off_t)(args.offset + args.len) ==
|
|
127910
|
+
(uintmax_t)(args.offset + args.len))))
|
|
127314
127911
|
frame = fio_bstr_reserve(NULL, framed_len);
|
|
127315
127912
|
if (!frame)
|
|
127316
127913
|
goto client_write_error;
|
|
127317
127914
|
if (args.buf) {
|
|
127318
127915
|
fio_websocket_write_message_client(
|
|
127319
|
-
frame,
|
|
127916
|
+
frame,
|
|
127917
|
+
FIO_BUF_INFO2((char *)args.buf + args.offset, args.len),
|
|
127918
|
+
0,
|
|
127919
|
+
0,
|
|
127920
|
+
0);
|
|
127320
127921
|
} else {
|
|
127321
127922
|
uint32_t mask = (uint32_t)(fio_rand64() | 0x01020408U);
|
|
127322
127923
|
size_t head = fio___websocket_hdr((uint8_t *)frame,
|
|
127323
|
-
|
|
127324
|
-
|
|
127325
|
-
|
|
127326
|
-
|
|
127924
|
+
args.len,
|
|
127925
|
+
mask,
|
|
127926
|
+
FIO_WEBSOCKET_OP_BINARY,
|
|
127927
|
+
0);
|
|
127327
127928
|
if (fio_fd_read(args.fd, frame + head, args.len, (off_t)args.offset) !=
|
|
127328
127929
|
args.len) {
|
|
127329
127930
|
fio_bstr_free(frame);
|
|
127330
127931
|
goto client_write_error;
|
|
127331
127932
|
}
|
|
127332
|
-
|
|
127333
|
-
|
|
127334
|
-
|
|
127335
|
-
((uint64_t)mask << 32) | (uint64_t)mask);
|
|
127933
|
+
fio_xmask(frame + head,
|
|
127934
|
+
args.len,
|
|
127935
|
+
((uint64_t)mask << 32) | (uint64_t)mask);
|
|
127336
127936
|
}
|
|
127337
127937
|
if (!args.buf && (unsigned)(args.fd + 1) > 1)
|
|
127338
127938
|
close(args.fd);
|
|
@@ -127981,6 +128581,17 @@ once per template instantiation pass.
|
|
|
127981
128581
|
Copyright and License: see header file (000 copyright.h) or top of file
|
|
127982
128582
|
***************************************************************************** */
|
|
127983
128583
|
#if !defined(FIO___RECURSIVE_INCLUDE) && defined(FIO_HTTP)
|
|
128584
|
+
#undef FIO___HTTP_STATE_STREAMING
|
|
128585
|
+
#undef FIO___HTTP_STATE_FINISHED
|
|
128586
|
+
#undef FIO___HTTP_STATE_UPGRADED
|
|
128587
|
+
#undef FIO___HTTP_STATE_WEBSOCKET
|
|
128588
|
+
#undef FIO___HTTP_STATE_SSE
|
|
128589
|
+
#undef FIO___HTTP_STATE_COOKIES_PARSED
|
|
128590
|
+
#undef FIO___HTTP_STATE_FREEING
|
|
128591
|
+
#undef FIO___HTTP_STATE_NO_CONTENT
|
|
128592
|
+
#undef FIO___HTTP_CFLAG_COMPRESS_DYNAMIC
|
|
128593
|
+
#undef FIO___HTTP_CFLAG_COMPRESS_WS
|
|
128594
|
+
#undef FIO___HTTP_CFLAG_COMPRESS_STATIC
|
|
127984
128595
|
#undef FIO_HTTP
|
|
127985
128596
|
#endif
|
|
127986
128597
|
/* *****************************************************************************
|