| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "http2_response.h" | ||
| 2 | #include <string.h> | ||
| 3 | #include <stdio.h> | ||
| 4 | #include "metrics.h" | ||
| 5 | |||
| 6 | 5 | void h2_response_init(Http2Response *resp) | |
| 7 | { | ||
| 8 | 5 | memset(resp, 0, sizeof(Http2Response)); | |
| 9 | 5 | resp->status_code = 200; | |
| 10 | 5 | strcpy(resp->status_text, "OK"); | |
| 11 | 5 | strcpy(resp->content_type, "text/html"); | |
| 12 | 5 | } | |
| 13 | |||
| 14 | 5 | void h2_response_set_status(Http2Response *resp, int status_code, const char *status_text) | |
| 15 | { | ||
| 16 | 5 | resp->status_code = status_code; | |
| 17 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | snprintf(resp->status_text, sizeof(resp->status_text), "%s", status_text ? status_text : "OK"); |
| 18 | 5 | snprintf(resp->status_code_str, sizeof(resp->status_code_str), "%d", status_code); | |
| 19 | 5 | } | |
| 20 | |||
| 21 | 22 | void h2_response_add_header(Http2Response *resp, const char *name, const char *value) | |
| 22 | { | ||
| 23 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
|
22 | if (resp->num_headers >= 16) |
| 24 | ✗ | return; | |
| 25 | |||
| 26 | 22 | resp->headers[resp->num_headers] = MAKE_NV(name, value); | |
| 27 | 22 | resp->num_headers++; | |
| 28 | } | ||
| 29 | |||
| 30 | 4 | void h2_response_set_body(Http2Response *resp, const char *body, size_t len) | |
| 31 | { | ||
| 32 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (len >= sizeof(resp->body)) |
| 33 | ✗ | len = sizeof(resp->body) - 1; | |
| 34 | |||
| 35 | 4 | memcpy(resp->body, body, len); | |
| 36 | 4 | resp->body[len] = '\0'; | |
| 37 | 4 | resp->body_len = len; | |
| 38 | 4 | } | |
| 39 | |||
| 40 | 1 | void h2_response_set_body_len(Http2Response *resp, size_t len) | |
| 41 | { | ||
| 42 | 1 | resp->body_len = len; | |
| 43 | 1 | } | |
| 44 | |||
| 45 | 4 | void h2_response_set_content_type(Http2Response *resp, const char *content_type) | |
| 46 | { | ||
| 47 | 4 | snprintf(resp->content_type, sizeof(resp->content_type), "%s", content_type); | |
| 48 | 4 | } | |
| 49 | |||
| 50 | 1 | void h2_response_finalize(Http2Response *resp) | |
| 51 | { | ||
| 52 | 1 | snprintf(resp->content_length_str, sizeof(resp->content_length_str), "%zu", resp->body_len); | |
| 53 | 1 | } | |
| 54 | |||
| 55 | 5 | void h2_response_add_security_headers(Http2Response *resp, SecurityHeadersConfig *config, CORSConfig *cors) | |
| 56 | { | ||
| 57 | 5 | int sec_headers_added = 0; | |
| 58 | 5 | int cors_headers_added = 0; | |
| 59 | |||
| 60 |
4/6✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 3 times.
|
5 | if (!resp || !config || !config->enabled) |
| 61 | 2 | return; | |
| 62 | |||
| 63 |
3/4✓ Branch 0 taken 18 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
|
21 | for (int i = 0; i < config->header_count && resp->num_headers < 16; i++) { |
| 64 | 18 | const SecurityHeader *header = &config->headers[i]; | |
| 65 | 18 | h2_response_add_header(resp, header->name, header->value); | |
| 66 | 18 | sec_headers_added++; | |
| 67 | } | ||
| 68 | |||
| 69 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
3 | if (cors && cors->enabled) { |
| 70 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if (cors->allow_origin[0] != '\0' && resp->num_headers < 16) { |
| 71 | 1 | h2_response_add_header(resp, "Access-Control-Allow-Origin", cors->allow_origin); | |
| 72 | 1 | cors_headers_added++; | |
| 73 | } | ||
| 74 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if (cors->allow_methods[0] != '\0' && resp->num_headers < 16) { |
| 75 | 1 | h2_response_add_header(resp, "Access-Control-Allow-Methods", cors->allow_methods); | |
| 76 | 1 | cors_headers_added++; | |
| 77 | } | ||
| 78 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if (cors->allow_headers[0] != '\0' && resp->num_headers < 16) { |
| 79 | 1 | h2_response_add_header(resp, "Access-Control-Allow-Headers", cors->allow_headers); | |
| 80 | 1 | cors_headers_added++; | |
| 81 | } | ||
| 82 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1 | if (cors->allow_credentials && resp->num_headers < 16) { |
| 83 | ✗ | h2_response_add_header(resp, "Access-Control-Allow-Credentials", "true"); | |
| 84 | ✗ | cors_headers_added++; | |
| 85 | } | ||
| 86 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if (cors->max_age_seconds > 0 && resp->num_headers < 16) { |
| 87 | char max_age_str[32]; | ||
| 88 | 1 | snprintf(max_age_str, sizeof(max_age_str), "%d", cors->max_age_seconds); | |
| 89 | 1 | h2_response_add_header(resp, "Access-Control-Max-Age", max_age_str); | |
| 90 | 1 | cors_headers_added++; | |
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (sec_headers_added > 0) { |
| 95 | 3 | metrics_increment_security_headers_sent(); | |
| 96 | } | ||
| 97 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if (cors_headers_added > 0) { |
| 98 | 1 | metrics_increment_cors_headers_sent(); | |
| 99 | } | ||
| 100 | } | ||
| 101 |