Repository: prebid/prebid-server
Pull request #2826 (2023-06-06 18:27:49)

YahooSSP rebranding to Yahoo Advertising.
With the yahoo SSP unit being replaced it was decided to rebrand the YahooSSP adapter with the YahooAdvertising name.
The yahoossp alias should be supported.

We also dropped the old verizonmedia alias support.


Patch:
diff --git a/adapters/yahoossp/yahoossp.go b/adapters/yahooAdvertising/yahooAdvertising.go
similarity index 93%
rename from adapters/yahoossp/yahoossp.go
rename to adapters/yahooAdvertising/yahooAdvertising.go
index 797ea708..d476adb4 100644
--- a/adapters/yahoossp/yahoossp.go
+++ b/adapters/yahooAdvertising/yahooAdvertising.go
@@ -1,4 +1,4 @@
-package yahoossp
+package yahooAdvertising
 
 import (
 	"encoding/json"
@@ -41,8 +41,8 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E
 			continue
 		}
 
-		var yahoosspExt openrtb_ext.ExtImpYahooSSP
-		err = json.Unmarshal(bidderExt.Bidder, &yahoosspExt)
+		var yahooAdvertisingExt openrtb_ext.ExtImpYahooAdvertising
+		err = json.Unmarshal(bidderExt.Bidder, &yahooAdvertisingExt)
 		if err != nil {
 			err = &errortypes.BadInput{
 				Message: fmt.Sprintf("imp #%d: %s", idx, err.Error()),
@@ -64,7 +64,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E
 			reqCopy.App = &appCopy
 		}
 
-		if err := changeRequestForBidService(&reqCopy, &yahoosspExt); err != nil {
+		if err := changeRequestForBidService(&reqCopy, &yahooAdvertisingExt); err != nil {
 			errors = append(errors, err)
 			continue
 		}
@@ -150,7 +150,7 @@ func getImpInfo(impId string, imps []openrtb2.Imp) (bool, openrtb_ext.BidType) {
 	return exists, mediaType
 }
 
-func changeRequestForBidService(request *openrtb2.BidRequest, extension *openrtb_ext.ExtImpYahooSSP) error {
+func changeRequestForBidService(request *openrtb2.BidRequest, extension *openrtb_ext.ExtImpYahooAdvertising) error {
 	/* Always override the tag ID and (site ID or app ID) of the request */
 	request.Imp[0].TagID = extension.Pos
 	if request.Site != nil {
@@ -218,7 +218,7 @@ func validateBanner(banner *openrtb2.Banner) error {
 	return nil
 }
 
-// Builder builds a new instance of the YahooSSP adapter for the given bidder with the given config.
+// Builder builds a new instance of the YahooAdvertising adapter for the given bidder with the given config.
 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
 	bidder := &adapter{
 		URI: config.Endpoint,
diff --git a/config/compression.go b/config/compression.go
new file mode 100644
index 00000000..db85202b
--- /dev/null
+++ b/config/compression.go
@@ -0,0 +1,21 @@
+package config
+
+import "github.com/prebid/prebid-server/util/httputil"
+
+type Compression struct {
+	Request  CompressionInfo `mapstructure:"request"`
+	Response CompressionInfo `mapstructure:"response"`
+}
+
+// CompressionInfo defines what types of compression algorithms are supported.
+type CompressionInfo struct {
+	GZIP bool `mapstructure:"enable_gzip"`
+}
+
+func (cfg *CompressionInfo) IsSupported(contentEncoding httputil.ContentEncoding) bool {
+	switch contentEncoding.Normalize() {
+	case httputil.ContentEncodingGZIP:
+		return cfg.GZIP
+	}
+	return false
+}
diff --git a/config/config.go b/config/config.go
index b537d128..eabf62ca 100644
--- a/config/config.go
+++ b/config/config.go
@@ -22,15 +22,16 @@ import (
 
 // Configuration specifies the static application config.
 type Configuration struct {
-	ExternalURL      string     `mapstructure:"external_url"`
-	Host             string     `mapstructure:"host"`
-	Port             int        `mapstructure:"port"`
-	UnixSocketEnable bool       `mapstructure:"unix_socket_enable"`
-	UnixSocketName   string     `mapstructure:"unix_socket_name"`
-	Client           HTTPClient `mapstructure:"http_client"`
-	CacheClient      HTTPClient `mapstructure:"http_client_cache"`
-	AdminPort        int        `mapstructure:"admin_port"`
-	EnableGzip       bool       `mapstructure:"enable_gzip"`
+	ExternalURL      string      `mapstructure:"external_url"`
+	Host             string      `mapstructure:"host"`
+	Port             int         `mapstructure:"port"`
+	UnixSocketEnable bool        `mapstructure:"unix_socket_enable"`
+	UnixSocketName   string      `mapstructure:"unix_socket_name"`
+	Client           HTTPClient  `mapstructure:"http_client"`
+	CacheClient      HTTPClient  `mapstructure:"http_client_cache"`
+	AdminPort        int         `mapstructure:"admin_port"`
+	EnableGzip       bool        `mapstructure:"enable_gzip"`
+	Compression      Compression `mapstructure:"compression"`
 	// GarbageCollectorThreshold allocates virtual memory (in bytes) which is not used by PBS but
 	// serves as a hack to trigger the garbage collector only when the heap reaches at least this size.
 	// More info: https://github.com/golang/go/issues/48409
@@ -837,7 +838,6 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) {
 	v.SetDefault("unix_socket_enable", false)              // boolean which decide if the socket-server will be started.
 	v.SetDefault("unix_socket_name", "prebid-server.sock") // path of the socket's file which must be listened.
 	v.SetDefault("admin_port", 6060)
-	v.SetDefault("enable_gzip", false)
 	v.SetDefault("garbage_collector_threshold", 0)
 	v.SetDefault("status_response", "")
 	v.SetDefault("datacenter", "")
@@ -1022,6 +1022,9 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) {
 	v.SetDefault("account_defaults.price_floors.max_schema_dims", 3)
 	v.SetDefault("account_defaults.events_enabled", false)
 
+	v.SetDefault("compression.response.enable_gzip", false)
+	v.SetDefault("compression.request.enable_gzip", false)
+
 	v.SetDefault("certificates_file", "")
 	v.SetDefault("auto_gen_source_tid", true)
 	v.SetDefault("generate_bid_id", false)
@@ -1070,6 +1073,7 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) {
 	migrateConfigSpecialFeature1(v)
 	migrateConfigTCF2PurposeFlags(v)
 	migrateConfigDatabaseConnection(v)
+	migrateConfigCompression(v)
 
 	// These defaults must be set after the migrate functions because those functions look for the presence of these
 	// config fields and there isn't a way to detect presence of a config field using the viper package if a default
@@ -1110,6 +1114,8 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) {
 	v.SetDefault("gdpr.tcf2.special_feature1.vendor_exceptions", []openrtb_ext.BidderName{})
 	v.SetDefault("price_floors.enabled", false)
 
+	v.SetDefault("enable_gzip", false)
+
 	// Defaults for account_defaults.events.default_url
 	v.SetDefault("account_defaults.events.default_url", "https://PBS_HOST/event?t=##PBS-EVENTTYPE##&vtype=##PBS-VASTEVENT##&b=##PBS-BIDID##&f=i&a=##PBS-ACCOUNTID##&ts=##PBS-TIMESTAMP##&bidder=##PBS-BIDDER##&int=##PBS-INTEGRATION##&mt=##PBS-MEDIATYPE##&ch=##PBS-CHANNEL##&aid=##PBS-AUCTIONID##&l=##PBS-LINEID##")
 
@@ -1141,6 +1147,20 @@ func migrateConfig(v *viper.Viper) {
 	}
 }
 
+func migrateConfigCompression(v *viper.Viper) {
+	oldField := "enable_gzip"
+	newField := "compression.response.enable_gzip"
+	if v.IsSet(oldField) {
+		oldConfig := v.GetBool(oldField)
+		if v.IsSet(newField) {
+			glog.Warningf("using %s and ignoring deprecated %s", newField, oldField)
+		} else {
+			glog.Warningf("%s is deprecated and should be changed to %s", oldField, newField)
+			v.Set(newField, oldConfig)
+		}
+	}
+}
+
 func migrateConfigPurposeOneTreatment(v *viper.Viper) {
 	if oldConfig, ok := v.Get("gdpr.tcf2.purpose_one_treatement").(map[string]interface{}); ok {
 		if v.IsSet("gdpr.tcf2.purpose_one_treatment") {
diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go
index 962c72d4..46a31138 100644
--- a/endpoints/openrtb2/auction.go
+++ b/endpoints/openrtb2/auction.go
@@ -1,11 +1,13 @@
 package openrtb2
 
 import (
+	"compress/gzip"
 	"context"
 	"encoding/json"
 	"errors"
 	"fmt"
 	"io"
+	"io/ioutil"
 	"net/http"
 	"net/url"
 	"regexp"
@@ -340,28 +342,49 @@ func sendAuctionResponse(
 //
 // If the errors list has at least one element, then no guarantees are made about the returned request.
 func (deps *endpointDeps) parseRequest(httpRequest *http.Request, labels *metrics.Labels, hookExecutor hookexecution.HookStageExecutor) (req *openrtb_ext.RequestWrapper, impExtInfoMap map[string]exchange.ImpExtInfo, storedAuctionResponses stored_responses.ImpsWithBidResponses, storedBidResponses stored_responses.ImpBidderStoredResp, bidderImpReplaceImpId stored_responses.BidderImpReplaceImpID, account *config.Account, errs []error) {
-	req = &openrtb_ext.RequestWrapper{}
-	req.BidRequest = &openrtb2.BidRequest{}
 	errs = nil
-
-	// Pull the request body into a buffer, so we have it for later usage.
-	lr := &io.LimitedReader{
-		R: httpRequest.Body,
+	var err error
+	var r io.ReadCloser = httpRequest.Body
+	reqContentEncoding := httputil.ContentEncoding(httpRequest.Header.Get("Content-Encoding"))
+	if reqContentEncoding != "" {
+		if !deps.cfg.Compression.Request.IsSupported(reqContentEncoding) {
+			errs = []error{fmt.Errorf("Content-Encoding of type %s is not supported", reqContentEncoding)}
+			return
+		} else {
+			r, err = getCompressionEnabledReader(httpRequest.Body, reqContentEncoding)
+			if err != nil {
+				errs = []error{err}
+				return
+			}
+		}
+	}
+	defer r.Close()
+	limitedReqReader := &io.LimitedReader{
+		R: r,
 		N: deps.cfg.MaxRequestSize,
 	}
-	requestJson, err := io.ReadAll(lr)
+
+	requestJson, err := ioutil.ReadAll(limitedReqReader)
 	if err != nil {
 		errs = []error{err}
 		return
 	}
-	// If the request size was too large, read through the rest of the request body so that the connection can be reused.
-	if lr.N <= 0 {
-		if written, err := io.Copy(io.Discard, httpRequest.Body); written > 0 || err != nil {
-			errs = []error{fmt.Errorf("Request size exceeded max size of %d bytes.", deps.cfg.MaxRequestSize)}
+
+	if limitedReqReader.N <= 0 {
+		// Limited Reader returns 0 if the request was exactly at the max size or over the limit.
+		// This is because it only reads up to N bytes. To check if the request was too large,
+		//  we need to look at the next byte of its underlying reader, limitedReader.R.
+		if _, err := limitedReqReader.R.Read(make([]byte, 1)); err != io.EOF {
+			// Discard the rest of the request body so that the connection can be reused.
+			io.Copy(io.Discard, httpRequest.Body)
+			errs = []error{fmt.Errorf("request size exceeded max size of %d bytes.", deps.cfg.MaxRequestSize)}
 			return
 		}
 	}
 
+	req = &openrtb_ext.RequestWrapper{}
+	req.BidRequest = &openrtb2.BidRequest{}
+
 	requestJson, rejectErr := hookExecutor.ExecuteEntrypointStage(httpRequest, requestJson)
 	if rejectErr != nil {
 		errs = []error{rejectErr}
@@ -472,6 +495,15 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request, labels *metric
 	return
 }
 
+func getCompressionEnabledReader(body io.ReadCloser, contentEncoding httputil.ContentEncoding) (io.ReadCloser, error) {
+	switch contentEncoding {
+	case httputil.ContentEncodingGZIP:
+		return gzip.NewReader(body)
+	default:
+		return nil, fmt.Errorf("unsupported compression type '%s'", contentEncoding)
+	}
+}
+
 // hasPayloadUpdatesAt checks if there are any successful payload updates at given stage
 func hasPayloadUpdatesAt(stageName string, outcomes []hookexecution.StageOutcome) bool {
 	for _, outcome := range outcomes {
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index a9f54710..4e47b77e 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -166,7 +166,7 @@ import (
 	"github.com/prebid/prebid-server/adapters/visx"
 	"github.com/prebid/prebid-server/adapters/vrtcal"
 	"github.com/prebid/prebid-server/adapters/xeworks"
-	"github.com/prebid/prebid-server/adapters/yahoossp"
+	"github.com/prebid/prebid-server/adapters/yahooAdvertising"
 	"github.com/prebid/prebid-server/adapters/yeahmobi"
 	"github.com/prebid/prebid-server/adapters/yieldlab"
 	"github.com/prebid/prebid-server/adapters/yieldmo"
@@ -258,6 +258,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderEngageBDR:         engagebdr.Builder,
 		openrtb_ext.BidderEPlanning:         eplanning.Builder,
 		openrtb_ext.BidderEpom:              epom.Builder,
+		openrtb_ext.BidderEpsilon:           conversant.Builder,
 		openrtb_ext.BidderEVolution:         evolution.Builder,
 		openrtb_ext.BidderEvtech:            limelightDigital.Builder,
 		openrtb_ext.BidderFlipp:             flipp.Builder,
@@ -352,7 +353,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderUnicorn:           unicorn.Builder,
 		openrtb_ext.BidderUnruly:            unruly.Builder,
 		openrtb_ext.BidderValueImpression:   apacdex.Builder,
-		openrtb_ext.BidderVerizonMedia:      yahoossp.Builder,
 		openrtb_ext.BidderVideoByte:         videobyte.Builder,
 		openrtb_ext.BidderVideoHeroes:       videoheroes.Builder,
 		openrtb_ext.BidderVidoomy:           vidoomy.Builder,
@@ -361,7 +361,8 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderVisx:              visx.Builder,
 		openrtb_ext.BidderVrtcal:            vrtcal.Builder,
 		openrtb_ext.BidderXeworks:           xeworks.Builder,
-		openrtb_ext.BidderYahooSSP:          yahoossp.Builder,
+		openrtb_ext.BidderYahooAdvertising:  yahooAdvertising.Builder,
+		openrtb_ext.BidderYahooSSP:          yahooAdvertising.Builder,
 		openrtb_ext.BidderYeahmobi:          yeahmobi.Builder,
 		openrtb_ext.BidderYieldlab:          yieldlab.Builder,
 		openrtb_ext.BidderYieldmo:           yieldmo.Builder,
diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go
index 4876cef7..33904aae 100644
--- a/exchange/adapter_util.go
+++ b/exchange/adapter_util.go
@@ -88,7 +88,7 @@ func GetDisabledBiddersErrorMessages(infos config.BidderInfos) map[string]string
 		"lifestreet":     `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`,
 		"adagio":         `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`,
 		"somoaudience":   `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`,
-		"yssp":           `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahoossp" in your configuration.`,
+		"yssp":           `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAdvertising" in your configuration.`,
 		"andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`,
 		"oftmedia":       `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`,
 		"groupm":         `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`,
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index 9f74a710..2e585de8 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -162,6 +162,7 @@ const (
 	BidderEmxDigital        BidderName = "emx_digital"
 	BidderEngageBDR         BidderName = "engagebdr"
 	BidderEPlanning         BidderName = "eplanning"
+	BidderEpsilon           BidderName = "epsilon"
 	BidderEpom              BidderName = "epom"
 	BidderEVolution         BidderName = "e_volution"
 	BidderEvtech            BidderName = "evtech"
@@ -257,7 +258,6 @@ const (
 	BidderUnicorn           BidderName = "unicorn"
 	BidderUnruly            BidderName = "unruly"
 	BidderValueImpression   BidderName = "valueimpression"
-	BidderVerizonMedia      BidderName = "verizonmedia"
 	BidderVideoByte         BidderName = "videobyte"
 	BidderVideoHeroes       BidderName = "videoheroes"
 	BidderVidoomy           BidderName = "vidoomy"
@@ -266,6 +266,7 @@ const (
 	BidderVisx              BidderName = "visx"
 	BidderVrtcal            BidderName = "vrtcal"
 	BidderXeworks           BidderName = "xeworks"
+	BidderYahooAdvertising  BidderName = "yahooAdvertising"
 	BidderYahooSSP          BidderName = "yahoossp"
 	BidderYeahmobi          BidderName = "yeahmobi"
 	BidderYieldlab          BidderName = "yieldlab"
@@ -355,6 +356,7 @@ func CoreBidderNames() []BidderName {
 		BidderEngageBDR,
 		BidderEPlanning,
 		BidderEpom,
+		BidderEpsilon,
 		BidderEVolution,
 		BidderEvtech,
 		BidderFlipp,
@@ -449,7 +451,6 @@ func CoreBidderNames() []BidderName {
 		BidderUnicorn,
 		BidderUnruly,
 		BidderValueImpression,
-		BidderVerizonMedia,
 		BidderVideoByte,
 		BidderVideoHeroes,
 		BidderVidoomy,
@@ -458,6 +459,7 @@ func CoreBidderNames() []BidderName {
 		BidderVisx,
 		BidderVrtcal,
 		BidderXeworks,
+		BidderYahooAdvertising,
 		BidderYahooSSP,
 		BidderYeahmobi,
 		BidderYieldlab,
diff --git a/openrtb_ext/imp_verizonmedia.go b/openrtb_ext/imp_verizonmedia.go
deleted file mode 100644
index 2ae8e5ea..00000000
--- a/openrtb_ext/imp_verizonmedia.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package openrtb_ext
-
-// ExtImpVerizonMedia defines the contract for bidrequest.imp[i].ext.prebid.bidder.verizonmedia
-type ExtImpVerizonMedia struct {
-	Dcn string `json:"dcn"`
-	Pos string `json:"pos"`
-}
diff --git a/openrtb_ext/imp_yahooAdvertising.go b/openrtb_ext/imp_yahooAdvertising.go
new file mode 100644
index 00000000..e0e8614a
--- /dev/null
+++ b/openrtb_ext/imp_yahooAdvertising.go
@@ -0,0 +1,7 @@
+package openrtb_ext
+
+// ExtImpYahooAdvertising defines the contract for bidrequest.imp[i].ext.prebid.bidder.yahooAdvertising
+type ExtImpYahooAdvertising struct {
+	Dcn string `json:"dcn"`
+	Pos string `json:"pos"`
+}
diff --git a/privacy/enforcement.go b/privacy/enforcement.go
index e1669f78..50d42e89 100644
--- a/privacy/enforcement.go
+++ b/privacy/enforcement.go
@@ -69,17 +69,9 @@ func (e Enforcement) getGeoScrubStrategy() ScrubStrategyGeo {
 }
 
 func (e Enforcement) getUserScrubStrategy() ScrubStrategyUser {
-	if e.COPPA {
+	if e.COPPA || e.CCPA || e.LMT || e.GDPRID {
 		return ScrubStrategyUserIDAndDemographic
 	}
 
-	if e.CCPA || e.LMT {
-		return ScrubStrategyUserID
-	}
-
-	if e.GDPRID {
-		return ScrubStrategyUserID
-	}
-
 	return ScrubStrategyUserNone
 }
diff --git a/privacy/scrubber.go b/privacy/scrubber.go
index c2ea7d63..428193bc 100644
--- a/privacy/scrubber.go
+++ b/privacy/scrubber.go
@@ -55,9 +55,6 @@ const (
 
 	// ScrubStrategyUserIDAndDemographic removes the user's buyer id, exchange id year of birth, and gender.
 	ScrubStrategyUserIDAndDemographic
-
-	// ScrubStrategyUserID removes the user's buyer id.
-	ScrubStrategyUserID
 )
 
 // ScrubStrategyDeviceID defines the approach to remove hardware id and device id data.
@@ -131,17 +128,12 @@ func (scrubber) ScrubUser(user *openrtb2.User, strategy ScrubStrategyUser, geo S
 
 	userCopy := *user
 
-	switch strategy {
-	case ScrubStrategyUserIDAndDemographic:
+	if strategy == ScrubStrategyUserIDAndDemographic {
 		userCopy.BuyerUID = ""
 		userCopy.ID = ""
 		userCopy.Ext = scrubUserExtIDs(userCopy.Ext)
 		userCopy.Yob = 0
 		userCopy.Gender = ""
-	case ScrubStrategyUserID:
-		userCopy.BuyerUID = ""
-		userCopy.ID = ""
-		userCopy.Ext = scrubUserExtIDs(userCopy.Ext)
 	}
 
 	switch geo {
diff --git a/server/server.go b/server/server.go
index ce77fdc8..31764cc4 100644
--- a/server/server.go
+++ b/server/server.go
@@ -91,10 +91,7 @@ func newAdminServer(cfg *config.Configuration, handler http.Handler) *http.Serve
 }
 
 func newMainServer(cfg *config.Configuration, handler http.Handler) *http.Server {
-	var serverHandler = handler
-	if cfg.EnableGzip {
-		serverHandler = gziphandler.GzipHandler(handler)
-	}
+	serverHandler := getCompressionEnabledHandler(handler, cfg.Compression.Response)
 
 	return &http.Server{
 		Addr:         cfg.Host + ":" + strconv.Itoa(cfg.Port),
@@ -106,10 +103,7 @@ func newMainServer(cfg *config.Configuration, handler http.Handler) *http.Server
 }
 
 func newSocketServer(cfg *config.Configuration, handler http.Handler) *http.Server {
-	var serverHandler = handler
-	if cfg.EnableGzip {
-		serverHandler = gziphandler.GzipHandler(handler)
-	}
+	serverHandler := getCompressionEnabledHandler(handler, cfg.Compression.Response)
 
 	return &http.Server{
 		Addr:         cfg.UnixSocketName,
@@ -119,6 +113,13 @@ func newSocketServer(cfg *config.Configuration, handler http.Handler) *http.Serv
 	}
 }
 
+func getCompressionEnabledHandler(h http.Handler, compressionInfo config.CompressionInfo) http.Handler {
+	if compressionInfo.GZIP {
+		h = gziphandler.GzipHandler(h)
+	}
+	return h
+}
+
 func runServer(server *http.Server, name string, listener net.Listener) (err error) {
 	if server == nil {
 		err = fmt.Errorf(">> Server is a nil_ptr.")
diff --git a/static/bidder-info/conversant.yaml b/static/bidder-info/conversant.yaml
index da003b25..2135544d 100644
--- a/static/bidder-info/conversant.yaml
+++ b/static/bidder-info/conversant.yaml
@@ -1,6 +1,6 @@
 endpoint: "http://api.hb.ad.cpe.dotomi.com/cvx/server/hb/ortb/25"
 maintainer:
-  email: "CNVR_PublisherIntegration@conversantmedia.com"
+  email: "PublisherIntegration@epsilon.com"
 gvlVendorID: 24
 capabilities:
   app:
@@ -15,4 +15,4 @@ userSync:
   redirect:
     url: "https://prebid-match.dotomi.com/match/bounce/current?version=1&networkId=72582&rurl={{.RedirectURL}}"
     userMacro: ""
-    # conversant appends the user id to end of the redirect url and does not utilize a macro
+    # epsilon appends the user id to end of the redirect url and does not utilize a macro
diff --git a/static/bidder-info/epsilon.yaml b/static/bidder-info/epsilon.yaml
new file mode 100644
index 00000000..856d82a6
--- /dev/null
+++ b/static/bidder-info/epsilon.yaml
@@ -0,0 +1,18 @@
+endpoint: "http://api.hb.ad.cpe.dotomi.com/cvx/server/hb/ortb/25"
+maintainer:
+  email: "PublisherIntegration@epsilon.com"
+gvlVendorID: 24
+capabilities:
+  app:
+    mediaTypes:
+      - banner
+      - video
+  site:
+    mediaTypes:
+      - banner
+      - video
+userSync:
+  redirect:
+    url: "https://prebid-match.dotomi.com/match/bounce/current?version=1&networkId=72582&rurl={{.RedirectURL}}"
+    userMacro: ""
+    # epsilon/conversant appends the user id to end of the redirect url and does not utilize a macro
diff --git a/static/bidder-info/verizonmedia.yaml b/static/bidder-info/verizonmedia.yaml
deleted file mode 100644
index 9be15b84..00000000
--- a/static/bidder-info/verizonmedia.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-disabled: true
-maintainer:
-  email: "dsp-supply-prebid@verizonmedia.com"
-gvlVendorID: 25
-capabilities:
-  app:
-    mediaTypes:
-      - banner
-  site:
-    mediaTypes:
-      - banner
-userSync:
-  # verizonmedia supports user syncing, but requires configuration by the host. contact this
-  # bidder directly at the email address in this file to ask about enabling user sync.
-  supports:
-    - redirect
\ No newline at end of file
diff --git a/static/bidder-info/yahooAdvertising.yaml b/static/bidder-info/yahooAdvertising.yaml
new file mode 100644
index 00000000..3798adf7
--- /dev/null
+++ b/static/bidder-info/yahooAdvertising.yaml
@@ -0,0 +1,18 @@
+endpoint: "https://s2shb.ssp.yahoo.com/admax/bid/partners/PBS"
+maintainer:
+  email: "hb-fe-tech@yahooinc.com"
+gvlVendorID: 25
+capabilities:
+  app:
+    mediaTypes:
+      - banner
+      - video
+  site:
+    mediaTypes:
+      - banner
+      - video
+userSync:
+  # yahooAdvertising supports user syncing, but requires configuration by the host. contact this
+  # bidder directly at the email address in this file to ask about enabling user sync.
+  supports:
+    - redirect
\ No newline at end of file
diff --git a/static/bidder-params/conversant.json b/static/bidder-params/conversant.json
index ba9c6bd5..883ef053 100644
--- a/static/bidder-params/conversant.json
+++ b/static/bidder-params/conversant.json
@@ -1,12 +1,12 @@
 {
   "$schema": "http://json-schema.org/draft-04/schema#",
-  "title": "Conversant Adapter Params",
-  "description": "A schema which validates params accepted by the Conversant adapter.",
+  "title": "Epsilon (formerly Conversant) Adapter Params",
+  "description": "A schema which validates params accepted by the Epsilon (Conversant) adapter.",
   "type": "object",
   "properties": {
     "site_id": {
       "type": "string",
-      "description": "A Conversant specific ID which identifies the site."
+      "description": "An Epsilon (Conversant) specific ID which identifies the site."
     },
    	"secure": {
    	  "type": "integer",
diff --git a/static/bidder-params/epsilon.json b/static/bidder-params/epsilon.json
new file mode 100644
index 00000000..a33a6832
--- /dev/null
+++ b/static/bidder-params/epsilon.json
@@ -0,0 +1,54 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "title": "Epsilon Adapter Params",
+  "description": "A schema which validates params accepted by the Epsilon adapter.",
+  "type": "object",
+  "properties": {
+    "site_id": {
+      "type": "string",
+      "description": "An Epsilon specific ID which identifies the site."
+    },
+    "secure": {
+      "type": "integer",
+      "description": "Override http/https context on ad markup."
+    },
+    "bidfloor" : {
+      "type": "number",
+      "description": "Minimum bid price that will be considered."
+    },
+    "tag_id": {
+      "type": "string",
+      "description": "Identifies specific ad placement."
+    },
+    "position": {
+      "type": "integer",
+      "description": "Ad position on screen."
+    },
+    "mimes": {
+      "type": "array",
+      "description": "Array of content MIME types.  For videos only.",
+      "items": {
+        "type": "string"
+      }
+    },
+    "maxduration": {
+      "type": "integer",
+      "description": "Maximum duration in seconds.  For videos only."
+    },
+    "api": {
+      "type": "array",
+      "description": "Array of supported API frameworks.  For videos only.",
+      "items": {
+        "type": "integer"
+      }
+    },
+    "protocols": {
+      "type": "array",
+      "description": "Array of supported video protocols.  For videos only.",
+      "items": {
+        "type": "integer"
+      }
+    }
+  },
+  "required": ["site_id"]
+}
\ No newline at end of file
diff --git a/static/bidder-params/verizonmedia.json b/static/bidder-params/yahooAdvertising.json
similarity index 75%
rename from static/bidder-params/verizonmedia.json
rename to static/bidder-params/yahooAdvertising.json
index 96649f08..4778f077 100644
--- a/static/bidder-params/verizonmedia.json
+++ b/static/bidder-params/yahooAdvertising.json
@@ -1,15 +1,17 @@
 {
 	"$schema": "http://json-schema.org/draft-04/schema#",
-	"title": "VerizonMedia Adapter Params",
-	"description": "A schema which validates params accepted by the VerizonMedia adapter",
+	"title": "YahooAdvertising Adapter Params",
+	"description": "A schema which validates params accepted by the YahooAdvertising adapter",
 	"type": "object",
 	"properties": {
 		"dcn": {
 			"type": "string",
+			"minLength": 1,
 			"description": "Site ID provided by One Mobile"
 		},
 		"pos": {
 			"type": "string",
+			"minLength": 1,
 			"description": "Placement ID"
 		}
 	},
diff --git a/util/httputil/httputil.go b/util/httputil/httputil.go
index 99236489..28334a54 100644
--- a/util/httputil/httputil.go
+++ b/util/httputil/httputil.go
@@ -14,6 +14,16 @@ var (
 	xRealIP       = http.CanonicalHeaderKey("X-Real-IP")
 )
 
+type ContentEncoding string
+
+const (
+	ContentEncodingGZIP ContentEncoding = "gzip"
+)
+
+func (k ContentEncoding) Normalize() ContentEncoding {
+	return ContentEncoding(strings.ToLower(string(k)))
+}
+
 // FindIP returns the first ip address found in the http request matching the predicate v.
 func FindIP(r *http.Request, v iputil.IPValidator) (net.IP, iputil.IPVersion) {
 	if ip, ver := findTrueClientIP(r, v); ip != nil {


Test patch:
diff --git a/adapters/yahoossp/params_test.go b/adapters/yahooAdvertising/params_test.go
similarity index 63%
rename from adapters/yahoossp/params_test.go
rename to adapters/yahooAdvertising/params_test.go
index 47d8d268..10d504cb 100644
--- a/adapters/yahoossp/params_test.go
+++ b/adapters/yahooAdvertising/params_test.go
@@ -1,4 +1,4 @@
-package yahoossp
+package yahooAdvertising
 
 import (
 	"encoding/json"
@@ -7,11 +7,11 @@ import (
 	"github.com/prebid/prebid-server/openrtb_ext"
 )
 
-// This file actually intends to test static/bidder-params/yahoossp.json
+// This file actually intends to test static/bidder-params/yahooAdvertising.json
 //
-// These also validate the format of the external API: request.imp[i].ext.yahoossp
+// These also validate the format of the external API: request.imp[i].ext.yahooAdvertising
 
-// TestValidParams makes sure that the yahoossp schema accepts all imp.ext fields which we intend to support.
+// TestValidParams makes sure that the yahooAdvertising schema accepts all imp.ext fields which we intend to support.
 func TestValidParams(t *testing.T) {
 	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
 	if err != nil {
@@ -19,13 +19,13 @@ func TestValidParams(t *testing.T) {
 	}
 
 	for _, validParam := range validParams {
-		if err := validator.Validate(openrtb_ext.BidderYahooSSP, json.RawMessage(validParam)); err != nil {
-			t.Errorf("Schema rejected yahoossp params: %s", validParam)
+		if err := validator.Validate(openrtb_ext.BidderYahooAdvertising, json.RawMessage(validParam)); err != nil {
+			t.Errorf("Schema rejected yahooAdvertising params: %s", validParam)
 		}
 	}
 }
 
-// TestInvalidParams makes sure that the yahoossp schema rejects all the imp.ext fields we don't support.
+// TestInvalidParams makes sure that the yahooAdvertising schema rejects all the imp.ext fields we don't support.
 func TestInvalidParams(t *testing.T) {
 	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
 	if err != nil {
@@ -33,7 +33,7 @@ func TestInvalidParams(t *testing.T) {
 	}
 
 	for _, invalidParam := range invalidParams {
-		if err := validator.Validate(openrtb_ext.BidderYahooSSP, json.RawMessage(invalidParam)); err == nil {
+		if err := validator.Validate(openrtb_ext.BidderYahooAdvertising, json.RawMessage(invalidParam)); err == nil {
 			t.Errorf("Schema allowed unexpected params: %s", invalidParam)
 		}
 	}
diff --git a/adapters/yahoossp/yahoossp_test.go b/adapters/yahooAdvertising/yahooAdvertising_test.go
similarity index 51%
rename from adapters/yahoossp/yahoossp_test.go
rename to adapters/yahooAdvertising/yahooAdvertising_test.go
index eeb739c6..e701c333 100644
--- a/adapters/yahoossp/yahoossp_test.go
+++ b/adapters/yahooAdvertising/yahooAdvertising_test.go
@@ -1,4 +1,4 @@
-package yahoossp
+package yahooAdvertising
 
 import (
 	"testing"
@@ -10,8 +10,8 @@ import (
 	"github.com/prebid/prebid-server/openrtb_ext"
 )
 
-func TestYahooSSPBidderEndpointConfig(t *testing.T) {
-	bidder, buildErr := Builder(openrtb_ext.BidderYahooSSP, config.Adapter{
+func TestYahooAdvertisingBidderEndpointConfig(t *testing.T) {
+	bidder, buildErr := Builder(openrtb_ext.BidderYahooAdvertising, config.Adapter{
 		Endpoint: "http://localhost/bid",
 	}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
 
@@ -19,17 +19,17 @@ func TestYahooSSPBidderEndpointConfig(t *testing.T) {
 		t.Fatalf("Builder returned unexpected error %v", buildErr)
 	}
 
-	bidderYahooSSP := bidder.(*adapter)
+	bidderYahooAdvertising := bidder.(*adapter)
 
-	assert.Equal(t, "http://localhost/bid", bidderYahooSSP.URI)
+	assert.Equal(t, "http://localhost/bid", bidderYahooAdvertising.URI)
 }
 
 func TestJsonSamples(t *testing.T) {
-	bidder, buildErr := Builder(openrtb_ext.BidderYahooSSP, config.Adapter{}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+	bidder, buildErr := Builder(openrtb_ext.BidderYahooAdvertising, config.Adapter{}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
 
 	if buildErr != nil {
 		t.Fatalf("Builder returned unexpected error %v", buildErr)
 	}
 
-	adapterstest.RunJSONBidderTest(t, "yahoossptest", bidder)
+	adapterstest.RunJSONBidderTest(t, "yahooAdvertisingtest", bidder)
 }
diff --git a/adapters/yahoossp/yahoossptest/exemplary/simple-app-banner.json b/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-app-banner.json
similarity index 98%
rename from adapters/yahoossp/yahoossptest/exemplary/simple-app-banner.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-app-banner.json
index 319e22e3..d5e77c71 100644
--- a/adapters/yahoossp/yahoossptest/exemplary/simple-app-banner.json
+++ b/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-app-banner.json
@@ -77,7 +77,7 @@
           "id": "test-request-id",
           "seatbid": [
             {
-              "seat": "yahoossp",
+              "seat": "yahooAdvertising",
               "bid": [{
                 "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
                 "impid": "test-imp-id",
diff --git a/adapters/yahoossp/yahoossptest/exemplary/simple-banner.json b/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-banner.json
similarity index 98%
rename from adapters/yahoossp/yahoossptest/exemplary/simple-banner.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-banner.json
index 344bbe9a..d08bdf06 100644
--- a/adapters/yahoossp/yahoossptest/exemplary/simple-banner.json
+++ b/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-banner.json
@@ -77,7 +77,7 @@
           "id": "test-request-id",
           "seatbid": [
             {
-              "seat": "yahoossp",
+              "seat": "yahooAdvertising",
               "bid": [{
                 "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
                 "impid": "test-imp-id",
diff --git a/adapters/yahoossp/yahoossptest/exemplary/simple-video.json b/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-video.json
similarity index 98%
rename from adapters/yahoossp/yahoossptest/exemplary/simple-video.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-video.json
index d6227264..ea95ec40 100644
--- a/adapters/yahoossp/yahoossptest/exemplary/simple-video.json
+++ b/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-video.json
@@ -92,7 +92,7 @@
           "id": "test-request-id",
           "seatbid": [
             {
-              "seat": "yahoossp",
+              "seat": "yahooAdvertising",
               "bid": [{
                 "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
                 "impid": "test-imp-id",
diff --git a/adapters/yahoossp/yahoossptest/supplemental/empty-banner-format.json b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/empty-banner-format.json
similarity index 100%
rename from adapters/yahoossp/yahoossptest/supplemental/empty-banner-format.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/empty-banner-format.json
diff --git a/adapters/yahoossp/yahoossptest/supplemental/invalid-banner-height.json b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/invalid-banner-height.json
similarity index 100%
rename from adapters/yahoossp/yahoossptest/supplemental/invalid-banner-height.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/invalid-banner-height.json
diff --git a/adapters/yahoossp/yahoossptest/supplemental/invalid-banner-width.json b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/invalid-banner-width.json
similarity index 100%
rename from adapters/yahoossp/yahoossptest/supplemental/invalid-banner-width.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/invalid-banner-width.json
diff --git a/adapters/yahoossp/yahoossptest/supplemental/non-supported-requests-bids-ignored.json b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/non-supported-requests-bids-ignored.json
similarity index 98%
rename from adapters/yahoossp/yahoossptest/supplemental/non-supported-requests-bids-ignored.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/non-supported-requests-bids-ignored.json
index 11a93f68..a44020da 100644
--- a/adapters/yahoossp/yahoossptest/supplemental/non-supported-requests-bids-ignored.json
+++ b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/non-supported-requests-bids-ignored.json
@@ -74,7 +74,7 @@
           "id": "test-request-id",
           "seatbid": [
             {
-              "seat": "yahoossp",
+              "seat": "yahooAdvertising",
               "bid": [{
                 "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
                 "impid": "test-imp-id",
diff --git a/adapters/yahoossp/yahoossptest/supplemental/required-nobidder-info.json b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/required-nobidder-info.json
similarity index 100%
rename from adapters/yahoossp/yahoossptest/supplemental/required-nobidder-info.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/required-nobidder-info.json
diff --git a/adapters/yahoossp/yahoossptest/supplemental/server-error.json b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/server-error.json
similarity index 100%
rename from adapters/yahoossp/yahoossptest/supplemental/server-error.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/server-error.json
diff --git a/adapters/yahoossp/yahoossptest/supplemental/server-response-wrong-impid.json b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/server-response-wrong-impid.json
similarity index 98%
rename from adapters/yahoossp/yahoossptest/supplemental/server-response-wrong-impid.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/server-response-wrong-impid.json
index 5b33f3af..1fcf61e1 100644
--- a/adapters/yahoossp/yahoossptest/supplemental/server-response-wrong-impid.json
+++ b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/server-response-wrong-impid.json
@@ -76,7 +76,7 @@
           "id": "test-request-id",
           "seatbid": [
             {
-              "seat": "yahoossp",
+              "seat": "yahooAdvertising",
               "bid": [{
                 "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
                 "impid": "wrong",
diff --git a/adapters/yahoossp/yahoossptest/supplemental/simple-banner-gpp-overwrite.json b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp-overwrite.json
similarity index 98%
rename from adapters/yahoossp/yahoossptest/supplemental/simple-banner-gpp-overwrite.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp-overwrite.json
index ffc7ae65..190f96bf 100644
--- a/adapters/yahoossp/yahoossptest/supplemental/simple-banner-gpp-overwrite.json
+++ b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp-overwrite.json
@@ -92,7 +92,7 @@
           "id": "test-request-id",
           "seatbid": [
             {
-              "seat": "yahoossp",
+              "seat": "yahooAdvertising",
               "bid": [{
                 "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
                 "impid": "test-imp-id",
diff --git a/adapters/yahoossp/yahoossptest/supplemental/simple-banner-gpp.json b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp.json
similarity index 98%
rename from adapters/yahoossp/yahoossptest/supplemental/simple-banner-gpp.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp.json
index 88f97d11..81c89f55 100644
--- a/adapters/yahoossp/yahoossptest/supplemental/simple-banner-gpp.json
+++ b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp.json
@@ -87,7 +87,7 @@
           "id": "test-request-id",
           "seatbid": [
             {
-              "seat": "yahoossp",
+              "seat": "yahooAdvertising",
               "bid": [{
                 "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
                 "impid": "test-imp-id",
diff --git a/adapters/yahoossp/yahoossptest/supplemental/simple-banner-ignore-width-when-height-missing.json b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-ignore-width-when-height-missing.json
similarity index 98%
rename from adapters/yahoossp/yahoossptest/supplemental/simple-banner-ignore-width-when-height-missing.json
rename to adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-ignore-width-when-height-missing.json
index 16e64c61..353d5e29 100644
--- a/adapters/yahoossp/yahoossptest/supplemental/simple-banner-ignore-width-when-height-missing.json
+++ b/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-ignore-width-when-height-missing.json
@@ -78,7 +78,7 @@
           "id": "test-request-id",
           "seatbid": [
             {
-              "seat": "yahoossp",
+              "seat": "yahooAdvertising",
               "bid": [{
                 "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
                 "impid": "test-imp-id",
diff --git a/config/compression_test.go b/config/compression_test.go
new file mode 100644
index 00000000..cd9048cd
--- /dev/null
+++ b/config/compression_test.go
@@ -0,0 +1,47 @@
+package config
+
+import (
+	"testing"
+
+	"github.com/prebid/prebid-server/util/httputil"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestReqCompressionCfgIsSupported(t *testing.T) {
+	testCases := []struct {
+		description     string
+		cfg             CompressionInfo
+		contentEncoding httputil.ContentEncoding
+		wantSupported   bool
+	}{
+		{
+			description: "Compression type not supported",
+			cfg: CompressionInfo{
+				GZIP: true,
+			},
+			contentEncoding: httputil.ContentEncoding("invalid"),
+			wantSupported:   false,
+		},
+		{
+			description: "Compression type supported",
+			cfg: CompressionInfo{
+				GZIP: true,
+			},
+			contentEncoding: httputil.ContentEncodingGZIP,
+			wantSupported:   true,
+		},
+		{
+			description: "Compression not enabled",
+			cfg: CompressionInfo{
+				GZIP: false,
+			},
+			contentEncoding: httputil.ContentEncodingGZIP,
+			wantSupported:   false,
+		},
+	}
+
+	for _, test := range testCases {
+		got := test.cfg.IsSupported(test.contentEncoding)
+		assert.Equal(t, got, test.wantSupported, test.description)
+	}
+}
diff --git a/config/config_test.go b/config/config_test.go
index 64f4f8a0..402f9ada 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -179,6 +179,11 @@ func TestDefaults(t *testing.T) {
 	//Assert the price floor default values
 	cmpBools(t, "price_floors.enabled", false, cfg.PriceFloors.Enabled)
 
+	// Assert compression related defaults
+	cmpBools(t, "enable_gzip", false, cfg.EnableGzip)
+	cmpBools(t, "compression.request.enable_gzip", false, cfg.Compression.Request.GZIP)
+	cmpBools(t, "compression.response.enable_gzip", false, cfg.Compression.Response.GZIP)
+
 	cmpBools(t, "account_defaults.price_floors.enabled", false, cfg.AccountDefaults.PriceFloors.Enabled)
 	cmpInts(t, "account_defaults.price_floors.enforce_floors_rate", 100, cfg.AccountDefaults.PriceFloors.EnforceFloorsRate)
 	cmpBools(t, "account_defaults.price_floors.adjust_for_bid_adjustment", true, cfg.AccountDefaults.PriceFloors.AdjustForBidAdjustment)
@@ -378,6 +383,12 @@ external_url: http://prebid-server.prebid.org/
 host: prebid-server.prebid.org
 port: 1234
 admin_port: 5678
+enable_gzip: false
+compression:
+    request:
+        enable_gzip: true
+    response:
+        enable_gzip: false
 garbage_collector_threshold: 1
 datacenter: "1"
 auction_timeouts_ms:
@@ -572,6 +583,11 @@ func TestFullConfig(t *testing.T) {
 	cmpBools(t, "account_defaults.events_enabled", *cfg.AccountDefaults.EventsEnabled, true)
 	cmpNils(t, "account_defaults.events.enabled", cfg.AccountDefaults.Events.Enabled)
 
+	// Assert compression related defaults
+	cmpBools(t, "enable_gzip", false, cfg.EnableGzip)
+	cmpBools(t, "compression.request.enable_gzip", true, cfg.Compression.Request.GZIP)
+	cmpBools(t, "compression.response.enable_gzip", false, cfg.Compression.Response.GZIP)
+
 	//Assert the NonStandardPublishers was correctly unmarshalled
 	assert.Equal(t, []string{"pub1", "pub2"}, cfg.GDPR.NonStandardPublishers, "gdpr.non_standard_publishers")
 	assert.Equal(t, map[string]struct{}{"pub1": {}, "pub2": {}}, cfg.GDPR.NonStandardPublisherMap, "gdpr.non_standard_publishers Hash Map")
@@ -2547,7 +2563,8 @@ func TestMigrateConfigDatabaseQueryParams(t *testing.T) {
 
 	v := viper.New()
 	v.SetConfigType("yaml")
-	v.ReadConfig(bytes.NewBuffer(config))
+	err := v.ReadConfig(bytes.NewBuffer(config))
+	assert.NoError(t, err)
 
 	migrateConfigDatabaseConnection(v)
 
@@ -2570,6 +2587,74 @@ func TestMigrateConfigDatabaseQueryParams(t *testing.T) {
 	assert.Equal(t, want_queries.poll_for_updates_amp_query, v.GetString("stored_responses.database.poll_for_updates.amp_query"))
 }
 
+func TestMigrateConfigCompression(t *testing.T) {
+	testCases := []struct {
+		desc                string
+		config              []byte
+		wantEnableGZIP      bool
+		wantReqGZIPEnabled  bool
+		wantRespGZIPEnabled bool
+	}{
+
+		{
+			desc:                "New config and old config not set",
+			config:              []byte{},
+			wantEnableGZIP:      false,
+			wantReqGZIPEnabled:  false,
+			wantRespGZIPEnabled: false,
+		},
+		{
+			desc: "Old config set, new config not set",
+			config: []byte(`
+                    enable_gzip: true
+                    `),
+			wantEnableGZIP:      true,
+			wantRespGZIPEnabled: true,
+			wantReqGZIPEnabled:  false,
+		},
+		{
+			desc: "Old config not set, new config set",
+			config: []byte(`
+                    compression:
+                        response:
+                            enable_gzip: true
+                        request:
+                            enable_gzip: false
+                    `),
+			wantEnableGZIP:      false,
+			wantRespGZIPEnabled: true,
+			wantReqGZIPEnabled:  false,
+		},
+		{
+			desc: "Old config set and new config set",
+			config: []byte(`
+                    enable_gzip: true
+                    compression:
+                        response:
+                            enable_gzip: false
+                        request:
+                            enable_gzip: true
+                    `),
+			wantEnableGZIP:      true,
+			wantRespGZIPEnabled: false,
+			wantReqGZIPEnabled:  true,
+		},
+	}
+
+	for _, test := range testCases {
+		v := viper.New()
+		v.SetConfigType("yaml")
+		err := v.ReadConfig(bytes.NewBuffer(test.config))
+		assert.NoError(t, err)
+
+		migrateConfigCompression(v)
+
+		assert.Equal(t, test.wantEnableGZIP, v.GetBool("enable_gzip"), test.desc)
+		assert.Equal(t, test.wantReqGZIPEnabled, v.GetBool("compression.request.enable_gzip"), test.desc)
+		assert.Equal(t, test.wantRespGZIPEnabled, v.GetBool("compression.response.enable_gzip"), test.desc)
+	}
+}
+
 func TestIsConfigInfoPresent(t *testing.T) {
 	configPrefix1Field2Only := []byte(`
       prefix1:
diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go
index 6d1ebcdb..6be85a99 100644
--- a/endpoints/openrtb2/auction_test.go
+++ b/endpoints/openrtb2/auction_test.go
@@ -2,6 +2,7 @@ package openrtb2
 
 import (
 	"bytes"
+	"compress/gzip"
 	"context"
 	"encoding/json"
 	"errors"
@@ -3895,6 +3896,105 @@ func TestParseRequestParseImpInfoError(t *testing.T) {
 	assert.Contains(t, errL[0].Error(), "echovideoattrs of type bool", "Incorrect error message")
 }
 
+func TestParseGzipedRequest(t *testing.T) {
+	testCases :=
+		[]struct {
+			desc           string
+			reqContentEnc  string
+			maxReqSize     int64
+			compressionCfg config.Compression
+			expectedErr    string
+		}{
+			{
+				desc:           "Gzip compression enabled, request size exceeds max request size",
+				reqContentEnc:  "gzip",
+				maxReqSize:     10,
+				compressionCfg: config.Compression{Request: config.CompressionInfo{GZIP: true}},
+				expectedErr:    "request size exceeded max size of 10 bytes.",
+			},
+			{
+				desc:           "Gzip compression enabled, request size is within max request size",
+				reqContentEnc:  "gzip",
+				maxReqSize:     2000,
+				compressionCfg: config.Compression{Request: config.CompressionInfo{GZIP: true}},
+				expectedErr:    "",
+			},
+			{
+				desc:           "Gzip compression enabled, request size is within max request size, content-encoding value not in lower case",
+				reqContentEnc:  "GZIP",
+				maxReqSize:     2000,
+				compressionCfg: config.Compression{Request: config.CompressionInfo{GZIP: true}},
+				expectedErr:    "",
+			},
+			{
+				desc:           "Request is Gzip compressed, but Gzip compression is disabled",
+				reqContentEnc:  "gzip",
+				compressionCfg: config.Compression{Request: config.CompressionInfo{GZIP: false}},
+				expectedErr:    "Content-Encoding of type gzip is not supported",
+			},
+			{
+				desc:           "Request is not Gzip compressed, but Gzip compression is enabled",
+				reqContentEnc:  "",
+				maxReqSize:     2000,
+				compressionCfg: config.Compression{Request: config.CompressionInfo{GZIP: true}},
+				expectedErr:    "",
+			},
+		}
+
+	reqBody := []byte(validRequest(t, "site.json"))
+	deps := &endpointDeps{
+		fakeUUIDGenerator{},
+		&warningsCheckExchange{},
+		mockBidderParamValidator{},
+		&mockStoredReqFetcher{},
+		empty_fetcher.EmptyFetcher{},
+		empty_fetcher.EmptyFetcher{},
+		&config.Configuration{MaxRequestSize: int64(50), Compression: config.Compression{Request: config.CompressionInfo{GZIP: false}}},
+		&metricsConfig.NilMetricsEngine{},
+		analyticsConf.NewPBSAnalytics(&config.Analytics{}),
+		map[string]string{},
+		false,
+		[]byte{},
+		openrtb_ext.BuildBidderMap(),
+		nil,
+		nil,
+		hardcodedResponseIPValidator{response: true},
+		empty_fetcher.EmptyFetcher{},
+		hooks.EmptyPlanBuilder{},
+	}
+
+	hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine)
+	for _, test := range testCases {
+		var req *http.Request
+		deps.cfg.MaxRequestSize = test.maxReqSize
+		deps.cfg.Compression = test.compressionCfg
+		if test.reqContentEnc == "gzip" {
+			var compressed bytes.Buffer
+			gw := gzip.NewWriter(&compressed)
+			_, err := gw.Write(reqBody)
+			assert.NoError(t, err, "Error writing gzip compressed request body", test.desc)
+			assert.NoError(t, gw.Close(), "Error closing gzip writer", test.desc)
+
+			req = httptest.NewRequest("POST", "/openrtb2/auction", bytes.NewReader(compressed.Bytes()))
+			req.Header.Set("Content-Encoding", "gzip")
+		} else {
+			req = httptest.NewRequest("POST", "/openrtb2/auction", bytes.NewReader(reqBody))
+		}
+		resReq, impExtInfoMap, _, _, _, _, errL := deps.parseRequest(req, &metrics.Labels{}, hookExecutor)
+
+		if test.expectedErr == "" {
+			assert.Nil(t, errL, "Error list should be nil", test.desc)
+			assert.NotNil(t, resReq, "Result request should not be nil", test.desc)
+			assert.NotNil(t, impExtInfoMap, "Impression info map should not be nil", test.desc)
+		} else {
+			assert.Nil(t, resReq, "Result request should be nil due to incorrect imp", test.desc)
+			assert.Nil(t, impExtInfoMap, "Impression info map should be nil due to incorrect imp", test.desc)
+			assert.Len(t, errL, 1, "One error should be returned", test.desc)
+			assert.Contains(t, errL[0].Error(), test.expectedErr, "Incorrect error message", test.desc)
+		}
+	}
+}
+
 func TestValidateNativeContextTypes(t *testing.T) {
 	impIndex := 4
 
diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go
index b08a85de..43cefeec 100644
--- a/exchange/adapter_util_test.go
+++ b/exchange/adapter_util_test.go
@@ -210,7 +210,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) {
 				"lifestreet":     `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`,
 				"adagio":         `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`,
 				"somoaudience":   `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`,
-				"yssp":           `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahoossp" in your configuration.`,
+				"yssp":           `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAdvertising" in your configuration.`,
 				"andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`,
 				"oftmedia":       `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`,
 				"groupm":         `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`,
@@ -223,7 +223,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) {
 				"lifestreet":     `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`,
 				"adagio":         `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`,
 				"somoaudience":   `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`,
-				"yssp":           `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahoossp" in your configuration.`,
+				"yssp":           `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAdvertising" in your configuration.`,
 				"andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`,
 				"oftmedia":       `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`,
 				"groupm":         `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`,
@@ -236,7 +236,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) {
 				"lifestreet":     `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`,
 				"adagio":         `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`,
 				"somoaudience":   `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`,
-				"yssp":           `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahoossp" in your configuration.`,
+				"yssp":           `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAdvertising" in your configuration.`,
 				"appnexus":       `Bidder "appnexus" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`,
 				"andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`,
 				"oftmedia":       `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`,
@@ -250,7 +250,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) {
 				"lifestreet":     `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`,
 				"adagio":         `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`,
 				"somoaudience":   `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`,
-				"yssp":           `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahoossp" in your configuration.`,
+				"yssp":           `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAdvertising" in your configuration.`,
 				"appnexus":       `Bidder "appnexus" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`,
 				"andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`,
 				"oftmedia":       `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`,
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index f9117eca..6fe0e55f 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -2294,6 +2294,7 @@ func TestCleanOpenRTBRequestsWithOpenRTBDowngrade(t *testing.T) {
 	bidReq.Regs.GPPSID = []int8{6}
 	bidReq.User.ID = ""
 	bidReq.User.BuyerUID = ""
+	bidReq.User.Yob = 0
 
 	downgradedRegs := *bidReq.Regs
 	downgradedUser := *bidReq.User
diff --git a/privacy/enforcement_test.go b/privacy/enforcement_test.go
index 5902a913..a9d7ca92 100644
--- a/privacy/enforcement_test.go
+++ b/privacy/enforcement_test.go
@@ -95,7 +95,7 @@ func TestApply(t *testing.T) {
 			expectedDeviceIPv4: ScrubStrategyIPV4Lowest8,
 			expectedDeviceIPv6: ScrubStrategyIPV6Lowest16,
 			expectedDeviceGeo:  ScrubStrategyGeoReducedPrecision,
-			expectedUser:       ScrubStrategyUserID,
+			expectedUser:       ScrubStrategyUserIDAndDemographic,
 			expectedUserGeo:    ScrubStrategyGeoReducedPrecision,
 		},
 		{
@@ -127,7 +127,7 @@ func TestApply(t *testing.T) {
 			expectedDeviceIPv4: ScrubStrategyIPV4Lowest8,
 			expectedDeviceIPv6: ScrubStrategyIPV6Lowest16,
 			expectedDeviceGeo:  ScrubStrategyGeoReducedPrecision,
-			expectedUser:       ScrubStrategyUserID,
+			expectedUser:       ScrubStrategyUserIDAndDemographic,
 			expectedUserGeo:    ScrubStrategyGeoReducedPrecision,
 		},
 		{
@@ -143,7 +143,7 @@ func TestApply(t *testing.T) {
 			expectedDeviceIPv4: ScrubStrategyIPV4None,
 			expectedDeviceIPv6: ScrubStrategyIPV6None,
 			expectedDeviceGeo:  ScrubStrategyGeoNone,
-			expectedUser:       ScrubStrategyUserID,
+			expectedUser:       ScrubStrategyUserIDAndDemographic,
 			expectedUserGeo:    ScrubStrategyGeoNone,
 		},
 		{
@@ -175,7 +175,7 @@ func TestApply(t *testing.T) {
 			expectedDeviceIPv4: ScrubStrategyIPV4Lowest8,
 			expectedDeviceIPv6: ScrubStrategyIPV6Lowest16,
 			expectedDeviceGeo:  ScrubStrategyGeoReducedPrecision,
-			expectedUser:       ScrubStrategyUserID,
+			expectedUser:       ScrubStrategyUserIDAndDemographic,
 			expectedUserGeo:    ScrubStrategyGeoReducedPrecision,
 		},
 		{
diff --git a/privacy/scrubber_test.go b/privacy/scrubber_test.go
index d8f2fdd8..7b4afac2 100644
--- a/privacy/scrubber_test.go
+++ b/privacy/scrubber_test.go
@@ -269,57 +269,6 @@ func TestScrubUser(t *testing.T) {
 			scrubUser: ScrubStrategyUserIDAndDemographic,
 			scrubGeo:  ScrubStrategyGeoNone,
 		},
-		{
-			description: "User ID & Geo Full",
-			expected: &openrtb2.User{
-				ID:       "",
-				BuyerUID: "",
-				Yob:      42,
-				Gender:   "anyGender",
-				Ext:      json.RawMessage(`{}`),
-				Geo:      &openrtb2.Geo{},
-			},
-			scrubUser: ScrubStrategyUserID,
-			scrubGeo:  ScrubStrategyGeoFull,
-		},
-		{
-			description: "User ID & Geo Reduced",
-			expected: &openrtb2.User{
-				ID:       "",
-				BuyerUID: "",
-				Yob:      42,
-				Gender:   "anyGender",
-				Ext:      json.RawMessage(`{}`),
-				Geo: &openrtb2.Geo{
-					Lat:   123.46,
-					Lon:   678.89,
-					Metro: "some metro",
-					City:  "some city",
-					ZIP:   "some zip",
-				},
-			},
-			scrubUser: ScrubStrategyUserID,
-			scrubGeo:  ScrubStrategyGeoReducedPrecision,
-		},
-		{
-			description: "User ID & Geo None",
-			expected: &openrtb2.User{
-				ID:       "",
-				BuyerUID: "",
-				Yob:      42,
-				Gender:   "anyGender",
-				Ext:      json.RawMessage(`{}`),
-				Geo: &openrtb2.Geo{
-					Lat:   123.456,
-					Lon:   678.89,
-					Metro: "some metro",
-					City:  "some city",
-					ZIP:   "some zip",
-				},
-			},
-			scrubUser: ScrubStrategyUserID,
-			scrubGeo:  ScrubStrategyGeoNone,
-		},
 		{
 			description: "User None & Geo Full",
 			expected: &openrtb2.User{