Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bidder names should be case insensitive #2400

Closed
VeronikaSolovei9 opened this issue Sep 29, 2022 · 12 comments · Fixed by #3141, #3140, #3139, #3136 or #3103
Closed

Bidder names should be case insensitive #2400

VeronikaSolovei9 opened this issue Sep 29, 2022 · 12 comments · Fixed by #3141, #3140, #3139, #3136 or #3103
Labels

Comments

@VeronikaSolovei9
Copy link
Contributor

VeronikaSolovei9 commented Sep 29, 2022

Dear community,

Right now in Prebid Server, bidder names are in mixed case.

There are many places where bidder name case appeared to be critical.
Every bidder may have different sources of configs including {bidder}.yaml, {bidder}.json, bidder related environment variables and entries in config files like pbs.json and pbs.yaml. This also applies to the {host}/info/bidders/{bidder} endpoint and bidder name in auction endpoint in req.imp[].ext.

We are seeking to increase consistency and simplicity within the system.
The bigger question is if we want to allow case insensitive bidder names or keep them case dependent.

Please share your thoughts.

@bretg
Copy link
Contributor

bretg commented Sep 30, 2022

Discussed in committee:

  • we can't lowercase the biddercode because that could cause targeting issues with ad server KVPs
  • rather, all places that compare biddercode should become case-insensitive

@bretg bretg changed the title Canonicalize bidder name case? Bidder names should be case insensitive Dec 22, 2022
@bretg bretg moved this from Triage to Ready for Dev in Prebid Server Prioritization Dec 22, 2022
@bretg
Copy link
Contributor

bretg commented Aug 2, 2023

This case-insensitive matching would work for cookie_sync as well as bidding.

@bretg
Copy link
Contributor

bretg commented Sep 5, 2023

Additional details. The case of the incoming biddercode should be insensitive wherever it's used in a comparison, including:

  • imp.ext.prebid.bidder.BIDDER
  • imp.ext.prebid.storedbidresponse
  • ext.prebid.data.bidders array
  • ext.prebid.bidderconfig.bidders array
  • ext.prebid.bidadjustmentfactors
  • ext.prebid.data.eidpermissions
  • ext.prebid.multibid.bidder and bidders
  • ext.prebid.aliases (originalBidderCode)
  • user.ext.prebid.buyeruids.BIDDER

And the request bidder code is also used in the output:

  • targeting variables (ext.prebid.targeting)
  • analytics
  • response ext.errors.BIDDER
  • responseext.warning.BIDDER
  • responseext.debug.httpcalls.BIDDER
  • responseext.responsetimemillis

@bretg
Copy link
Contributor

bretg commented Sep 27, 2023

A question came up around metrics. Though we said that in the ORTB response the biddercode should preserve the case that came in on the request, that would change metrics cardinality. There's a proposal to lowercase the biddercodes for metrics.

@bretg
Copy link
Contributor

bretg commented Sep 28, 2023

Discussed in committee and agreed that the biddercode should be normalized. Up to the developer whether this is lowercase or base adapter case.

@bretg
Copy link
Contributor

bretg commented Oct 3, 2023

Done in PBS-Java 2.0

@bretg bretg moved this from Triage to In Progress in Prebid Server Prioritization Oct 3, 2023
@bretg bretg added the PBS-Go label Oct 3, 2023
@bretg
Copy link
Contributor

bretg commented Oct 6, 2023

Discussed the scenario of multiple case structures for a single bidder in committee. The idea is that's an edge case and inconsistent input can result in inconsistent output. The code should do what's easiest.

e.g.

  • for imp-level items like targeting, use the case of the bidder offered within that imp.
  • for global items like debug/warning output, they can be separate entries.

Confirmed in the PBS-Java implmentation passing two imps, one which refers to Appnexus, the other to APPNEXUS.

bid output

{
  "seatbid": [{
     "bid": [{
           ...
          "ext": {
            "appnexus": { ... },   // base adapter case. This is fine.
            "prebid": {
              "targeting": {
                "hb_pb": "1.50",
                "hb_size_Appnexus": "300x250",        // request case
                "hb_cache_path_Appnex": "/cache",
                "hb_cache_path": "/cache",
                "hb_pb_Appnexus": "1.50",
                "hb_size": "300x250",
                "hb_cache_host_Appnex": "prebid-server-iad3.rubiconproject.com",
                "hb_bidder": "Appnexus",
                "hb_cache_id_Appnexus": "28b8ef08-5abe-498b-882f-b99aa31ce2b9",
                "hb_bidder_Appnexus": "Appnexus"
              }
       }],
      "seat": "Appnexus"
    },{
      "bid": [
        {
           ...
          "ext": {
            "appnexus": { ... }
            "prebid": {
              "type": "video",
              "targeting": {
                "hb_pb": "5.00",
                "hb_cache_path_APPNEX": "/cache",
                "hb_cache_path": "/cache",
                "hb_cache_id_APPNEXUS": "2c66e6c4-ba45-41f7-86e8-833f1837c2af",
                "hb_size": "1x1",
                "hb_size_APPNEXUS": "1x1",
                "hb_cache_host_APPNEX": "prebid-server-iad3.rubiconproject.com",
                "hb_bidder": "APPNEXUS",
                "hb_cache_id": "2c66e6c4-ba45-41f7-86e8-833f1837c2af",
                "hb_cache_host": "prebid-server-iad3.rubiconproject.com",
                "hb_pb_APPNEXUS": "5.00",
                "hb_bidder_APPNEXUS": "APPNEXUS"
                }
      ...
      "seat": "APPNEXUS",

debug/warning output

  "ext": {
    "debug": {
      "httpcalls": {
        "APPNEXUS": [ ... ]
        "Appnexus": [ ...]
       }
     },
    "responsetimemillis": {
      "APPNEXUS": 13,
      "cache": 5,
      "Appnexus": 37
    },

@SyntaxNode
Copy link
Contributor

SyntaxNode commented Oct 6, 2023

@bretg Thank you for the example. What's your thoughts on what should happen if the same adapter is included twice in the same request?

"imp": [
  {
    "id": "some-impression-id",
    "banner": {
      "format": [
        {
          "w": 600,
          "h": 500
        },
        {
          "w": 300,
          "h": 600
        }
      ]
    },
    "ext": {
      "APPnexus": {
        "placementId": 12883451
      },
      "appnexUS": {
        "placementId": 12883451
      }
    }
  }
]
  • fixed a typo. the bidder name were accidentally the same. not the point i wanted to convey.

@bretg
Copy link
Contributor

bretg commented Oct 6, 2023

That is invalid JSON -- the same attribute cannot be part of an object twice.
Whatever we do now for invalid JSON... believe it's taking the first one or the last one.

@SyntaxNode
Copy link
Contributor

That is invalid JSON -- the same attribute cannot be part of an object twice. Whatever we do now for invalid JSON... believe it's taking the first one or the last one.

It's actually valid JSON. JSON is case sensitive so this is seen as two distinct elements in the map.

We could:

  1. Accept this request taking both of these to be implicit aliases of appnexus. Might be abused to call bidders multiple times, but that's already possible today with request aliases.
  2. Reject this request. They should know better. This is not the intent of this feature.
  3. Take the first one. Problem is, maps are unordered in JSON so it's indeterminate which one will be chosen.

@bretg
Copy link
Contributor

bretg commented Oct 6, 2023

Maybe you meant to make the example have two different cases, but they both wound up 'APPnexus'.
Ok, assuming they make one of them APPnexus and one APPNEXUS, I have little sympathy for the actual outcome. My take would be "whatever's easiest". If they're all equally easy, then just accept them both and call the adapter twice.

@SyntaxNode
Copy link
Contributor

Maybe you meant to make the example have two different cases, but they both wound up 'APPnexus'.

Doh! Yes. Copy/paste error. I'll go back and edit for my question to make sense.

then just accept them both and call the adapter twice.

This is the easiest, so it shall be.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment