Skip to content
This repository has been archived by the owner on Dec 22, 2022. It is now read-only.

Commit

Permalink
Added header User Agent decoding (prebid#1268)
Browse files Browse the repository at this point in the history
* Added header User Agent decoding

* Added header User Agent decoding: unit tests

* Added header User Agent decoding: unit tests

* Added check UA is encoded to avoid `+` converted to space

Co-authored-by: Veronika Solovei <veronika.solovei@xandr.com>
  • Loading branch information
VeronikaSolovei9 and Veronika Solovei authored Apr 22, 2020
1 parent db56781 commit c5b4bf2
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 2 deletions.
16 changes: 14 additions & 2 deletions endpoints/openrtb2/video_auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import (
"io"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"strings"
"time"

"github.com/buger/jsonparser"
jsonpatch "github.com/evanphx/json-patch"
"github.com/evanphx/json-patch"
"github.com/gofrs/uuid"
"github.com/prebid/prebid-server/errortypes"

Expand Down Expand Up @@ -617,7 +618,18 @@ func (deps *endpointDeps) parseVideoRequest(request []byte, headers http.Header)

//if Device.UA is not present in request body, init it with user-agent from request header if it's present
if req.Device.UA == "" {
req.Device.UA = headers.Get("User-Agent")
ua := headers.Get("User-Agent")

//Check UA is encoded. Without it the `+` character would get changed to a space if not actually encoded
if strings.ContainsAny(ua, "%") {
var err error
req.Device.UA, err = url.QueryUnescape(ua)
if err != nil {
req.Device.UA = ua
}
} else {
req.Device.UA = ua
}
}

errL, podErrors := deps.validateVideoRequest(req)
Expand Down
43 changes: 43 additions & 0 deletions endpoints/openrtb2/video_auction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,49 @@ func TestParseVideoRequestWithoutUserAgentAndEmptyHeader(t *testing.T) {

}

func TestParseVideoRequestWithEncodedUserAgentInHeader(t *testing.T) {
ex := &mockExchangeVideo{}
reqData, err := ioutil.ReadFile("sample-requests/video/video_valid_sample_without_device_user_agent.json")
if err != nil {
t.Fatalf("Failed to fetch a valid request: %v", err)
}

uaEncoded := "Mozilla%2F5.0%20%28Macintosh%3B%20Intel%20Mac%20OS%20X%2010_14_6%29%20AppleWebKit%2F537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F78.0.3904.87%20Safari%2F537.36"
uaDecoded := "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"

headers := http.Header{}
headers.Add("User-Agent", uaEncoded)

deps := mockDeps(t, ex)
req, valErr, podErr := deps.parseVideoRequest(reqData, headers)

assert.Equal(t, uaDecoded, req.Device.UA, "Device.ua should be taken from request header")
assert.Equal(t, []error(nil), valErr, "No validation errors should be returned")
assert.Equal(t, make([]PodError, 0), podErr, "No pod errors should be returned")

}

func TestParseVideoRequestWithDecodedUserAgentInHeader(t *testing.T) {
ex := &mockExchangeVideo{}
reqData, err := ioutil.ReadFile("sample-requests/video/video_valid_sample_without_device_user_agent.json")
if err != nil {
t.Fatalf("Failed to fetch a valid request: %v", err)
}

uaDecoded := "Mozilla/5.0+(Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"

headers := http.Header{}
headers.Add("User-Agent", uaDecoded)

deps := mockDeps(t, ex)
req, valErr, podErr := deps.parseVideoRequest(reqData, headers)

assert.Equal(t, uaDecoded, req.Device.UA, "Device.ua should be taken from request header")
assert.Equal(t, []error(nil), valErr, "No validation errors should be returned")
assert.Equal(t, make([]PodError, 0), podErr, "No pod errors should be returned")

}

func TestHandleErrorDebugLog(t *testing.T) {
vo := analytics.VideoObject{
Status: 200,
Expand Down

0 comments on commit c5b4bf2

Please sign in to comment.