mirror of
https://github.com/movie-web/extension.git
synced 2025-09-13 13:33:25 +00:00
serialize body
This commit is contained in:
@@ -2,9 +2,20 @@ import type { PlasmoMessaging } from '@plasmohq/messaging';
|
|||||||
|
|
||||||
import type { BaseRequest } from '~types/request';
|
import type { BaseRequest } from '~types/request';
|
||||||
import type { BaseResponse } from '~types/response';
|
import type { BaseResponse } from '~types/response';
|
||||||
|
import { setDynamicRules } from '~utils/declarativeNetRequest';
|
||||||
import { makeFullUrl } from '~utils/fetcher';
|
import { makeFullUrl } from '~utils/fetcher';
|
||||||
import { assertDomainWhitelist } from '~utils/storage';
|
import { assertDomainWhitelist } from '~utils/storage';
|
||||||
|
|
||||||
|
type Body =
|
||||||
|
| {
|
||||||
|
bodyType: 'string';
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
bodyType: 'FormData' | 'URLSearchParams' | 'Object';
|
||||||
|
value: Record<string, string>;
|
||||||
|
};
|
||||||
|
|
||||||
export interface Request extends BaseRequest {
|
export interface Request extends BaseRequest {
|
||||||
baseUrl?: string;
|
baseUrl?: string;
|
||||||
headers?: Record<string, string>;
|
headers?: Record<string, string>;
|
||||||
@@ -12,7 +23,7 @@ export interface Request extends BaseRequest {
|
|||||||
query?: Record<string, string>;
|
query?: Record<string, string>;
|
||||||
readHeaders?: Record<string, string>;
|
readHeaders?: Record<string, string>;
|
||||||
url: string;
|
url: string;
|
||||||
body?: string | FormData | URLSearchParams;
|
body?: Body;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Response<T> = BaseResponse<{
|
type Response<T> = BaseResponse<{
|
||||||
@@ -24,14 +35,52 @@ type Response<T> = BaseResponse<{
|
|||||||
};
|
};
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
const mapBodyToFetchBody = (body: Request['body']): BodyInit => {
|
||||||
|
if (body?.bodyType === 'FormData') {
|
||||||
|
const formData = new FormData();
|
||||||
|
Object.entries(body.value).forEach(([key, value]) => {
|
||||||
|
formData.append(key, value);
|
||||||
|
});
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
if (body?.bodyType === 'URLSearchParams') {
|
||||||
|
const searchParams = new URLSearchParams();
|
||||||
|
Object.entries(body.value).forEach(([key, value]) => {
|
||||||
|
searchParams.set(key, value);
|
||||||
|
});
|
||||||
|
return searchParams;
|
||||||
|
}
|
||||||
|
if (body?.bodyType === 'Object') {
|
||||||
|
return JSON.stringify(body.value);
|
||||||
|
}
|
||||||
|
if (body?.bodyType === 'string') {
|
||||||
|
return body.value;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
const handler: PlasmoMessaging.MessageHandler<Request, Response<any>> = async (req, res) => {
|
const handler: PlasmoMessaging.MessageHandler<Request, Response<any>> = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
await assertDomainWhitelist(req.sender.tab.url);
|
await assertDomainWhitelist(req.sender.tab.url);
|
||||||
|
|
||||||
|
console.log(req.body.headers['User-Agent']);
|
||||||
|
if (req.body.headers['User-Agent']) {
|
||||||
|
console.log('preparing stream');
|
||||||
|
await setDynamicRules({
|
||||||
|
ruleId: 23498,
|
||||||
|
targetDomains: [req.body.url],
|
||||||
|
requestHeaders: {
|
||||||
|
'User-Agent': req.body.headers['User-Agent'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const rules = await chrome.declarativeNetRequest.getDynamicRules();
|
||||||
|
console.log(rules);
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch(makeFullUrl(req.body.url, req.body), {
|
const response = await fetch(makeFullUrl(req.body.url, req.body), {
|
||||||
method: req.body.method,
|
method: req.body.method,
|
||||||
headers: req.body.headers,
|
headers: req.body.headers,
|
||||||
body: req.body.body,
|
body: mapBodyToFetchBody(req.body.body),
|
||||||
});
|
});
|
||||||
const contentType = response.headers.get('content-type');
|
const contentType = response.headers.get('content-type');
|
||||||
const body = contentType?.includes('application/json') ? await response.json() : await response.text();
|
const body = contentType?.includes('application/json') ? await response.json() : await response.text();
|
||||||
@@ -46,6 +95,8 @@ const handler: PlasmoMessaging.MessageHandler<Request, Response<any>> = async (r
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.log('error');
|
||||||
|
console.log(err);
|
||||||
res.send({
|
res.send({
|
||||||
success: false,
|
success: false,
|
||||||
error: err.message,
|
error: err.message,
|
||||||
|
@@ -2,7 +2,7 @@ import type { PlasmoMessaging } from '@plasmohq/messaging';
|
|||||||
|
|
||||||
import type { BaseRequest } from '~types/request';
|
import type { BaseRequest } from '~types/request';
|
||||||
import type { BaseResponse } from '~types/response';
|
import type { BaseResponse } from '~types/response';
|
||||||
import { isChrome } from '~utils/extension';
|
import { setDynamicRules } from '~utils/declarativeNetRequest';
|
||||||
import { assertDomainWhitelist } from '~utils/storage';
|
import { assertDomainWhitelist } from '~utils/storage';
|
||||||
|
|
||||||
interface Request extends BaseRequest {
|
interface Request extends BaseRequest {
|
||||||
@@ -13,112 +13,15 @@ interface Request extends BaseRequest {
|
|||||||
responseHeaders?: Record<string, string>;
|
responseHeaders?: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapHeadersToDeclarativeNetRequestHeaders = (
|
|
||||||
headers: Record<string, string>,
|
|
||||||
op: string,
|
|
||||||
): { header: string; operation: any; value: string }[] => {
|
|
||||||
return Object.entries(headers).map(([name, value]) => ({
|
|
||||||
header: name,
|
|
||||||
operation: op,
|
|
||||||
value,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handler: PlasmoMessaging.MessageHandler<Request, BaseResponse> = async (req, res) => {
|
const handler: PlasmoMessaging.MessageHandler<Request, BaseResponse> = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
await assertDomainWhitelist(req.sender.tab.url);
|
await assertDomainWhitelist(req.sender.tab.url);
|
||||||
if (isChrome()) {
|
await setDynamicRules(req.body);
|
||||||
await chrome.declarativeNetRequest.updateDynamicRules({
|
|
||||||
removeRuleIds: [req.body.ruleId],
|
|
||||||
addRules: [
|
|
||||||
{
|
|
||||||
id: req.body.ruleId,
|
|
||||||
condition: {
|
|
||||||
...(req.body.targetDomains && { requestDomains: req.body.targetDomains }),
|
|
||||||
...(req.body.targetRegex && { regexFilter: req.body.targetRegex }),
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
type: chrome.declarativeNetRequest.RuleActionType.MODIFY_HEADERS,
|
|
||||||
...(req.body.requestHeaders && Object.keys(req.body.requestHeaders).length > 0
|
|
||||||
? {
|
|
||||||
requestHeaders: mapHeadersToDeclarativeNetRequestHeaders(
|
|
||||||
req.body.requestHeaders,
|
|
||||||
chrome.declarativeNetRequest.HeaderOperation.SET,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
: {}),
|
|
||||||
responseHeaders: [
|
|
||||||
{
|
|
||||||
header: 'Access-Control-Allow-Origin',
|
|
||||||
operation: chrome.declarativeNetRequest.HeaderOperation.SET,
|
|
||||||
value: '*',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
header: 'Access-Control-Allow-Methods',
|
|
||||||
operation: chrome.declarativeNetRequest.HeaderOperation.SET,
|
|
||||||
value: 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
header: 'Access-Control-Allow-Headers',
|
|
||||||
operation: chrome.declarativeNetRequest.HeaderOperation.SET,
|
|
||||||
value: '*',
|
|
||||||
},
|
|
||||||
...mapHeadersToDeclarativeNetRequestHeaders(
|
|
||||||
req.body.responseHeaders ?? {},
|
|
||||||
chrome.declarativeNetRequest.HeaderOperation.SET,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
if (chrome.runtime.lastError?.message) throw new Error(chrome.runtime.lastError.message);
|
|
||||||
} else {
|
|
||||||
await browser.declarativeNetRequest.updateDynamicRules({
|
|
||||||
removeRuleIds: [req.body.ruleId],
|
|
||||||
addRules: [
|
|
||||||
{
|
|
||||||
id: req.body.ruleId,
|
|
||||||
condition: {
|
|
||||||
...(req.body.targetDomains && { requestDomains: req.body.targetDomains }),
|
|
||||||
...(req.body.targetRegex && { regexFilter: req.body.targetRegex }),
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
type: 'modifyHeaders',
|
|
||||||
...(req.body.requestHeaders && Object.keys(req.body.requestHeaders).length > 0
|
|
||||||
? {
|
|
||||||
requestHeaders: mapHeadersToDeclarativeNetRequestHeaders(req.body.requestHeaders, 'set'),
|
|
||||||
}
|
|
||||||
: {}),
|
|
||||||
responseHeaders: [
|
|
||||||
{
|
|
||||||
header: 'Access-Control-Allow-Origin',
|
|
||||||
operation: 'set',
|
|
||||||
value: '*',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
header: 'Access-Control-Allow-Methods',
|
|
||||||
operation: 'set',
|
|
||||||
value: 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
header: 'Access-Control-Allow-Headers',
|
|
||||||
operation: 'set',
|
|
||||||
value: '*',
|
|
||||||
},
|
|
||||||
...mapHeadersToDeclarativeNetRequestHeaders(req.body.responseHeaders ?? {}, 'set'),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
if (browser.runtime.lastError?.message) throw new Error(browser.runtime.lastError.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
res.send({
|
res.send({
|
||||||
success: true,
|
success: true,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
res.send({
|
res.send({
|
||||||
success: false,
|
success: false,
|
||||||
error: err.message,
|
error: err.message,
|
||||||
|
110
src/utils/declarativeNetRequest.ts
Normal file
110
src/utils/declarativeNetRequest.ts
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import { isChrome } from './extension';
|
||||||
|
|
||||||
|
interface DynamicRule {
|
||||||
|
ruleId: number;
|
||||||
|
targetDomains?: [string, ...string[]];
|
||||||
|
targetRegex?: string;
|
||||||
|
requestHeaders?: Record<string, string>;
|
||||||
|
responseHeaders?: Record<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapHeadersToDeclarativeNetRequestHeaders = (
|
||||||
|
headers: Record<string, string>,
|
||||||
|
op: string,
|
||||||
|
): { header: string; operation: any; value: string }[] => {
|
||||||
|
return Object.entries(headers).map(([name, value]) => ({
|
||||||
|
header: name,
|
||||||
|
operation: op,
|
||||||
|
value,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setDynamicRules = async (body: DynamicRule) => {
|
||||||
|
if (isChrome()) {
|
||||||
|
await chrome.declarativeNetRequest.updateDynamicRules({
|
||||||
|
removeRuleIds: [body.ruleId],
|
||||||
|
addRules: [
|
||||||
|
{
|
||||||
|
id: body.ruleId,
|
||||||
|
condition: {
|
||||||
|
...(body.targetDomains && { requestDomains: body.targetDomains }),
|
||||||
|
...(body.targetRegex && { regexFilter: body.targetRegex }),
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
type: chrome.declarativeNetRequest.RuleActionType.MODIFY_HEADERS,
|
||||||
|
...(body.requestHeaders && Object.keys(body.requestHeaders).length > 0
|
||||||
|
? {
|
||||||
|
requestHeaders: mapHeadersToDeclarativeNetRequestHeaders(
|
||||||
|
body.requestHeaders,
|
||||||
|
chrome.declarativeNetRequest.HeaderOperation.SET,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
responseHeaders: [
|
||||||
|
{
|
||||||
|
header: 'Access-Control-Allow-Origin',
|
||||||
|
operation: chrome.declarativeNetRequest.HeaderOperation.SET,
|
||||||
|
value: '*',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: 'Access-Control-Allow-Methods',
|
||||||
|
operation: chrome.declarativeNetRequest.HeaderOperation.SET,
|
||||||
|
value: 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: 'Access-Control-Allow-Headers',
|
||||||
|
operation: chrome.declarativeNetRequest.HeaderOperation.SET,
|
||||||
|
value: '*',
|
||||||
|
},
|
||||||
|
...mapHeadersToDeclarativeNetRequestHeaders(
|
||||||
|
body.responseHeaders ?? {},
|
||||||
|
chrome.declarativeNetRequest.HeaderOperation.SET,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
if (chrome.runtime.lastError?.message) throw new Error(chrome.runtime.lastError.message);
|
||||||
|
} else {
|
||||||
|
await browser.declarativeNetRequest.updateDynamicRules({
|
||||||
|
removeRuleIds: [body.ruleId],
|
||||||
|
addRules: [
|
||||||
|
{
|
||||||
|
id: body.ruleId,
|
||||||
|
condition: {
|
||||||
|
...(body.targetDomains && { requestDomains: body.targetDomains }),
|
||||||
|
...(body.targetRegex && { regexFilter: body.targetRegex }),
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
type: 'modifyHeaders',
|
||||||
|
...(body.requestHeaders && Object.keys(body.requestHeaders).length > 0
|
||||||
|
? {
|
||||||
|
requestHeaders: mapHeadersToDeclarativeNetRequestHeaders(body.requestHeaders, 'set'),
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
responseHeaders: [
|
||||||
|
{
|
||||||
|
header: 'Access-Control-Allow-Origin',
|
||||||
|
operation: 'set',
|
||||||
|
value: '*',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: 'Access-Control-Allow-Methods',
|
||||||
|
operation: 'set',
|
||||||
|
value: 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: 'Access-Control-Allow-Headers',
|
||||||
|
operation: 'set',
|
||||||
|
value: '*',
|
||||||
|
},
|
||||||
|
...mapHeadersToDeclarativeNetRequestHeaders(body.responseHeaders ?? {}, 'set'),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
if (browser.runtime.lastError?.message) throw new Error(browser.runtime.lastError.message);
|
||||||
|
}
|
||||||
|
};
|
Reference in New Issue
Block a user