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