|
33 | 33 | #define _GNU_SOURCE |
34 | 34 | #include <string.h> |
35 | 35 |
|
| 36 | +#ifdef FLB_SYSTEM_WINDOWS |
| 37 | +#include <winsock2.h> |
| 38 | +#include <ws2tcpip.h> |
| 39 | +#endif |
| 40 | + |
36 | 41 | #include <fluent-bit/flb_info.h> |
| 42 | +#include <fluent-bit/flb_compat.h> |
37 | 43 | #include <fluent-bit/flb_kv.h> |
38 | 44 | #include <fluent-bit/flb_log.h> |
39 | 45 | #include <fluent-bit/flb_mem.h> |
@@ -617,11 +623,55 @@ static int add_host_and_content_length(struct flb_http_client *c) |
617 | 623 | out_port = c->port; |
618 | 624 | } |
619 | 625 |
|
620 | | - if (c->flags & FLB_IO_TLS && out_port == 443) { |
621 | | - tmp = flb_sds_copy(host, out_host, strlen(out_host)); |
| 626 | + /* Check if out_host is an unbracketed IPv6 address */ |
| 627 | + struct in6_addr addr; |
| 628 | + char *zone_id; |
| 629 | + char addr_buf[INET6_ADDRSTRLEN]; |
| 630 | + int is_ipv6 = 0; |
| 631 | + int is_https_default_port; |
| 632 | + const char *host_for_header; |
| 633 | + |
| 634 | + if (out_host && out_host[0] != '[') { |
| 635 | + /* Strip zone ID if present (e.g., fe80::1%eth0 -> fe80::1) */ |
| 636 | + zone_id = strchr(out_host, '%'); |
| 637 | + if (zone_id) { |
| 638 | + len = zone_id - out_host; |
| 639 | + if (len < INET6_ADDRSTRLEN) { |
| 640 | + memcpy(addr_buf, out_host, len); |
| 641 | + addr_buf[len] = '\0'; |
| 642 | + is_ipv6 = (inet_pton(AF_INET6, addr_buf, &addr) == 1); |
| 643 | + } |
| 644 | + } |
| 645 | + else { |
| 646 | + is_ipv6 = (inet_pton(AF_INET6, out_host, &addr) == 1); |
| 647 | + } |
| 648 | + } |
| 649 | + |
| 650 | + /* Use stripped address (without zone ID) for Host header if zone ID was present */ |
| 651 | + host_for_header = (is_ipv6 && zone_id) ? addr_buf : out_host; |
| 652 | + |
| 653 | + /* Check if connection uses TLS and port is 443 (HTTPS default) */ |
| 654 | + is_https_default_port = flb_stream_get_flag_status(&u->base, FLB_IO_TLS) && out_port == 443; |
| 655 | + |
| 656 | + if (is_https_default_port) { |
| 657 | + if (is_ipv6) { |
| 658 | + /* IPv6 address needs brackets for RFC compliance */ |
| 659 | + tmp = flb_sds_printf(&host, "[%s]", host_for_header); |
| 660 | + } |
| 661 | + else { |
| 662 | + /* HTTPS on default port 443 - omit port from Host header */ |
| 663 | + tmp = flb_sds_copy(host, out_host, strlen(out_host)); |
| 664 | + } |
622 | 665 | } |
623 | 666 | else { |
624 | | - tmp = flb_sds_printf(&host, "%s:%i", out_host, out_port); |
| 667 | + if (is_ipv6) { |
| 668 | + /* IPv6 address needs brackets when combined with port */ |
| 669 | + tmp = flb_sds_printf(&host, "[%s]:%i", host_for_header, out_port); |
| 670 | + } |
| 671 | + else { |
| 672 | + /* IPv4 address, domain name, or already bracketed IPv6 */ |
| 673 | + tmp = flb_sds_printf(&host, "%s:%i", out_host, out_port); |
| 674 | + } |
625 | 675 | } |
626 | 676 |
|
627 | 677 | if (!tmp) { |
|
0 commit comments