-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
131 lines (104 loc) · 3.51 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import { matchPattern } from 'url-matcher'
import { pick } from 'accept-language-parser'
import config from './config.js'
addEventListener('fetch', (event) => event.respondWith(handler(event)))
const handler = async event => {
const request = event.request
// Only run on GET or HEAD requests
if (request.method !== 'GET' && request.method !== 'HEAD') {
console.log('Request is non-GET, ignoring.')
return fetch(request)
}
const url = new URL(request.url)
// Check if the path is already prefixed when enabled in config.
if (!config.listen_on_prefixed_paths) {
const urlArray = url.pathname.split('/')
// Ignore if the url has no first part e.g. /
if (urlArray.length > 2) {
const firstPart = urlArray[1]
let hasLanguage = false
for (const i in config.supported_languages) {
const language = config.supported_languages[i]
// If there was a match, break from the loop.
if (language.toLowerCase() === firstPart.toLowerCase()) {
hasLanguage = true
break
}
}
// Return if a language was found.
if (hasLanguage) {
console.log('The request already has a language prefix ('+firstPart+'), ignoring.')
return fetch(request)
}
}
}
// Weather or not this request should be handled.
let handleThis = config.listen_on_all_paths
// Don't use route-matching when listen_on_all_paths is enabled.
if (!config.listen_on_all_paths) {
for (const i in config.listen_on_paths) {
const path = config.listen_on_paths[i]
const match = matchPattern(path, url.pathname)
console.log('Matching ', path, ' against ', url.pathname, match)
// If there was a match, break from the loop.
if (match && match.remainingPathname === '') {
console.log('Match')
handleThis = true
break
}
console.log('No match')
}
}
// Return if we are not supposed to handle this.
if (!handleThis) {
if(config.always_on_not_found) {
try {
const res = await fetch(request)
console.log(res)
// Redirect if we'd return a 404 otherwise
if(res.status === 404) {
console.log('Sub-Request is 404, continuing.')
} else {
console.log('Sub-Request is '+res.status+', not redirecting.')
return fetch(request)
}
} catch(e) {
console.log(e);
console.log('Sub-Request failed, continuing.')
}
} else {
console.log('Request is not for us, ignoring.')
return fetch(request)
}
}
const headers = request.headers
// Use default language if no Accept-Language Header was sent by the client.
if (!headers.has('Accept-Language')) {
return redirectWithPrefix(url, config.default_language)
}
let language = pick(
config.supported_languages,
headers.get('Accept-Language')
)
// If accept-language-parser didn't manage to find a supported language, use the default one.
if (!language) {
language = config.default_language
}
// Do the redirect.
return redirectWithPrefix(url, language)
}
/**
* Generate a HTTP response redirecting to a URL, prefixed with a prefix.
* @param {URL} url The URL the redirect is based on
* @param {string} prefix The string to prefix 'url' with.
* @returns {Response} The final response
*/
async function redirectWithPrefix (url, prefix) {
url.pathname = '/' + prefix + url.pathname
return new Response(null, {
status: 302,
headers: new Headers({
Location: url.href
})
})
}