Skip to content

Commit

Permalink
fix encoding url in archive
Browse files Browse the repository at this point in the history
  • Loading branch information
marcopiovanello committed Oct 20, 2023
1 parent 600475f commit 6688bc3
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 54 deletions.
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
29 changes: 20 additions & 9 deletions frontend/src/lib/httpClient.ts
Original file line number Diff line number Diff line change
@@ -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 (opt && !opt.headers) {
opt.headers = {
'Content-Type': 'application/json',
}
}

if (!res.ok) {
onError(await res.text())
return
throw await res.text()
}
onSuccess(await res.json() as T)
return res.json() as T
}
30 changes: 9 additions & 21 deletions frontend/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { pipe } from 'fp-ts/lib/function'
import type { RPCResponse } from "./types"

/**
Expand All @@ -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]+)*$/
Expand All @@ -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)
Expand Down Expand Up @@ -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
)
40 changes: 23 additions & 17 deletions frontend/src/views/Archive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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('/')
Expand Down Expand Up @@ -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}`)
})
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -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=
Expand Down
9 changes: 8 additions & 1 deletion server/handlers/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/base64"
"fmt"
"net/http"
"net/url"
"os"
"path/filepath"
"sort"
Expand Down Expand Up @@ -130,14 +131,20 @@ 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)
return
}

decodedStr := string(decoded)
fmt.Println(decodedStr)
fmt.Println("decoded", decodedStr)

root := config.Instance().GetConfig().DownloadPath

Expand Down
3 changes: 2 additions & 1 deletion server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit 6688bc3

Please sign in to comment.