Skip to content

Commit

Permalink
Merge pull request #342 from dfpc-coe/video-csp
Browse files Browse the repository at this point in the history
Video CSP
  • Loading branch information
ingalls authored Sep 18, 2024
2 parents 97aef41 + 1ac74ba commit 0838a3a
Show file tree
Hide file tree
Showing 21 changed files with 4,291 additions and 3,120 deletions.
8 changes: 3 additions & 5 deletions api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ EXPOSE 5000
ENV HOME=/home/etl
WORKDIR $HOME

RUN apk add nodejs-current npm memcached python3 make bash g++ openssl postgresql-client
RUN apk add nodejs-current npm memcached python3 make bash g++ openssl postgresql-client grep

WORKDIR $HOME/api

Expand All @@ -27,8 +27,6 @@ RUN npm run lint \
&& npm run build

COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./start $HOME/api

CMD memcached -d -u root \
&& sed -i "s/API_URL/${API_URL}/g" /etc/nginx/nginx.conf \
&& nginx \
&& npm run prod
CMD ["./start"]
4 changes: 2 additions & 2 deletions api/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export default class Config {
SigningSecret = 'coe-wildland-fire';
API_URL = 'http://localhost:5001';
Bucket = process.env.ASSET_BUCKET;
PMTILES_URL = 'http://localhost:5001';
PMTILES_URL = process.env.PMTILES_URL || 'http://localhost:5001';
} else {
if (!process.env.StackName) throw new Error('StackName env must be set');
if (!process.env.API_URL) throw new Error('API_URL env must be set');
Expand All @@ -133,7 +133,7 @@ export default class Config {
const apiUrl = new URL(`http://${process.env.API_URL}`);
if (apiUrl.hostname === 'localhost') {
API_URL = `http://${process.env.API_URL}`;
PMTILES_URL = 'http://localhost:5001'
PMTILES_URL = process.env.PMTILES_URL || 'http://localhost:5001'
} else {
PMTILES_URL = `https://tiles.${process.env.API_URL}`;
API_URL = String(`https://${process.env.API_URL}`);
Expand Down
27 changes: 26 additions & 1 deletion api/lib/control/video-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export default class VideoServiceControl {
if (c.config && c.config.rtmp) {
// Format: rtmp://localhost/mystream
const url = new URL(`/${lease.path}`, c.url.replace(/^http(s)?:/, 'rtmp:'))
url.port = '';
url.port = c.config.rtmpAddress.replace(':', '');

if (lease.stream_user) url.searchParams.append('user', lease.stream_user);
if (lease.stream_pass) url.searchParams.append('pass', lease.stream_pass);
Expand Down Expand Up @@ -272,6 +272,7 @@ export default class VideoServiceControl {

async generate(opts: {
name: string;
ephemeral: boolean;
expiration: string;
path: string;
username: string;
Expand All @@ -286,6 +287,7 @@ export default class VideoServiceControl {
const lease = await this.config.models.VideoLease.generate({
name: opts.name,
expiration: opts.expiration,
ephemeral: opts.ephemeral,
path: opts.path,
username: opts.username,
proxy: opts.proxy
Expand All @@ -297,6 +299,29 @@ export default class VideoServiceControl {
headers.append('Content-Type', 'application/json');

if (lease.proxy) {
try {
const proxy = new URL(opts.proxy);

// Check for HLS Errors
if (['http:', 'https:'].includes(proxy.protocol)) {
const res = await fetch(proxy);

if (res.status === 404) {
throw new Err(400, null, 'External Video Server reports Video Stream not found');
} else if (!res.ok) {
throw new Err(res.status, null, `External Video Server failed stream video - HTTP Error ${res.status}`);
}
}
} catch (err) {
if (err instanceof Err) {
throw err;
} else if (err instanceof TypeError && err.code === 'ERR_INVALID_URL') {
throw new Err(400, null, 'Invalid Video Stream URL');
} else {
throw new Err(500, err instanceof Error ? err : new Error(String(err)), 'Failed to generate proxy stream');
}
}

const res = await fetch(url, {
method: 'POST',
headers,
Expand Down
1 change: 1 addition & 0 deletions api/lib/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class toEnum {

export enum Basemap_Format {
PNG = 'png',
JPEG = 'jpeg',
MVT = 'mvt'
}

Expand Down
1 change: 1 addition & 0 deletions api/lib/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const VideoLease = pgTable('video_lease', {
updated: timestamp('updated', { withTimezone: true, mode: 'string' }).notNull().default(sql`Now()`),
username: text('username').notNull().references(() => Profile.username),

ephemeral: boolean('ephemeral').notNull().default(false),
expiration: timestamp('expiration', { withTimezone: true, mode: 'string' }).notNull().default(sql`Now() + INTERVAL 1 HOUR;`),
path: text('path').notNull(),
stream_user: text('stream_user'),
Expand Down
1 change: 1 addition & 0 deletions api/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const ProfileResponse = Type.Object({

export const VideoLeaseResponse = createSelectSchema(schemas.VideoLease, {
id: Type.Integer(),
ephemeral: Type.Boolean()
});

export const OverlayResponse = createSelectSchema(schemas.Overlay, {
Expand Down
1 change: 1 addition & 0 deletions api/migrations/0061_wide_bruce_banner.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE "video_lease" ADD COLUMN "ephemeral" boolean DEFAULT false NOT NULL;
Loading

0 comments on commit 0838a3a

Please sign in to comment.