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

Fix/cmcd nor #3747

Merged
merged 4 commits into from
Sep 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 37 additions & 1 deletion src/core/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
* @ignore
*/

import path from 'path-browserify'

class Utils {
static mixin(dest, source, copy) {
let s;
Expand Down Expand Up @@ -96,7 +98,7 @@ class Utils {
}
}

static parseHttpHeaders (headerStr) {
static parseHttpHeaders(headerStr) {
let headers = {};
if (!headerStr) {
return headers;
Expand Down Expand Up @@ -139,6 +141,40 @@ class Utils {
}
return hash;
}

/**
* Compares both urls and returns a relative url (target relative to original)
* @param {string} original
* @param {string} target
* @return {string|*}
*/
static getRelativeUrl(originalUrl, targetUrl) {
try {
const original = new URL(originalUrl);
const target = new URL(targetUrl);

// Unify the protocol to compare the origins
original.protocol = target.protocol;
if (original.origin !== target.origin) {
return targetUrl;
}

// Use the relative path implementation of the path library. We need to cut off the actual filename in the end to get the relative path
let relativePath = path.relative(original.pathname.substr(0, original.pathname.lastIndexOf('/')), target.pathname.substr(0, target.pathname.lastIndexOf('/')));

// In case the relative path is empty (both path are equal) return the filename only. Otherwise add a slash in front of the filename
const startIndexOffset = relativePath.length === 0 ? 1 : 0;
relativePath += target.pathname.substr(target.pathname.lastIndexOf('/') + startIndexOffset, target.pathname.length - 1);

// Build the other candidate, e.g. the 'host relative' path that starts with "/", and return the shortest of the two candidates.
if (target.pathname.length < relativePath.length) {
return target.pathname;
}
return relativePath;
} catch (e) {
return targetUrl
}
}
}

export default Utils;
3 changes: 1 addition & 2 deletions src/streaming/models/CmcdModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,7 @@ function CmcdModel() {

if (nextRequest) {
if (request.url !== nextRequest.url) {
let url = new URL(nextRequest.url);
data.nor = url.pathname;
data.nor = encodeURIComponent(Utils.getRelativeUrl(request.url, nextRequest.url));
} else if (nextRequest.range) {
data.nrr = nextRequest.range;
}
Expand Down
90 changes: 90 additions & 0 deletions test/unit/core.Utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import Utils from '../../src/core/Utils'
import {expect} from 'chai';

describe('Utils', () => {
describe('getRelativeUrl', () => {

it('Should return complete url if no original url is given', () => {
const b = 'https://localhost:3000/d/e/f.mp4';

expect(Utils.getRelativeUrl(undefined,b)).to.be.equal('https://localhost:3000/d/e/f.mp4');
})

it('Should return relative url if strings are different after server name', () => {
const a = 'https://localhost:3000/a/b/c.mp4';
const b = 'https://localhost:3000/d/e/f.mp4';

expect(Utils.getRelativeUrl(a,b)).to.be.equal('/d/e/f.mp4');
})

it('Should return relative url if strings are similar up to one element before filename', () => {
const a = 'https://localhost:3000/a/b/c.mp4';
const b = 'https://localhost:3000/a/c/f.mp4';

expect(Utils.getRelativeUrl(a,b)).to.be.equal('../c/f.mp4');
})

it('Should return relative url if strings are similar up to filename', () => {
const a = 'https://localhost:3000/a/b/c.mp4';
const b = 'https://localhost:3000/a/b/f.mp4';

expect(Utils.getRelativeUrl(a,b)).to.be.equal('f.mp4');
})

it('Should return complete url if origin is different', () => {
const a = 'https://localhost:3000/a/b/c.mp4';
const b = 'https://loca:3000/a/b/f.mp4';

expect(Utils.getRelativeUrl(a,b)).to.be.equal('https://loca:3000/a/b/f.mp4');
})

it('Should return filename if origin differs in terms of SSL', () => {
const a = 'https://localhost:3000/a/b/c.mp4';
const b = 'http://localhost:3000/a/b/e.mp4';

expect(Utils.getRelativeUrl(a,b)).to.be.equal('e.mp4');
})

it('Should return relative url if part of the pathnames are not equal', () => {
const a = 'https://localhost:3000/a/b/c.mp4';
const b = 'https://localhost:3000/ab/b/f.mp4';

expect(Utils.getRelativeUrl(a,b)).to.be.equal('/ab/b/f.mp4');
})

it('Should return relative url if target pathname is longer than source pathname ', () => {
const a = 'https://localhost:3000/a/b/f.mp4';
const b = 'https://localhost:3000/a/b/f/e/c.mp4';

expect(Utils.getRelativeUrl(a,b)).to.be.equal('f/e/c.mp4');
})

it('Should return relative url if source pathname is longer than target pathname ', () => {
const a = 'https://localhost:3000/a/b/f/e/c.mp4';
const b = 'https://localhost:3000/a/b/f.mp4';

expect(Utils.getRelativeUrl(a,b)).to.be.equal('/a/b/f.mp4');
})

it('Should return relative url if source contains slash in the end ', () => {
const a = 'https://localhost:3000/a/';
const b = 'https://localhost:3000/a/b.mp4';

expect(Utils.getRelativeUrl(a,b)).to.be.equal('b.mp4');
})

it('Should return relative url if source pathnames are exceptionally long ', () => {
const a = 'https://localhost:3000/a/b/c/d/e/f/g/h/1.mp4';
const b = 'https://localhost:3000/a/b/c/d/e/change/i/j/k/l/m/n/2.mp4';

expect(Utils.getRelativeUrl(a,b)).to.be.equal('../../../change/i/j/k/l/m/n/2.mp4');
})

it('Should return relative url if source contains slash in the end and multiple elements in the path', () => {
const a = 'https://localhost:3000/a/b/c/';
const b = 'https://localhost:3000/a/b/x/c.mp4';

expect(Utils.getRelativeUrl(a,b)).to.be.equal('../x/c.mp4');
})
})
})
10 changes: 6 additions & 4 deletions test/unit/streaming.models.CmcdModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ describe('CmcdModel', function () {
const MEASURED_THROUGHPUT = 8327641;
const BUFFER_LEVEL = parseInt(dashMetricsMock.getCurrentBufferLevel() * 10) * 100;
const VIDEO_OBJECT_TYPE = 'v';
const NEXT_OBJECT_URL = '/next_object';
const NEXT_OBJECT_URL = 'next_object';
const NEXT_OBJECT_RANGE = '100-500';

abrControllerMock.setTopBitrateInfo({bitrate: TOP_BITRATE});
Expand All @@ -135,7 +135,8 @@ describe('CmcdModel', function () {
mediaType: MEDIA_TYPE,
quality: 0,
mediaInfo: {bitrateList: [{bandwidth: BITRATE}]},
duration: DURATION
duration: DURATION,
url: 'http://test.url/firstRequest'
};

let headers = cmcdModel.getHeaderParameters(request);
Expand Down Expand Up @@ -430,7 +431,7 @@ describe('CmcdModel', function () {
const MEASURED_THROUGHPUT = 8327641;
const BUFFER_LEVEL = parseInt(dashMetricsMock.getCurrentBufferLevel() * 10) * 100;
const VIDEO_OBJECT_TYPE = 'v';
const NEXT_OBJECT_URL = '/next_object';
const NEXT_OBJECT_URL = 'next_object';
const NEXT_OBJECT_RANGE = '100-500';

abrControllerMock.setTopBitrateInfo({bitrate: TOP_BITRATE});
Expand All @@ -444,7 +445,8 @@ describe('CmcdModel', function () {
mediaType: MEDIA_TYPE,
quality: 0,
mediaInfo: {bitrateList: [{bandwidth: BITRATE}]},
duration: DURATION
duration: DURATION,
url: 'http://test.url/firstRequest'
};

let parameters = cmcdModel.getQueryParameter(request);
Expand Down