Skip to content

Commit

Permalink
Workaround for bug in iOS 14 related to setting LMT flag (#1159)
Browse files Browse the repository at this point in the history
  • Loading branch information
schernysh authored Feb 23, 2021
1 parent a18f9d8 commit 9a3723f
Show file tree
Hide file tree
Showing 5 changed files with 374 additions and 22 deletions.
94 changes: 91 additions & 3 deletions src/main/java/org/prebid/server/auction/AuctionRequestFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.prebid.server.log.ConditionalLogger;
import org.prebid.server.metric.MetricName;
import org.prebid.server.privacy.model.PrivacyContext;
import org.prebid.server.proto.openrtb.ext.request.ExtDevice;
import org.prebid.server.proto.openrtb.ext.request.ExtMediaTypePriceGranularity;
import org.prebid.server.proto.openrtb.ext.request.ExtPriceGranularity;
import org.prebid.server.proto.openrtb.ext.request.ExtPublisher;
Expand Down Expand Up @@ -276,7 +277,7 @@ BidRequest fillImplicitParameters(BidRequest bidRequest, RoutingContext context,
final HttpServerRequest request = context.request();

final Device device = bidRequest.getDevice();
final Device populatedDevice = populateDevice(device, request);
final Device populatedDevice = populateDevice(device, bidRequest.getApp(), request);

final Site site = bidRequest.getSite();
final Site populatedSite = bidRequest.getApp() != null ? null : populateSite(site, request);
Expand Down Expand Up @@ -334,7 +335,7 @@ private void checkBlacklistedApp(BidRequest bidRequest) {
* Populates the request body's 'device' section from the incoming http request if the original is partially filled
* and the request contains necessary info (User-Agent, IP-address).
*/
private Device populateDevice(Device device, HttpServerRequest request) {
private Device populateDevice(Device device, App app, HttpServerRequest request) {
final String deviceIp = device != null ? device.getIp() : null;
final String deviceIpv6 = device != null ? device.getIpv6() : null;

Expand All @@ -352,10 +353,13 @@ private Device populateDevice(Device device, HttpServerRequest request) {

final String ua = device != null ? device.getUa() : null;
final Integer dnt = resolveDntHeader(request);
final Integer lmt = resolveLmt(device, app);

if (!Objects.equals(deviceIp, resolvedIp)
|| !Objects.equals(deviceIpv6, resolvedIpv6)
|| StringUtils.isBlank(ua) || dnt != null) {
|| StringUtils.isBlank(ua)
|| dnt != null
|| lmt != null) {

final Device.DeviceBuilder builder = device == null ? Device.builder() : device.toBuilder();

Expand All @@ -366,6 +370,10 @@ private Device populateDevice(Device device, HttpServerRequest request) {
builder.dnt(dnt);
}

if (lmt != null) {
builder.lmt(lmt);
}

builder
.ip(resolvedIp)
.ipv6(resolvedIpv6);
Expand Down Expand Up @@ -405,6 +413,86 @@ private void logWarnIfNoIp(String resolvedIp, String resolvedIpv6) {
}
}

private Integer resolveLmt(Device device, App app) {
if (app == null || device == null || !StringUtils.equalsIgnoreCase(device.getOs(), "ios")) {
return null;
}

final String osv = device.getOsv();
if (osv == null) {
return null;
}

// osv format expected: "[major].[minor]". Example: 14.0
final String[] versionParts = StringUtils.split(osv, '.');
if (versionParts.length != 2) {
return null;
}

final Integer versionMajor = tryParse(versionParts[0]);
final Integer versionMinor = tryParse(versionParts[1]);
if (versionMajor == null || versionMinor == null) {
return null;
}

if (versionMajor < 14) {
return null;
}

return resolveLmtForIos14AndHigher(device, versionMinor);
}

private static Integer tryParse(String number) {
try {
return Integer.parseUnsignedInt(number);
} catch (NumberFormatException e) {
return null;
}
}

private Integer resolveLmtForIos14AndHigher(Device device, Integer versionMinor) {
if (versionMinor == 0 || versionMinor == 1) {
return resolveLmtForIos14Minor0And1(device);
}

if (versionMinor >= 2) {
return resolveLmtForIos14Minor2AndHigher(device);
}

return null;
}

private static Integer resolveLmtForIos14Minor0And1(Device device) {
final String ifa = device.getIfa();
final Integer lmt = device.getLmt();

if (StringUtils.isEmpty(ifa) || ifa.equals("00000000-0000-0000-0000-000000000000")) {
return !Objects.equals(lmt, 1) ? 1 : null;
}

return !Objects.equals(lmt, 0) ? 0 : null;
}

private static Integer resolveLmtForIos14Minor2AndHigher(Device device) {
final ExtDevice deviceExt = device.getExt();
final Integer atts = deviceExt != null ? deviceExt.getAtts() : null;
final Integer lmt = device.getLmt();

if (atts == null) {
return null;
}

if (atts == 1 || atts == 2) {
return !Objects.equals(lmt, 1) ? 1 : null;
}

if (atts == 0 || atts == 3) {
return !Objects.equals(lmt, 0) ? 0 : null;
}

return null;
}

/**
* Populates the request body's 'site' section from the incoming http request if the original is partially filled
* and the request contains necessary info (domain, page).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
@ToString(callSuper = true)
public class ExtDevice extends FlexibleExtension {

Integer atts;

ExtDevicePrebid prebid;

public static ExtDevice empty() {
return of(null);
return of(null, null);
}
}
Loading

0 comments on commit 9a3723f

Please sign in to comment.