@@ -1508,158 +1508,104 @@ func TestBuildRequestURL(t *testing.T) {
15081508 }
15091509}
15101510
1511- func TestDirectTransmitAdditionalHeaders (t * testing.T ) {
1512- // Create test server that captures headers
1513- var capturedHeaders http.Header
1514- var headerMutex sync.Mutex
1515-
1516- server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1517- headerMutex .Lock ()
1518- capturedHeaders = r .Header .Clone ()
1519- headerMutex .Unlock ()
1520-
1521- // Read and discard body
1522- io .ReadAll (r .Body )
1523- r .Body .Close ()
1524-
1525- // Send proper response
1526- w .Header ().Set ("Content-Type" , "application/json" )
1527- w .WriteHeader (http .StatusOK )
1528- w .Write ([]byte (`[{"status": 202}]` ))
1529- }))
1530- defer server .Close ()
1531-
1532- // Create DirectTransmission with additional headers
1533- additionalHeaders := map [string ]string {
1534- "FORWARD_TO_URL" : "https://proxy.example.com" ,
1535- "X-Custom-Header" : "custom-value" ,
1536- }
1537-
1538- mockMetrics := & metrics.MockMetrics {}
1539- mockMetrics .Start ()
1540- mockLogger := & logger.MockLogger {}
1541-
1542- dt := NewDirectTransmission (
1543- types .TransmitTypeUpstream ,
1544- http .DefaultTransport .(* http.Transport ),
1545- 10 ,
1546- 100 * time .Millisecond ,
1547- 10 * time .Second ,
1548- false , // no compression to simplify test
1549- additionalHeaders ,
1550- )
1551- dt .Logger = mockLogger
1552- dt .Version = "test-version"
1553- dt .Metrics = mockMetrics
1554-
1555- err := dt .Start ()
1556- require .NoError (t , err )
1557- defer dt .Stop ()
1558-
1559- // Send a test event
1560- mockCfg := & config.MockConfig {}
1561- eventData := types .NewPayload (mockCfg , map [string ]any {"test" : "value" })
1562- eventData .ExtractMetadata ()
1563-
1564- event := & types.Event {
1565- Context : context .Background (),
1566- APIHost : server .URL ,
1567- APIKey : "test-api-key" ,
1568- Dataset : "test-dataset" ,
1569- SampleRate : 1 ,
1570- Timestamp : time .Now ().UTC (),
1571- Data : eventData ,
1511+ // TestDirectTransmission_AdditionalHeaders validates that additional headers configured
1512+ // in Network.AdditionalHeaders are properly sent with HTTP requests.
1513+ // Config-level validation (reserved headers, etc.) is tested in config/config_test.go
1514+ func TestDirectTransmission_AdditionalHeaders (t * testing.T ) {
1515+ testCases := []struct {
1516+ desc string
1517+ additionalHeaders map [string ]string
1518+ }{
1519+ {
1520+ desc : "with-additional-headers" ,
1521+ additionalHeaders : map [string ]string {
1522+ "FORWARD_TO_URL" : "https://proxy.example.com" ,
1523+ "X-Custom-Header" : "custom-value" ,
1524+ },
1525+ },
1526+ {
1527+ desc : "with-empty-additional-headers" ,
1528+ additionalHeaders : map [string ]string {},
1529+ },
1530+ {
1531+ desc : "with-nil-additional-headers" ,
1532+ additionalHeaders : nil ,
1533+ },
15721534 }
1573- dt .EnqueueEvent (event )
1574-
1575- // Wait for the event to be sent
1576- require .Eventually (t , func () bool {
1577- headerMutex .Lock ()
1578- defer headerMutex .Unlock ()
1579- return capturedHeaders != nil
1580- }, 5 * time .Second , 50 * time .Millisecond , "headers should be captured" )
1581-
1582- // Verify custom headers were sent
1583- headerMutex .Lock ()
1584- defer headerMutex .Unlock ()
1585- assert .Equal (t , "https://proxy.example.com" , capturedHeaders .Get ("FORWARD_TO_URL" ))
1586- assert .Equal (t , "custom-value" , capturedHeaders .Get ("X-Custom-Header" ))
1587-
1588- // Verify standard Honeycomb headers are also present
1589- assert .Equal (t , "test-api-key" , capturedHeaders .Get ("X-Honeycomb-Team" ))
1590- assert .Equal (t , "application/msgpack" , capturedHeaders .Get ("Content-Type" ))
1591- }
1592-
1593- func TestDirectTransmitNoAdditionalHeaders (t * testing.T ) {
1594- // Create test server that captures headers
1595- var capturedHeaders http.Header
1596- var headerMutex sync.Mutex
1597-
1598- server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1599- headerMutex .Lock ()
1600- capturedHeaders = r .Header .Clone ()
1601- headerMutex .Unlock ()
1602-
1603- io .ReadAll (r .Body )
1604- r .Body .Close ()
1605-
1606- w .Header ().Set ("Content-Type" , "application/json" )
1607- w .WriteHeader (http .StatusOK )
1608- w .Write ([]byte (`[{"status": 202}]` ))
1609- }))
1610- defer server .Close ()
1611-
1612- // Create DirectTransmission without additional headers (nil)
1613- mockMetrics := & metrics.MockMetrics {}
1614- mockMetrics .Start ()
1615- mockLogger := & logger.MockLogger {}
1616-
1617- dt := NewDirectTransmission (
1618- types .TransmitTypeUpstream ,
1619- http .DefaultTransport .(* http.Transport ),
1620- 10 ,
1621- 100 * time .Millisecond ,
1622- 10 * time .Second ,
1623- false ,
1624- nil , // No additional headers
1625- )
1626- dt .Logger = mockLogger
1627- dt .Version = "test-version"
1628- dt .Metrics = mockMetrics
1629-
1630- err := dt .Start ()
1631- require .NoError (t , err )
1632- defer dt .Stop ()
1633-
1634- // Send a test event
1635- mockCfg := & config.MockConfig {}
1636- eventData := types .NewPayload (mockCfg , map [string ]any {"test" : "value" })
1637- eventData .ExtractMetadata ()
1535+ for _ , tC := range testCases {
1536+ t .Run (tC .desc , func (t * testing.T ) {
1537+ t .Parallel ()
1538+
1539+ mockMetrics := & metrics.MockMetrics {}
1540+ mockMetrics .Start ()
1541+ t .Cleanup (mockMetrics .Stop )
1542+
1543+ dt := NewDirectTransmission (
1544+ types .TransmitTypeUpstream ,
1545+ http .DefaultTransport .(* http.Transport ),
1546+ 10 ,
1547+ 100 * time .Millisecond ,
1548+ 10 * time .Second ,
1549+ false , // no compression to simplify test
1550+ tC .additionalHeaders ,
1551+ )
1552+ dt .Logger = & logger.MockLogger {}
1553+ dt .Metrics = mockMetrics
1554+ dt .Version = tC .desc + "-test"
1555+
1556+ // Store http.Header(s) received for validation outside handler
1557+ var receivedHeaders atomic.Value
1558+
1559+ capturingHeadersServer := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1560+ receivedHeaders .Store (r .Header .Clone ())
1561+
1562+ // Read and discard body
1563+ _ , _ = io .ReadAll (r .Body )
1564+ r .Body .Close ()
1565+
1566+ // Send proper response
1567+ w .Header ().Set ("Content-Type" , "application/json" )
1568+ w .WriteHeader (http .StatusOK )
1569+ w .Write ([]byte (`[{"status": 202}]` ))
1570+ }))
1571+ t .Cleanup (capturingHeadersServer .Close )
16381572
1639- event := & types.Event {
1640- Context : context .Background (),
1641- APIHost : server .URL ,
1642- APIKey : "test-api-key" ,
1643- Dataset : "test-dataset" ,
1644- SampleRate : 1 ,
1645- Timestamp : time .Now ().UTC (),
1646- Data : eventData ,
1573+ // Start the test DirectTransmission
1574+ err := dt .Start ()
1575+ require .NoError (t , err )
1576+ t .Cleanup (func () { dt .Stop () })
1577+
1578+ // Send a test event
1579+ eventData := types .NewPayload (& config.MockConfig {}, map [string ]any {"test" : "value" })
1580+ eventData .ExtractMetadata ()
1581+
1582+ event := & types.Event {
1583+ Context : context .Background (),
1584+ APIHost : capturingHeadersServer .URL ,
1585+ APIKey : "test-additional-headers" ,
1586+ Dataset : "test-dataset" ,
1587+ SampleRate : 1 ,
1588+ Timestamp : time .Now ().UTC (),
1589+ Data : eventData ,
1590+ }
1591+ dt .EnqueueEvent (event )
1592+
1593+ // Wait for the server to receive the request
1594+ require .Eventually (t , func () bool {
1595+ return receivedHeaders .Load () != nil
1596+ }, 5 * time .Second , 50 * time .Millisecond , "request with headers should have been received" )
1597+
1598+ // Validate headers
1599+ headers := receivedHeaders .Load ().(http.Header )
1600+ if len (tC .additionalHeaders ) > 0 {
1601+ for customHeaderName , customHeaderValue := range tC .additionalHeaders {
1602+ assert .Equal (t , customHeaderValue , headers .Get (customHeaderName ),
1603+ "Additional header '%s' has unexpected value" , customHeaderName )
1604+ }
1605+ }
1606+ assert .Equal (t , "test-additional-headers" , headers .Get ("X-Honeycomb-Team" ))
1607+ assert .Equal (t , "application/msgpack" , headers .Get ("Content-Type" ))
1608+ assert .Contains (t , headers .Get ("User-Agent" ), tC .desc + "-test" )
1609+ })
16471610 }
1648- dt .EnqueueEvent (event )
1649-
1650- // Wait for the event to be sent
1651- require .Eventually (t , func () bool {
1652- headerMutex .Lock ()
1653- defer headerMutex .Unlock ()
1654- return capturedHeaders != nil
1655- }, 5 * time .Second , 50 * time .Millisecond , "headers should be captured" )
1656-
1657- // Verify standard Honeycomb headers are present
1658- headerMutex .Lock ()
1659- defer headerMutex .Unlock ()
1660- assert .Equal (t , "test-api-key" , capturedHeaders .Get ("X-Honeycomb-Team" ))
1661- assert .Equal (t , "application/msgpack" , capturedHeaders .Get ("Content-Type" ))
1662-
1663- // Custom headers should not be present
1664- assert .Empty (t , capturedHeaders .Get ("FORWARD_TO_URL" ))
16651611}
0 commit comments