@@ -19,12 +19,11 @@ import (
19
19
// data collection and sends it to the Signal Sciences Agent for
20
20
// inspection.
21
21
type Module struct {
22
- config * ModuleConfig
23
- handler http.Handler
24
- inspector Inspector
25
- inspInit InspectorInitFunc
26
- inspFini InspectorFiniFunc
27
- headerExtractor HeaderExtractorFunc
22
+ config * ModuleConfig
23
+ handler http.Handler
24
+ inspector Inspector
25
+ inspInit InspectorInitFunc
26
+ inspFini InspectorFiniFunc
28
27
}
29
28
30
29
// NewModule wraps an existing http.Handler with one that extracts data and
@@ -39,12 +38,11 @@ func NewModule(h http.Handler, options ...ModuleConfigOption) (*Module, error) {
39
38
40
39
// The following are the defaults, overridden by passing in functional options
41
40
m := Module {
42
- handler : h ,
43
- config : config ,
44
- inspector : config .Inspector (),
45
- inspInit : config .InspectorInit (),
46
- inspFini : config .InspectorFini (),
47
- headerExtractor : config .HeaderExtractor (),
41
+ handler : h ,
42
+ config : config ,
43
+ inspector : config .Inspector (),
44
+ inspInit : config .InspectorInit (),
45
+ inspFini : config .InspectorFini (),
48
46
}
49
47
50
48
// By default, use an RPC based inspector if not configured externally
@@ -169,8 +167,7 @@ func (m *Module) ServeHTTP(w http.ResponseWriter, req *http.Request) {
169
167
if m .config .Debug () {
170
168
log .Printf ("DEBUG: calling 'RPC.PostRequest' due to anomaly: method=%s host=%s url=%s code=%d size=%d duration=%s" , req .Method , req .Host , req .URL , code , size , duration )
171
169
}
172
- inspin := NewRPCMsgIn (req , nil , code , size , duration , m .config .ModuleIdentifier (), m .config .ServerIdentifier ())
173
- m .extractHeaders (req , inspin )
170
+ inspin := NewRPCMsgIn (m .config , req , nil , code , size , duration )
174
171
inspin .WAFResponse = wafresponse
175
172
inspin .HeadersOut = convertHeaders (rw .Header ())
176
173
@@ -225,8 +222,7 @@ func (m *Module) inspectorPreRequest(req *http.Request) (inspin2 RPCMsgIn2, out
225
222
req .Body = ioutil .NopCloser (bytes .NewBuffer (reqbody ))
226
223
}
227
224
228
- inspin := NewRPCMsgInWithModuleConfig (m .config , req , reqbody )
229
- m .extractHeaders (req , inspin )
225
+ inspin := NewRPCMsgIn (m .config , req , reqbody , - 1 , - 1 , 0 )
230
226
231
227
if m .config .Debug () {
232
228
log .Printf ("DEBUG: Making PreRequest call to inspector: %s %s" , inspin .Method , inspin .URI )
@@ -276,20 +272,6 @@ func (m *Module) inspectorPreRequest(req *http.Request) (inspin2 RPCMsgIn2, out
276
272
return
277
273
}
278
274
279
- func (m * Module ) extractHeaders (req * http.Request , inspin * RPCMsgIn ) {
280
- // If the user supplied a custom header extractor, use it to unpack the
281
- // headers. If there no custom header extractor or it returns an error,
282
- // fallback to the native headers on the request.
283
- if m .headerExtractor != nil {
284
- hin , err := m .headerExtractor (req )
285
- if err == nil {
286
- inspin .HeadersIn = convertHeaders (hin )
287
- } else if m .config .Debug () {
288
- log .Printf ("DEBUG: Error extracting custom headers, using native headers: %s" , err )
289
- }
290
- }
291
- }
292
-
293
275
// inspectorPostRequest makes a postrequest call to the inspector
294
276
func (m * Module ) inspectorPostRequest (inspin * RPCMsgIn ) error {
295
277
// Create message to agent from the input request
@@ -329,93 +311,42 @@ func (m *Module) inspectorUpdateRequest(inspin RPCMsgIn2) error {
329
311
// NewRPCMsgIn creates a message from a go http.Request object
330
312
// End-users of the golang module never need to use this
331
313
// directly and it is only exposed for performance testing
332
- func NewRPCMsgIn (r * http.Request , postbody []byte , code int , size int64 , dur time.Duration , module , server string ) * RPCMsgIn {
314
+ func NewRPCMsgIn (mcfg * ModuleConfig , r * http.Request , postbody []byte , code int , size int64 , dur time.Duration ) * RPCMsgIn {
333
315
now := time .Now ()
334
316
335
- // assemble a message to send to inspector
336
- tlsProtocol := ""
337
- tlsCipher := ""
338
- scheme := "http"
339
- if r .TLS != nil {
340
- // convert golang/spec integers into something human readable
341
- scheme = "https"
342
- tlsProtocol = tlstext .Version (r .TLS .Version )
343
- tlsCipher = tlstext .CipherSuite (r .TLS .CipherSuite )
344
- }
345
-
346
- // golang removes Host header from req.Header map and
347
- // promotes it to r.Host field. Add it back as the first header.
348
- hin := convertHeaders (r .Header )
349
- if len (r .Host ) > 0 {
350
- hin = append ([][2 ]string {{"Host" , r .Host }}, hin ... )
351
- }
352
-
353
- return & RPCMsgIn {
354
- ModuleVersion : module ,
355
- ServerVersion : server ,
317
+ msgIn := RPCMsgIn {
318
+ ModuleVersion : mcfg .ModuleIdentifier (),
319
+ ServerVersion : mcfg .ServerIdentifier (),
320
+ ServerFlavor : mcfg .ServerFlavor (),
356
321
ServerName : r .Host ,
357
322
Timestamp : now .Unix (),
358
- NowMillis : now .UnixNano () / 1e6 ,
323
+ NowMillis : now .UnixMilli () ,
359
324
RemoteAddr : stripPort (r .RemoteAddr ),
360
325
Method : r .Method ,
361
- Scheme : scheme ,
362
326
URI : r .RequestURI ,
363
327
Protocol : r .Proto ,
364
- TLSProtocol : tlsProtocol ,
365
- TLSCipher : tlsCipher ,
366
328
ResponseCode : int32 (code ),
367
- ResponseMillis : int64 ( dur / time . Millisecond ),
329
+ ResponseMillis : dur . Milliseconds ( ),
368
330
ResponseSize : size ,
369
331
PostBody : string (postbody ),
370
- HeadersIn : hin ,
371
332
}
372
- }
373
-
374
- // NewRPCMsgInWithModuleConfig creates a message from a ModuleConfig object
375
- // End-users of the golang module never need to use this
376
- // directly and it is only exposed for performance testing
377
- func NewRPCMsgInWithModuleConfig (mcfg * ModuleConfig , r * http.Request , postbody []byte ) * RPCMsgIn {
378
-
379
- now := time .Now ()
380
333
381
- // assemble a message to send to inspector
382
- tlsProtocol := ""
383
- tlsCipher := ""
384
- scheme := "http"
385
334
if r .TLS != nil {
386
335
// convert golang/spec integers into something human readable
387
- scheme = "https"
388
- tlsProtocol = tlstext .Version (r .TLS .Version )
389
- tlsCipher = tlstext .CipherSuite (r .TLS .CipherSuite )
336
+ msgIn .Scheme = "https"
337
+ msgIn .TLSProtocol = tlstext .Version (r .TLS .Version )
338
+ msgIn .TLSCipher = tlstext .CipherSuite (r .TLS .CipherSuite )
339
+ } else {
340
+ msgIn .Scheme = "http"
390
341
}
391
342
392
- // golang removes Host header from req.Header map and
393
- // promotes it to r.Host field. Add it back as the first header.
394
- hin := convertHeaders (r .Header )
395
- if len (r .Host ) > 0 {
396
- hin = append ([][2 ]string {{"Host" , r .Host }}, hin ... )
343
+ if hdrs := mcfg .RawHeaderExtractor (); hdrs != nil {
344
+ msgIn .HeadersIn = hdrs (r )
397
345
}
398
-
399
- return & RPCMsgIn {
400
- ModuleVersion : mcfg .ModuleIdentifier (),
401
- ServerVersion : mcfg .ServerIdentifier (),
402
- ServerFlavor : mcfg .ServerFlavor (),
403
- ServerName : r .Host ,
404
- Timestamp : now .Unix (),
405
- NowMillis : now .UnixNano () / 1e6 ,
406
- RemoteAddr : stripPort (r .RemoteAddr ),
407
- Method : r .Method ,
408
- Scheme : scheme ,
409
- URI : r .RequestURI ,
410
- Protocol : r .Proto ,
411
- TLSProtocol : tlsProtocol ,
412
- TLSCipher : tlsCipher ,
413
- ResponseCode : - 1 ,
414
- ResponseMillis : 0 ,
415
- ResponseSize : - 1 ,
416
- PostBody : string (postbody ),
417
- HeadersIn : hin ,
346
+ if msgIn .HeadersIn == nil {
347
+ msgIn .HeadersIn = requestHeader (r )
418
348
}
349
+ return & msgIn
419
350
}
420
351
421
352
// stripPort removes any port from an address (e.g., the client port from the RemoteAddr)
@@ -505,6 +436,22 @@ func inspectableContentType(s string) bool {
505
436
return false
506
437
}
507
438
439
+ // requestHeader returns request headers with host header
440
+ func requestHeader (r * http.Request ) [][2 ]string {
441
+ out := make ([][2 ]string , 0 , len (r .Header )+ 1 )
442
+ // golang removes Host header from req.Header map and
443
+ // promotes it to r.Host field. Add it back as the first header.
444
+ if len (r .Host ) > 0 {
445
+ out = append (out , [2 ]string {"Host" , r .Host })
446
+ }
447
+ for key , values := range r .Header {
448
+ for _ , value := range values {
449
+ out = append (out , [2 ]string {key , value })
450
+ }
451
+ }
452
+ return out
453
+ }
454
+
508
455
// converts a http.Header map to a [][2]string
509
456
func convertHeaders (h http.Header ) [][2 ]string {
510
457
// get headers
0 commit comments