mirror of
				https://codeberg.org/ashley/poke
				synced 2025-07-17 16:52:11 +00:00 
			
		
		
		
	Merge pull request 'several enhancements related to proxy microservice' (#20) from janderedev/poketube:main into main
Reviewed-on: https://codeberg.org/Ashley/poketube/pulls/20
This commit is contained in:
		
						commit
						371e6ca54c
					
				
							
								
								
									
										12
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| version: '3.1' | ||||
| 
 | ||||
| # TODO: Dockerize the other services | ||||
| 
 | ||||
| services: | ||||
|   proxy: | ||||
|     build: | ||||
|       context: . | ||||
|       dockerfile: p/Dockerfile | ||||
|     restart: unless-stopped | ||||
|     ports: | ||||
|       - 3000:3000 | ||||
							
								
								
									
										7
									
								
								p/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								p/Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| FROM node:18 | ||||
| WORKDIR /app | ||||
| COPY package.json /app/ | ||||
| COPY p /app/p | ||||
| RUN npm install --frozen-lockfile | ||||
| ENV NODE_ENV production | ||||
| CMD ["node", "p/server.js"] | ||||
							
								
								
									
										73
									
								
								p/server.js
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								p/server.js
									
									
									
									
									
								
							| @ -1,49 +1,74 @@ | ||||
| const fs = require("fs"); | ||||
| const express = require("express"); | ||||
| const fetch = require("node-fetch"); | ||||
| const htmlParser = require("node-html-parser"); | ||||
| const { URL } = require("url"); | ||||
| 
 | ||||
| // Array of hostnames that will be proxied
 | ||||
| const URL_WHITELIST = [ | ||||
|   'i.ytimg.com', | ||||
|   'yt3.googleusercontent.com', | ||||
|   'cdn.glitch.global', | ||||
|   'cdn.statically.io', | ||||
|   'site-assets.fontawesome.com', | ||||
|   'fonts.gstatic.com', | ||||
|   'yt3.ggpht.com', | ||||
|   'tube.kuylar.dev', | ||||
|   'lh3.googleusercontent.com', | ||||
|   'is4-ssl.mzstatic.com', | ||||
|   'twemoji.maxcdn.com', | ||||
|   'unpkg.com', | ||||
| ]; | ||||
| 
 | ||||
| const app = express(); | ||||
| 
 | ||||
| app.use(express.json()); // for parsing application/json
 | ||||
| app.use(express.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
 | ||||
| 
 | ||||
| app.use(function (req, res, next) { | ||||
|   console.log(`=> ${req.method} ${req.originalUrl.slice(1)}`) | ||||
|   next(); | ||||
| }); | ||||
| 
 | ||||
| app.use(function (req, res, next) { | ||||
|   res.header("Access-Control-Allow-Origin", "*"); | ||||
|   next(); | ||||
| }); | ||||
| let Proxy = async (req, res) => { | ||||
|   const url = "https://" + req.originalUrl.slice(10); | ||||
| 
 | ||||
|   let f = await fetch(url, { | ||||
|     method: req.method, | ||||
|   }); | ||||
|   if (false && f.headers.get("content-type").includes("html")) { | ||||
|     const body = await f.text(); | ||||
|     if (false && !htmlParser.valid(body)) { | ||||
|       console.warn(`[ERROR] Invalid HTML at ${url}`); | ||||
|       f.body.pipe(res); | ||||
|       return; | ||||
| /** | ||||
|  * @param {express.Request} req  | ||||
|  * @param {express.Response} res  | ||||
|  */ | ||||
| const proxy = async (req, res) => { | ||||
|   try { | ||||
|     let url; | ||||
| 
 | ||||
|     try { | ||||
|       url = new URL("https://" + req.originalUrl.slice(1)); | ||||
|     } catch(e) { | ||||
|       console.log('==> Cannot parse URL: ' + e); | ||||
|       return res.status(400).send('Malformed URL'); | ||||
|     } | ||||
|     const root = htmlParser.parse(body); | ||||
|     let html = root.childNodes.filter( | ||||
|       (x) => x.tagName && x.tagName.toLowerCase() == "html" | ||||
|     )[0]; | ||||
| 
 | ||||
|     if (!html) { | ||||
|       console.warn(`[ERROR] No <html> at ${url}`); | ||||
|       res.send(body); | ||||
|     if (!URL_WHITELIST.includes(url.host)) { | ||||
|       console.log(`==> Refusing to proxy host ${url.host}`); | ||||
|       res.status(401).send(`Hostname '${url.host}' is not permitted`); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     res.send(html.toString()); | ||||
|   } else { | ||||
|     console.log(`==> Proxying request`); | ||||
| 
 | ||||
|     let f = await fetch(url, { | ||||
|       method: req.method, | ||||
|     }); | ||||
| 
 | ||||
|     f.body.pipe(res); | ||||
|   } catch(e) { | ||||
|     console.log(`==> Error: ${e}`); | ||||
|     res.status(500).send('Internal server error'); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| const listener = (req, res) => { | ||||
|   Proxy(req, res); | ||||
|   proxy(req, res); | ||||
| }; | ||||
| 
 | ||||
| app.get("/", (req, res) => | ||||
| @ -52,4 +77,4 @@ app.get("/", (req, res) => | ||||
| 
 | ||||
| app.all("/*", listener); | ||||
| 
 | ||||
| app.listen(3000, () => {}); | ||||
| app.listen(3000, () => console.log('Listening on 0.0.0.0:3000')); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Ashley
						Ashley