mirror of
https://github.com/rikkaneko/paste.git
synced 2025-06-06 16:45:41 +00:00
Add URL redirection support
Signed-off-by: Joe Ma <rikkaneko23@gmail.com>
This commit is contained in:
parent
5404d3055b
commit
19c9c69a78
3 changed files with 58 additions and 9 deletions
3
.idea/codeStyles/Project.xml
generated
3
.idea/codeStyles/Project.xml
generated
|
@ -19,6 +19,9 @@
|
||||||
<JetCodeStyleSettings>
|
<JetCodeStyleSettings>
|
||||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
</JetCodeStyleSettings>
|
</JetCodeStyleSettings>
|
||||||
|
<Markdown>
|
||||||
|
<option name="WRAP_TEXT_IF_LONG" value="false" />
|
||||||
|
</Markdown>
|
||||||
<Python>
|
<Python>
|
||||||
<option name="SPACE_WITHIN_BRACES" value="true" />
|
<option name="SPACE_WITHIN_BRACES" value="true" />
|
||||||
<option name="SPACE_AROUND_POWER_OPERATOR" value="false" />
|
<option name="SPACE_AROUND_POWER_OPERATOR" value="false" />
|
||||||
|
|
63
src/index.ts
63
src/index.ts
|
@ -147,10 +147,12 @@ export default {
|
||||||
let password: string | undefined;
|
let password: string | undefined;
|
||||||
let read_limit: number | undefined;
|
let read_limit: number | undefined;
|
||||||
let need_qrcode: boolean = false;
|
let need_qrcode: boolean = false;
|
||||||
|
let paste_type: string | undefined;
|
||||||
// Content-Type: multipart/form-data
|
// Content-Type: multipart/form-data
|
||||||
if (content_type.includes('multipart/form-data')) {
|
if (content_type.includes('multipart/form-data')) {
|
||||||
const formdata = await request.formData();
|
const formdata = await request.formData();
|
||||||
const data = formdata.get('u');
|
const data = formdata.get('u');
|
||||||
|
const type = formdata.get('paste-type');
|
||||||
if (data === null) {
|
if (data === null) {
|
||||||
return new Response('Invalid request.\n', {
|
return new Response('Invalid request.\n', {
|
||||||
status: 422,
|
status: 422,
|
||||||
|
@ -167,6 +169,8 @@ export default {
|
||||||
mime_type = 'text/plain; charset=UTF-8;';
|
mime_type = 'text/plain; charset=UTF-8;';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof type === 'string') paste_type = type;
|
||||||
|
|
||||||
// Set password
|
// Set password
|
||||||
const pass = formdata.get('pass');
|
const pass = formdata.get('pass');
|
||||||
if (typeof pass === 'string') {
|
if (typeof pass === 'string') {
|
||||||
|
@ -195,6 +199,7 @@ export default {
|
||||||
title = headers.get('x-title') || undefined;
|
title = headers.get('x-title') || undefined;
|
||||||
mime_type = headers.get('x-content-type') || undefined;
|
mime_type = headers.get('x-content-type') || undefined;
|
||||||
password = headers.get('x-pass') || undefined;
|
password = headers.get('x-pass') || undefined;
|
||||||
|
paste_type = headers.get('x-paste-type') || undefined;
|
||||||
const count = headers.get('x-read-limit') || undefined;
|
const count = headers.get('x-read-limit') || undefined;
|
||||||
if (typeof count === 'string') {
|
if (typeof count === 'string') {
|
||||||
const n = parseInt(count);
|
const n = parseInt(count);
|
||||||
|
@ -213,6 +218,24 @@ export default {
|
||||||
need_qrcode = true;
|
need_qrcode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate paste type parameter
|
||||||
|
switch (paste_type) {
|
||||||
|
case 'link':
|
||||||
|
mime_type = 'text/x-uri';
|
||||||
|
paste_type = 'link';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'paste':
|
||||||
|
case undefined:
|
||||||
|
paste_type = undefined;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return new Response('Unknown paste type.\n', {
|
||||||
|
status: 422,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Check password rules
|
// Check password rules
|
||||||
if (password && !check_password_rules(password)) {
|
if (password && !check_password_rules(password)) {
|
||||||
return new Response('Invalid password. ' +
|
return new Response('Invalid password. ' +
|
||||||
|
@ -249,6 +272,7 @@ export default {
|
||||||
password: password ? sha256(password).slice(0, 16) : undefined,
|
password: password ? sha256(password).slice(0, 16) : undefined,
|
||||||
read_count_remain: read_limit ?? undefined,
|
read_count_remain: read_limit ?? undefined,
|
||||||
mime_type: mime_type || undefined,
|
mime_type: mime_type || undefined,
|
||||||
|
type: paste_type,
|
||||||
size,
|
size,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -390,19 +414,41 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
res.headers.set('cache-control', 'public, max-age=18000');
|
res.headers.set('cache-control', 'public, max-age=18000');
|
||||||
// Alter content type to text/plain
|
|
||||||
if (option === 'raw' || descriptor.mime_type === undefined) {
|
|
||||||
res.headers.delete('content-type');
|
|
||||||
} else {
|
|
||||||
res.headers.set('content-type', descriptor.mime_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
res.headers.set('content-disposition',
|
res.headers.set('content-disposition',
|
||||||
`inline; filename="${encodeURIComponent(descriptor.title ?? uuid)}"`);
|
`inline; filename="${encodeURIComponent(descriptor.title ?? uuid)}"`);
|
||||||
|
|
||||||
if (option === 'download') {
|
if (descriptor.mime_type)
|
||||||
|
res.headers.set('content-type', descriptor.mime_type);
|
||||||
|
// Let the browser guess the content
|
||||||
|
else res.headers.delete('content-type');
|
||||||
|
|
||||||
|
// Handle option
|
||||||
|
if (option === 'raw') res.headers.delete('content-type');
|
||||||
|
else if (option === 'download')
|
||||||
res.headers.set('content-disposition',
|
res.headers.set('content-disposition',
|
||||||
`attachment; filename="${encodeURIComponent(descriptor.title ?? uuid)}"`);
|
`attachment; filename="${encodeURIComponent(descriptor.title ?? uuid)}"`);
|
||||||
|
|
||||||
|
// Link redirection
|
||||||
|
else if (descriptor.type === 'link' || option === 'link') {
|
||||||
|
const content = await res.clone().arrayBuffer();
|
||||||
|
try {
|
||||||
|
const href = new TextDecoder().decode(content);
|
||||||
|
new URL(href);
|
||||||
|
res.headers.set('location', href);
|
||||||
|
res = new Response(res.body, {
|
||||||
|
status: 301,
|
||||||
|
headers: {
|
||||||
|
location: href,
|
||||||
|
...res.headers,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof TypeError) {
|
||||||
|
res = new Response('Invalid URL.', {
|
||||||
|
status: 422,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// res.body cannot be read twice
|
// res.body cannot be read twice
|
||||||
|
@ -578,4 +624,5 @@ interface PasteIndexEntry {
|
||||||
password?: string,
|
password?: string,
|
||||||
editable?: boolean, // Default: True
|
editable?: boolean, // Default: True
|
||||||
read_count_remain?: number
|
read_count_remain?: number
|
||||||
|
type?: string;
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
name = "paste"
|
name = "paste"
|
||||||
main = "src/index.ts"
|
main = "src/index.ts"
|
||||||
compatibility_date = "2022-05-30"
|
compatibility_date = "2022-05-30"
|
||||||
node_compat = true
|
|
||||||
workers_dev = false
|
workers_dev = false
|
||||||
kv_namespaces = [
|
kv_namespaces = [
|
||||||
{ binding = "PASTE_INDEX", id = "a578863da0564cd7beadd9ce4a2d53e8", preview_id = "66d9440e13124099a5e508fe1ff0a489" }
|
{ binding = "PASTE_INDEX", id = "a578863da0564cd7beadd9ce4a2d53e8", preview_id = "66d9440e13124099a5e508fe1ff0a489" }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue