add url encoding/decoding mechanism

This commit is contained in:
La macchina desiderante 2024-05-24 23:09:56 +02:00
parent 7b1d712904
commit 702b67bdd7
7 changed files with 53 additions and 4 deletions

View File

@ -5,4 +5,11 @@ ENABLE_REDIS=true
# REDIS_URL='redis://redis:6379'
# if cache enabled, set redis url for external redis
REDIS_URL='redis://127.0.0.1:6379'
REDIS_URL='redis://127.0.0.1:6379'
# this key is necessary to encrypt/decrypt urls for server-side stream
# if not set, a default value (check const DEFAULT_ENCODING_KEY inside src/constants/encoding.ts ) will be used
# please generate a new one with command `pwgen 20 1` (pwgen command needs to be installed)
# uncomment variable below and add generated value
# ENCODING_KEY=''

View File

@ -23,6 +23,8 @@ services:
environment:
- ENABLE_REDIS=true
- REDIS_URL=redis://redis:6379
# Please generate a new encoding key with command `pwgen 20 1`, decomment following variable and insert result into it:
# - ENCODING_KEY=
redis:
image: redis:alpine

View File

@ -1,4 +1,5 @@
import { Platforms } from "@/meta/settings";
import { decodeUrl } from "@/utils/string";
import axios from "axios";
type GetParams = {
@ -22,7 +23,7 @@ export async function GET(req: Request, { params }: GetParams) {
)
}
const decodedUrl = decodeURIComponent(encodedUrl)
const decodedUrl = decodeUrl(encodedUrl)
const response = await axios.get<ReadableStream>(decodedUrl, {
responseType: "stream",

View File

@ -0,0 +1 @@
export const DEFAULT_ENCODING_KEY = 'oom2oz8ut0ieshie1Hae'

1
src/constants/stream.ts Normal file
View File

@ -0,0 +1 @@
export const DEFAULT_VIDEO_STREAM_ROUTE_PREFIX = '/api/stream'

View File

@ -4,6 +4,8 @@ import { getHeadersWithCookie } from "../common/headers"
import { GalleryData, VideoSourceItem } from "@/meta/data"
import { Cookies, Platforms, PornHubOrientations } from "@/meta/settings"
import { getCookie } from "@/utils/cookies/read"
import { encodeUrl } from "@/utils/string"
import { DEFAULT_VIDEO_STREAM_ROUTE_PREFIX } from "@/constants/stream"
interface PornHubVideoSrcElem {
videoUrl: string
@ -48,7 +50,7 @@ export const getPornHubMediaUrlList = async (url: string, sessionCookie: string)
if (response.data) {
videos = await response.data.map((elem: PornHubVideoSrcElem) => ({
src: `/api/stream/${Platforms.pornhub}/${encodeURIComponent(elem?.videoUrl)}`,
src: `${DEFAULT_VIDEO_STREAM_ROUTE_PREFIX}/${Platforms.pornhub}/${encodeUrl(elem?.videoUrl)}`,
type: 'video/mp4',
size: elem?.quality
})) as VideoSourceItem[]

View File

@ -1,3 +1,5 @@
import { DEFAULT_ENCODING_KEY } from "@/constants/encoding";
export const removeHttpS = (url: string): string => {
if (url.startsWith("http://")) {
return url.slice(7);
@ -13,4 +15,37 @@ export const encodeVideoUrlPath = (input: string): string => {
export const decodeVideoUrlPath = (input: string): string => {
return `/${decodeURIComponent(input)}`;
};
};
const getEncodingKey = ():string => {
return process.env.ENCODING_KEY ?? DEFAULT_ENCODING_KEY;
}
export function encodeUrl(url: string): string {
const key = getEncodingKey()
// Convert the URL and key to UTF-8 bytes
const urlBytes = new TextEncoder().encode(url);
const keyBytes = new TextEncoder().encode(key);
// XOR the bytes of the URL with the key bytes
const encodedBytes = urlBytes.map((byte, index) => byte ^ keyBytes[index % keyBytes.length]);
// Convert the XORed bytes to a base64 string
//@ts-ignore
return btoa(String.fromCharCode(...encodedBytes));
}
export function decodeUrl(encodedUrl: string): string {
const key = getEncodingKey()
// Decode the base64 string to get the XORed bytes
const encodedBytes = Uint8Array.from(atob(encodedUrl), char => char.charCodeAt(0));
const keyBytes = new TextEncoder().encode(key);
// XOR the encoded bytes with the key bytes to get the original URL bytes
const urlBytes = encodedBytes.map((byte, index) => byte ^ keyBytes[index % keyBytes.length]);
// Convert the bytes back to a string
return new TextDecoder().decode(urlBytes);
}