fix encoding url in archive
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
"@fontsource/roboto": "^5.0.6",
|
||||
"@mui/icons-material": "^5.11.16",
|
||||
"@mui/material": "^5.13.5",
|
||||
"fp-ts": "^2.16.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-helmet": "^6.1.0",
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
export async function ffetch<T>(
|
||||
url: string,
|
||||
onSuccess: (res: T) => void,
|
||||
onError: (err: string) => void,
|
||||
opt?: RequestInit,
|
||||
) {
|
||||
import { tryCatch } from 'fp-ts/TaskEither'
|
||||
import { flow } from 'fp-ts/lib/function'
|
||||
|
||||
export const ffetch = <T>(url: string, opt?: RequestInit) => flow(
|
||||
tryCatch(
|
||||
() => fetcher<T>(url, opt),
|
||||
(e) => `error while fetching: ${e}`
|
||||
)
|
||||
)
|
||||
|
||||
const fetcher = async <T>(url: string, opt?: RequestInit) => {
|
||||
const res = await fetch(url, opt)
|
||||
if (!res.ok) {
|
||||
onError(await res.text())
|
||||
return
|
||||
|
||||
if (opt && !opt.headers) {
|
||||
opt.headers = {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
}
|
||||
onSuccess(await res.json() as T)
|
||||
|
||||
if (!res.ok) {
|
||||
throw await res.text()
|
||||
}
|
||||
return res.json() as T
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { pipe } from 'fp-ts/lib/function'
|
||||
import type { RPCResponse } from "./types"
|
||||
|
||||
/**
|
||||
@@ -10,15 +11,6 @@ export function validateIP(ipAddr: string): boolean {
|
||||
return ipRegex.test(ipAddr)
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a domain via regex.
|
||||
* The validation pass if the domain respects the following formats:
|
||||
* - localhost
|
||||
* - domain.tld
|
||||
* - dir.domain.tld
|
||||
* @param domainName
|
||||
* @returns domain validity test
|
||||
*/
|
||||
export function validateDomain(url: string): boolean {
|
||||
const urlRegex = /(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/
|
||||
const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/
|
||||
@@ -28,17 +20,6 @@ export function validateDomain(url: string): boolean {
|
||||
return urlRegex.test(url) || name === 'localhost' && slugRegex.test(slug)
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a domain via regex.
|
||||
* Exapmples
|
||||
* - http://example.com
|
||||
* - https://example.com
|
||||
* - http://www.example.com
|
||||
* - https://www.example.com
|
||||
* - http://10.0.0.1/[something]/[something-else]
|
||||
* @param url
|
||||
* @returns url validity test
|
||||
*/
|
||||
export function isValidURL(url: string): boolean {
|
||||
let urlRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/
|
||||
return urlRegex.test(url)
|
||||
@@ -93,4 +74,11 @@ export function mapProcessStatus(status: number) {
|
||||
}
|
||||
|
||||
export const prefersDarkMode = () =>
|
||||
window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
|
||||
export const base64URLEncode = (s: string) => pipe(
|
||||
s,
|
||||
s => String.fromCodePoint(...new TextEncoder().encode(s)),
|
||||
btoa,
|
||||
encodeURIComponent
|
||||
)
|
||||
@@ -26,22 +26,26 @@ import FolderIcon from '@mui/icons-material/Folder'
|
||||
import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'
|
||||
import VideoFileIcon from '@mui/icons-material/VideoFile'
|
||||
|
||||
import { matchW } from 'fp-ts/lib/TaskEither'
|
||||
import { pipe } from 'fp-ts/lib/function'
|
||||
import { useEffect, useMemo, useState, useTransition } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { BehaviorSubject, Subject, combineLatestWith, map, share } from 'rxjs'
|
||||
import { serverURL } from '../atoms/settings'
|
||||
import { useObservable } from '../hooks/observable'
|
||||
import { useToast } from '../hooks/toast'
|
||||
import { useI18n } from '../hooks/useI18n'
|
||||
import { ffetch } from '../lib/httpClient'
|
||||
import { DeleteRequest, DirectoryEntry } from '../types'
|
||||
import { roundMiB } from '../utils'
|
||||
import { base64URLEncode, roundMiB } from '../utils'
|
||||
|
||||
export default function Downloaded() {
|
||||
const serverAddr = useRecoilValue(serverURL)
|
||||
const navigate = useNavigate()
|
||||
|
||||
const { i18n } = useI18n()
|
||||
const { pushMessage } = useToast()
|
||||
|
||||
const [openDialog, setOpenDialog] = useState(false)
|
||||
|
||||
@@ -50,20 +54,24 @@ export default function Downloaded() {
|
||||
|
||||
const [isPending, startTransition] = useTransition()
|
||||
|
||||
const fetcher = () => ffetch<DirectoryEntry[]>(
|
||||
`${serverAddr}/archive/downloaded`,
|
||||
(d) => files$.next(d),
|
||||
() => navigate('/login'),
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
const fetcher = () => pipe(
|
||||
ffetch<DirectoryEntry[]>(
|
||||
`${serverAddr}/archive/downloaded`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
subdir: '',
|
||||
})
|
||||
}
|
||||
),
|
||||
matchW(
|
||||
(e) => {
|
||||
pushMessage(e)
|
||||
navigate('/login')
|
||||
},
|
||||
body: JSON.stringify({
|
||||
subdir: '',
|
||||
})
|
||||
}
|
||||
)
|
||||
(d) => files$.next(d),
|
||||
)
|
||||
)()
|
||||
|
||||
const fetcherSubfolder = (sub: string) => {
|
||||
const folders = sub.startsWith('/')
|
||||
@@ -137,9 +145,7 @@ export default function Downloaded() {
|
||||
}, [serverAddr])
|
||||
|
||||
const onFileClick = (path: string) => startTransition(() => {
|
||||
const encoded = btoa(
|
||||
String.fromCodePoint(...new TextEncoder().encode(path))
|
||||
)
|
||||
const encoded = base64URLEncode(path)
|
||||
|
||||
window.open(`${serverAddr}/archive/d/${encoded}`)
|
||||
})
|
||||
|
||||
3
go.mod
3
go.mod
@@ -4,11 +4,12 @@ go 1.20
|
||||
|
||||
require (
|
||||
github.com/go-chi/chi/v5 v5.0.10
|
||||
github.com/go-chi/cors v1.2.1
|
||||
github.com/goccy/go-json v0.10.2
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/marcopeocchi/fazzoletti v0.0.0-20230308161120-c545580f79fa
|
||||
golang.org/x/sys v0.12.0
|
||||
golang.org/x/sys v0.13.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
8
go.sum
8
go.sum
@@ -1,21 +1,21 @@
|
||||
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
|
||||
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/marcopeocchi/fazzoletti v0.0.0-20230308161120-c545580f79fa h1:uaAQLGhN4SesB9inOQ1Q6EH+BwTWHQOvwhR0TIJvnYc=
|
||||
github.com/marcopeocchi/fazzoletti v0.0.0-20230308161120-c545580f79fa/go.mod h1:RvfVo/6Sbnfra9kkvIxDW8NYOOaYsHjF0DdtMCs9cdo=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
@@ -130,6 +131,12 @@ func SendFile(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
path, err := url.QueryUnescape(path)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
decoded, err := base64.StdEncoding.DecodeString(path)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
@@ -137,7 +144,7 @@ func SendFile(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
decodedStr := string(decoded)
|
||||
fmt.Println(decodedStr)
|
||||
fmt.Println("decoded", decodedStr)
|
||||
|
||||
root := config.Instance().GetConfig().DownloadPath
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/go-chi/cors"
|
||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/handlers"
|
||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
||||
middlewares "github.com/marcopeocchi/yt-dlp-web-ui/server/middleware"
|
||||
@@ -54,7 +55,7 @@ func newServer(c serverConfig) *http.Server {
|
||||
|
||||
r := chi.NewRouter()
|
||||
|
||||
r.Use(middlewares.CORS)
|
||||
r.Use(cors.AllowAll().Handler)
|
||||
r.Use(middleware.Logger)
|
||||
|
||||
app := http.FileServer(http.FS(c.frontend))
|
||||
|
||||
Reference in New Issue
Block a user