Skip to content

Commit cd2a02e

Browse files
committed
Change domain fallback and harmonized hostname extraction
1 parent 4889865 commit cd2a02e

File tree

2 files changed

+139
-10
lines changed

2 files changed

+139
-10
lines changed

src/main/java/org/prebid/server/bidder/sparteo/SparteoBidder.java

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.iab.openrtb.response.BidResponse;
1414
import com.iab.openrtb.response.SeatBid;
1515
import org.apache.commons.collections4.CollectionUtils;
16+
import org.apache.commons.lang3.StringUtils;
1617
import org.prebid.server.bidder.Bidder;
1718
import org.prebid.server.bidder.model.BidderBid;
1819
import org.prebid.server.bidder.model.BidderCall;
@@ -30,6 +31,8 @@
3031
import org.prebid.server.util.BidderUtil;
3132
import org.prebid.server.util.HttpUtil;
3233

34+
import java.net.URI;
35+
import java.net.URISyntaxException;
3336
import java.util.ArrayList;
3437
import java.util.Collection;
3538
import java.util.Collections;
@@ -185,20 +188,58 @@ private String replaceMacros(Site site, App app, String networkId) {
185188
return resolveEndpoint(domain, networkId, bundle);
186189
}
187190

191+
private static String normalizeHostname(String host) {
192+
String h = StringUtils.trimToEmpty(host);
193+
if (h.isEmpty()) {
194+
return "";
195+
}
196+
197+
String hostname = null;
198+
try {
199+
hostname = new URI(h).getHost();
200+
} catch (URISyntaxException e) {
201+
}
202+
203+
if (StringUtils.isNotEmpty(hostname)) {
204+
h = hostname;
205+
} else {
206+
if (h.contains(":")) {
207+
h = StringUtils.substringBefore(h, ":");
208+
} else {
209+
h = StringUtils.substringBefore(h, "/");
210+
}
211+
}
212+
213+
h = h.toLowerCase();
214+
h = StringUtils.removeStart(h, "www.");
215+
h = StringUtils.removeEnd(h, ".");
216+
217+
return "null".equals(h) ? "" : h;
218+
}
219+
188220
private String resolveDomain(Site site, App app) {
189221
if (site != null) {
190-
final String siteDomain = site.getDomain();
222+
final String siteDomain = normalizeHostname(site.getDomain());
191223
if (siteDomain != null && !siteDomain.isEmpty()) {
192224
return siteDomain;
193225
}
194-
final Publisher pub = site.getPublisher();
195-
if (pub != null && pub.getDomain() != null && !pub.getDomain().isEmpty()) {
196-
return pub.getDomain();
226+
}
227+
228+
if (app != null) {
229+
final String appDomain = normalizeHostname(app.getDomain());
230+
if (appDomain != null && !appDomain.isEmpty()) {
231+
return appDomain;
197232
}
233+
return null;
198234
}
199-
if (app != null && app.getDomain() != null && !app.getDomain().isEmpty()) {
200-
return app.getDomain();
235+
236+
if (site != null) {
237+
final String fromPage = normalizeHostname(site.getPage());
238+
if (fromPage != null && !fromPage.isEmpty()) {
239+
return fromPage;
240+
}
201241
}
242+
202243
return null;
203244
}
204245

src/test/java/org/prebid/server/bidder/sparteo/SparteoBidderTest.java

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -683,12 +683,12 @@ public void makeBidsShouldReturnEmptyResultWhenSeatBidHasEmptyBidList() throws J
683683
public void makeHttpRequestsShouldAppendDomainAndNetworkIdAsQueryParams() {
684684
// given
685685
final ObjectNode impExt = mapper.createObjectNode();
686-
impExt.set("bidder", mapper.createObjectNode()
687-
.put("networkId", "testNetworkId"));
686+
impExt.set("bidder", mapper.createObjectNode().put("networkId", "testNetworkId"));
688687

689688
final BidRequest bidRequest = givenBidRequest(
690689
request -> request.site(Site.builder()
691-
.publisher(Publisher.builder().domain("dev.sparteo.com").build())
690+
.domain("dev.sparteo.com")
691+
.publisher(Publisher.builder().build())
692692
.build()),
693693
givenImp(imp -> imp.ext(impExt)));
694694

@@ -700,8 +700,34 @@ public void makeHttpRequestsShouldAppendDomainAndNetworkIdAsQueryParams() {
700700
assertThat(result.getValue()).hasSize(1);
701701

702702
final String uri = result.getValue().get(0).getUri();
703+
assertThat(uri).isEqualTo(
704+
"https://test.sparteo.com/endpoint?network_id=testNetworkId&domain=dev.sparteo.com");
705+
}
706+
707+
@Test
708+
public void makeHttpRequestsShouldAppendSitePageDomainAndNetworkIdAsQueryParams() {
709+
// given
710+
final ObjectNode impExt = mapper.createObjectNode();
711+
impExt.set("bidder", mapper.createObjectNode().put("networkId", "testNetworkId"));
712+
713+
final BidRequest bidRequest = givenBidRequest(
714+
request -> request.site(Site.builder()
715+
.domain(null)
716+
.page("https://www.dev.sparteo.com:3000/p")
717+
.publisher(Publisher.builder().build())
718+
.build()),
719+
givenImp(imp -> imp.ext(impExt)));
720+
721+
// when
722+
final Result<List<HttpRequest<BidRequest>>> result = sparteoBidder.makeHttpRequests(bidRequest);
723+
724+
// then
725+
assertThat(result.getErrors()).isEmpty();
726+
assertThat(result.getValue()).hasSize(1);
703727

704-
assertThat(uri).isEqualTo("https://test.sparteo.com/endpoint?network_id=testNetworkId&domain=dev.sparteo.com");
728+
final String uri = result.getValue().get(0).getUri();
729+
assertThat(uri).isEqualTo(
730+
"https://test.sparteo.com/endpoint?network_id=testNetworkId&domain=dev.sparteo.com");
705731
}
706732

707733
@Test
@@ -920,6 +946,58 @@ public void makeHttpRequestsShouldNotAppendBundleWhenNoAppBundle() {
920946
.isEqualTo("https://test.sparteo.com/endpoint?network_id=networkId&domain=dev.sparteo.com");
921947
}
922948

949+
@Test
950+
public void normalizeHostnameShouldReturnBaseDomain() {
951+
final String base = "dev.sparteo.com";
952+
953+
// Already normalized
954+
assertThat(normalize(base)).isEqualTo(base);
955+
956+
// Case folding + trimming
957+
assertThat(normalize("DeV.SpArTeO.CoM")).isEqualTo(base);
958+
assertThat(normalize(" " + base + " ")).isEqualTo(base);
959+
960+
// Strip leading "www."
961+
assertThat(normalize("www." + base)).isEqualTo(base);
962+
assertThat(normalize("WWW." + base)).isEqualTo(base);
963+
964+
// Strip exactly ONE trailing dot
965+
assertThat(normalize(base + ".")).isEqualTo(base);
966+
// Pathological: multiple trailing dots → only one removed by the method
967+
assertThat(normalize(base + "..")).isEqualTo(base + ".");
968+
969+
// Literal "null" (any case) -> empty string
970+
assertThat(normalize("null")).isEqualTo("");
971+
assertThat(normalize("NuLl")).isEqualTo("");
972+
973+
// Empty / whitespace-only -> empty string
974+
assertThat(normalize("")).isEqualTo("");
975+
assertThat(normalize(" ")).isEqualTo("");
976+
977+
// Non-"www" prefixes are NOT stripped
978+
assertThat(normalize("www2." + base)).isEqualTo("www2." + base);
979+
980+
// Bare host + port
981+
assertThat(normalize("www." + base + ":8080")).isEqualTo(base);
982+
assertThat(normalize("DEV.SPARTEO.COM:443")).isEqualTo(base);
983+
assertThat(normalize(base + ".:8443")).isEqualTo(base); // trailing dot + port
984+
985+
// Bare host + path
986+
assertThat(normalize(base + "/some/path?x=1")).isEqualTo(base);
987+
assertThat(normalize("www." + base + "/p")).isEqualTo(base);
988+
989+
// Bare host + port + path
990+
assertThat(normalize(base + ":8080/p?q=1")).isEqualTo(base);
991+
assertThat(normalize("www." + base + ":3000/some/path")).isEqualTo(base);
992+
993+
// Absolute URLs
994+
assertThat(normalize("https://www." + base + "/x")).isEqualTo(base);
995+
assertThat(normalize("http://WWW." + base + ":8080/abc")).isEqualTo(base);
996+
997+
// Odd spacing around URL
998+
assertThat(normalize(" https://www." + base + ":3000/x ")).isEqualTo(base);
999+
}
1000+
9231001
private BidRequest givenBidRequest(UnaryOperator<BidRequest.BidRequestBuilder> customizer, Imp... imps) {
9241002
return customizer.apply(BidRequest.builder().imp(asList(imps))).build();
9251003
}
@@ -979,4 +1057,14 @@ private ObjectNode createBidExtWithEmptyPrebid() {
9791057
bidExt.set("prebid", mapper.createObjectNode());
9801058
return bidExt;
9811059
}
1060+
1061+
private static String normalize(String in) {
1062+
try {
1063+
final var m = SparteoBidder.class.getDeclaredMethod("normalizeHostname", String.class);
1064+
m.setAccessible(true);
1065+
return (String) m.invoke(null, in);
1066+
} catch (ReflectiveOperationException e) {
1067+
throw new RuntimeException("Unable to call normalizeHostname via reflection", e);
1068+
}
1069+
}
9821070
}

0 commit comments

Comments
 (0)