@@ -55,24 +55,14 @@ const (
55
55
processStartTimeHeader = "Process-Start-Time-Unix"
56
56
)
57
57
58
- type Compression int
58
+ type Compression string
59
59
60
60
const (
61
- Identity Compression = iota
62
- Gzip
63
- Zstd
61
+ Identity Compression = "identity"
62
+ Gzip Compression = "gzip"
63
+ Zstd Compression = "zstd"
64
64
)
65
65
66
- var compressions = [... ]string {
67
- "identity" ,
68
- "gzip" ,
69
- "zstd" ,
70
- }
71
-
72
- func (c Compression ) String () string {
73
- return compressions [c ]
74
- }
75
-
76
66
var defaultCompressionFormats = []Compression {Identity , Gzip , Zstd }
77
67
78
68
var gzipPool = sync.Pool {
@@ -143,6 +133,18 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO
143
133
}
144
134
}
145
135
136
+ // Select all supported compression formats
137
+ var compressions []string
138
+ if ! opts .DisableCompression {
139
+ offers := defaultCompressionFormats
140
+ if len (opts .OfferedCompressions ) > 0 {
141
+ offers = opts .OfferedCompressions
142
+ }
143
+ for _ , comp := range offers {
144
+ compressions = append (compressions , string (comp ))
145
+ }
146
+ }
147
+
146
148
h := http .HandlerFunc (func (rsp http.ResponseWriter , req * http.Request ) {
147
149
if ! opts .ProcessStartTime .IsZero () {
148
150
rsp .Header ().Set (processStartTimeHeader , strconv .FormatInt (opts .ProcessStartTime .Unix (), 10 ))
@@ -188,13 +190,17 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO
188
190
}
189
191
rsp .Header ().Set (contentTypeHeader , string (contentType ))
190
192
191
- w , err := GetWriter (req , rsp , opts .DisableCompression , opts . OfferedCompressions )
193
+ w , encodingHeader , err := NegotiateEncodingWriter (req , rsp , opts .DisableCompression , compressions )
192
194
if err != nil {
193
195
if opts .ErrorLog != nil {
194
196
opts .ErrorLog .Println ("error getting writer" , err )
195
197
}
198
+ // Since the writer received from NegotiateEncodingWriter will be nil, in case there's an error, we set it here
199
+ w = io .Writer (rsp )
196
200
}
197
201
202
+ rsp .Header ().Set (contentEncodingHeader , encodingHeader )
203
+
198
204
enc := expfmt .NewEncoder (w , contentType )
199
205
200
206
// handleError handles the error according to opts.ErrorHandling
@@ -419,48 +425,41 @@ func httpError(rsp http.ResponseWriter, err error) {
419
425
)
420
426
}
421
427
422
- func GetWriter (r * http.Request , rsp http.ResponseWriter , disableCompression bool , offeredCompressions []Compression ) (io.Writer , error ) {
428
+ func NegotiateEncodingWriter (r * http.Request , rsp http.ResponseWriter , disableCompression bool , compressions []string ) (_ io.Writer , encodingHeaderValue string , _ error ) {
423
429
w := io .Writer (rsp )
424
- rsp .Header ().Set (contentEncodingHeader , "identity" )
425
- if ! disableCompression {
426
- offers := defaultCompressionFormats
427
- if len (offeredCompressions ) > 0 {
428
- offers = offeredCompressions
429
- }
430
- var compressions []string
431
- for _ , comp := range offers {
432
- compressions = append (compressions , comp .String ())
430
+
431
+ if disableCompression {
432
+ return w , string (Identity ), nil
433
+ }
434
+
435
+ // TODO(mrueg): Replace internal/github.com/gddo once https://github.com/golang/go/issues/19307 is implemented.
436
+ compression := httputil .NegotiateContentEncoding (r , compressions )
437
+
438
+ switch compression {
439
+ case "zstd" :
440
+ // TODO(mrueg): Replace klauspost/compress with stdlib implementation once https://github.com/golang/go/issues/62513 is implemented.
441
+ z , err := zstd .NewWriter (rsp , zstd .WithEncoderLevel (zstd .SpeedFastest ))
442
+ if err != nil {
443
+ return nil , "" , err
433
444
}
434
- // TODO(mrueg): Replace internal/github.com/gddo once https://github.com/golang/go/issues/19307 is implemented.
435
- compression := httputil .NegotiateContentEncoding (r , compressions )
436
- switch compression {
437
- case "zstd" :
438
- rsp .Header ().Set (contentEncodingHeader , "zstd" )
439
- // TODO(mrueg): Replace klauspost/compress with stdlib implementation once https://github.com/golang/go/issues/62513 is implemented.
440
- z , err := zstd .NewWriter (rsp , zstd .WithEncoderLevel (zstd .SpeedFastest ))
441
- if err != nil {
442
- return nil , err
443
- }
444
445
445
- z .Reset (w )
446
- defer z .Close ()
446
+ z .Reset (w )
447
+ defer z .Close ()
447
448
448
- w = z
449
- case "gzip" :
450
- rsp .Header ().Set (contentEncodingHeader , "gzip" )
451
- gz := gzipPool .Get ().(* gzip.Writer )
452
- defer gzipPool .Put (gz )
449
+ w = z
450
+ case "gzip" :
451
+ gz := gzipPool .Get ().(* gzip.Writer )
452
+ defer gzipPool .Put (gz )
453
453
454
- gz .Reset (w )
455
- defer gz .Close ()
454
+ gz .Reset (w )
455
+ defer gz .Close ()
456
456
457
- w = gz
458
- case "identity" :
459
- // This means the content is not compressed.
460
- default :
461
- // The content encoding was not implemented yet.
462
- return w , fmt .Errorf ("content compression format not recognized: %s. Valid formats are: %s" , compression , defaultCompressionFormats )
463
- }
457
+ w = gz
458
+ case "identity" :
459
+ // This means the content is not compressed.
460
+ default :
461
+ // The content encoding was not implemented yet.
462
+ return nil , "" , fmt .Errorf ("content compression format not recognized: %s. Valid formats are: %s" , compression , defaultCompressionFormats )
464
463
}
465
- return w , nil
464
+ return w , compression , nil
466
465
}
0 commit comments