Skip to content

Commit 737de78

Browse files
committed
feat: update backend contract version and enhance xHTTP extra parameters functionality
- Upgraded @remnawave/backend-contract to version 0.3.60 in package.json and package-lock.json. - Added new localization entries for xHTTP extra parameters in English, Persian, and Russian locale files. - Implemented a drawer in BaseHostForm for managing xHTTP extra parameters with sample JSON input. - Updated EditHostModalWidget to handle xHTTP extra parameters during host updates.
1 parent 7c5380b commit 737de78

File tree

7 files changed

+172
-12
lines changed

7 files changed

+172
-12
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"@mantine/nprogress": "^7.17.2",
4646
"@monaco-editor/react": "^4.7.0",
4747
"@paralleldrive/cuid2": "2.2.2",
48-
"@remnawave/backend-contract": "0.3.54",
48+
"@remnawave/backend-contract": "0.3.60",
4949
"@stablelib/base64": "^2.0.1",
5050
"@stablelib/x25519": "^2.0.1",
5151
"@tabler/icons-react": "^3.31.0",

public/locales/en/remnawave.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,13 @@
304304
"tls-transport-layer-security": "TLS (Transport Layer Security)",
305305
"none": "None",
306306
"inbounds-default": "Inbound's default",
307-
"here-you-can-override-security-settings-from-xtls-config": "Here you can override security settings from XTLS Config."
307+
"here-you-can-override-security-settings-from-xtls-config": "Here you can override security settings from XTLS Config.",
308+
"extra-xhttp": "Extra xHTTP",
309+
"xhttp-extra-params": "xHTTP extra params",
310+
"extra-xhttp-description": "This extra params will work only with xHTTP protocol. Pass object \"extra\" to the client. This JSON input is not validated, be sure to paste the correct extra params. Use the button below to copy the basic extra params, then paste it into the JSON input.",
311+
"invalid-json": "Invalid JSON",
312+
"fill-with-sample-xhttp-extra-params": "Fill with sample xHTTP extra params",
313+
"close": "Close"
308314
},
309315
"base-node-form": {
310316
"country": "Country",
@@ -802,4 +808,4 @@
802808
"updated-at": "Updated At"
803809
}
804810
}
805-
}
811+
}

public/locales/fa/remnawave.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,13 @@
304304
"inbounds-default": "پیش فرض ورودی",
305305
"none": "هیچ کدام",
306306
"security-layer": "لایه امنیتی",
307-
"tls-transport-layer-security": "TLS (امنیت لایه حمل و نقل)"
307+
"tls-transport-layer-security": "TLS (امنیت لایه حمل و نقل)",
308+
"extra-xhttp": "Extra xHTTP",
309+
"xhttp-extra-params": "xHTTP extra params",
310+
"extra-xhttp-description": "This extra params will work only with xHTTP protocol. Pass object \"extra\" to the client. This JSON input is not validated, be sure to paste the correct extra params. Use the button below to copy the basic extra params, then paste it into the JSON input.",
311+
"invalid-json": "Invalid JSON",
312+
"fill-with-sample-xhttp-extra-params": "Fill with sample xHTTP extra params",
313+
"close": "Close"
308314
},
309315
"base-node-form": {
310316
"country": "کشور",

public/locales/ru/remnawave.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,13 @@
304304
"inbounds-default": "По умолчанию",
305305
"none": "None",
306306
"security-layer": "Security Layer",
307-
"tls-transport-layer-security": "TLS"
307+
"tls-transport-layer-security": "TLS",
308+
"extra-xhttp": "Extra xHTTP",
309+
"xhttp-extra-params": "xHTTP extra params",
310+
"extra-xhttp-description": "This extra params will work only with xHTTP protocol. Pass object \"extra\" to the client. This JSON input is not validated, be sure to paste the correct extra params. Use the button below to copy the basic extra params, then paste it into the JSON input.",
311+
"invalid-json": "Invalid JSON",
312+
"fill-with-sample-xhttp-extra-params": "Fill with sample xHTTP extra params",
313+
"close": "Close"
308314
},
309315
"base-node-form": {
310316
"country": "Страна",

src/shared/ui/forms/hosts/base-host-form/base-host-form.tsx

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,112 @@ import {
22
ActionIcon,
33
Button,
44
Collapse,
5+
Drawer,
56
Group,
7+
JsonInput,
68
NumberInput,
79
Select,
810
Stack,
911
Switch,
12+
Text,
1013
TextInput,
1114
Tooltip
1215
} from '@mantine/core'
16+
import {
17+
PiArrowUpDuotone,
18+
PiCaretDown,
19+
PiCaretUp,
20+
PiFloppyDiskDuotone,
21+
PiInfo,
22+
PiPencilDuotone
23+
} from 'react-icons/pi'
1324
import {
1425
ALPN,
1526
CreateHostCommand,
1627
FINGERPRINTS,
1728
SECURITY_LAYERS,
1829
UpdateHostCommand
1930
} from '@remnawave/backend-contract'
20-
import { PiCaretDown, PiCaretUp, PiFloppyDiskDuotone, PiInfo } from 'react-icons/pi'
31+
import { useDisclosure } from '@mantine/hooks'
2132
import { useTranslation } from 'react-i18next'
2233

2334
import { DeleteHostFeature } from '@features/ui/dashboard/hosts/delete-host'
2435
import { RemarkInfoPopoverWidget } from '@widgets/dashboard/hosts/popovers'
2536

2637
import { IProps } from './interfaces'
2738

39+
const basicXHttpExtraParams = `{
40+
"headers": {},
41+
"xPaddingBytes": "100-1000",
42+
"noGRPCHeader": false,
43+
"scMaxEachPostBytes": 1000000,
44+
"scMinPostsIntervalMs": 30,
45+
"scStreamUpServerSecs": "20-80",
46+
"xmux": {
47+
"maxConcurrency": "16-32",
48+
"maxConnections": 0,
49+
"cMaxReuseTimes": 0,
50+
"hMaxRequestTimes": "600-900",
51+
"hMaxReusableSecs": "1800-3000",
52+
"hKeepAlivePeriod": 0
53+
},
54+
"downloadSettings": {
55+
"address": "",
56+
"port": 443,
57+
"network": "xhttp",
58+
"security": "tls",
59+
"tlsSettings": {},
60+
"xhttpSettings": {
61+
"path": "/yourpath"
62+
},
63+
"sockopt": {}
64+
}
65+
}`
66+
67+
const pasteBasicXHttpExtraParams = `{
68+
"headers": {},
69+
"xPaddingBytes": "100-1000",
70+
"noGRPCHeader": false,
71+
"scMaxEachPostBytes": 1000000,
72+
"scMinPostsIntervalMs": 30,
73+
"scStreamUpServerSecs": "20-80",
74+
"xmux": {
75+
"maxConcurrency": "16-32",
76+
"maxConnections": 0,
77+
"cMaxReuseTimes": 0,
78+
"hMaxRequestTimes": "600-900",
79+
"hMaxReusableSecs": "1800-3000",
80+
"hKeepAlivePeriod": 0
81+
}
82+
}
83+
`
84+
2885
export const BaseHostForm = <T extends CreateHostCommand.Request | UpdateHostCommand.Request>(
2986
props: IProps<T>
3087
) => {
3188
const { form, advancedOpened, handleSubmit, host, inbounds, setAdvancedOpened, isSubmitting } =
3289
props
3390

3491
const { t } = useTranslation()
92+
const [opened, { open, close }] = useDisclosure(false)
3593

3694
const securityLayerLabels = {
3795
[SECURITY_LAYERS.TLS]: t('base-host-form.tls-transport-layer-security'),
3896
[SECURITY_LAYERS.NONE]: t('base-host-form.none'),
3997
[SECURITY_LAYERS.DEFAULT]: t('base-host-form.inbounds-default')
4098
}
4199

100+
const isXhttpExtraButtonDisabled = () => {
101+
return (
102+
!inbounds ||
103+
!form.getValues().inboundUuid ||
104+
!inbounds.some(
105+
(inbound) =>
106+
inbound.uuid === form.getValues().inboundUuid && inbound.network === 'xhttp'
107+
)
108+
)
109+
}
110+
42111
return (
43112
<form onSubmit={handleSubmit}>
44113
<Stack gap="md">
@@ -226,6 +295,17 @@ export const BaseHostForm = <T extends CreateHostCommand.Request | UpdateHostCom
226295
{...form.getInputProps('fingerprint')}
227296
w="55%"
228297
/>
298+
299+
<Button
300+
color="pink"
301+
disabled={isXhttpExtraButtonDisabled()}
302+
leftSection={<PiPencilDuotone />}
303+
mt={'xs'}
304+
onClick={open}
305+
variant="light"
306+
>
307+
{t('base-host-form.extra-xhttp')}
308+
</Button>
229309
</Group>
230310
</Stack>
231311
</Collapse>
@@ -249,6 +329,43 @@ export const BaseHostForm = <T extends CreateHostCommand.Request | UpdateHostCom
249329
{t('base-host-form.save')}
250330
</Button>
251331
</Group>
332+
333+
<Drawer
334+
onClose={close}
335+
opened={opened}
336+
overlayProps={{ backgroundOpacity: 0.6, blur: 0 }}
337+
padding="lg"
338+
position="right"
339+
size="lg"
340+
title={t('base-host-form.xhttp-extra-params')}
341+
>
342+
<Stack gap="md">
343+
<Text size="sm">{t('base-host-form.extra-xhttp-description')}</Text>
344+
<JsonInput
345+
autosize
346+
formatOnBlur
347+
key={form.key('xHttpExtraParams')}
348+
minRows={15}
349+
placeholder={basicXHttpExtraParams}
350+
validationError={t('base-host-form.invalid-json')}
351+
{...form.getInputProps('xHttpExtraParams')}
352+
/>
353+
354+
<Button
355+
color="gray"
356+
leftSection={<PiArrowUpDuotone size="1.2rem" />}
357+
onClick={() => {
358+
// @ts-expect-error -- TODO: fix this
359+
form.setFieldValue('xHttpExtraParams', pasteBasicXHttpExtraParams)
360+
}}
361+
variant="light"
362+
>
363+
{t('base-host-form.fill-with-sample-xhttp-extra-params')}
364+
</Button>
365+
366+
<Button onClick={close}>{t('base-host-form.close')}</Button>
367+
</Stack>
368+
</Drawer>
252369
</form>
253370
)
254371
}

src/widgets/dashboard/hosts/edit-host-modal/edit-host-modal.widget.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ export const EditHostModalWidget = () => {
2626
const form = useForm<UpdateHostCommand.Request>({
2727
name: 'edit-host-form',
2828
mode: 'uncontrolled',
29-
validate: zodResolver(UpdateHostCommand.RequestSchema.omit({ uuid: true }))
29+
validate: zodResolver(
30+
UpdateHostCommand.RequestSchema.omit({ uuid: true, xHttpExtraParams: true })
31+
)
3032
})
3133

3234
const handleClose = () => {
@@ -50,6 +52,14 @@ export const EditHostModalWidget = () => {
5052

5153
useEffect(() => {
5254
if (host && inbounds) {
55+
let xHttpExtraParamsParsed: null | object | string
56+
57+
if (typeof host.xHttpExtraParams === 'object' && host.xHttpExtraParams !== null) {
58+
xHttpExtraParamsParsed = JSON.stringify(host.xHttpExtraParams, null, 2)
59+
} else {
60+
xHttpExtraParamsParsed = ''
61+
}
62+
5363
form.setValues({
5464
remark: host.remark,
5565
address: host.address,
@@ -61,6 +71,7 @@ export const EditHostModalWidget = () => {
6171
host: host.host ?? undefined,
6272
path: host.path ?? undefined,
6373
alpn: (host.alpn as UpdateHostCommand.Request['alpn']) ?? undefined,
74+
xHttpExtraParams: xHttpExtraParamsParsed,
6475
fingerprint:
6576
(host.fingerprint as UpdateHostCommand.Request['fingerprint']) ?? undefined
6677
})
@@ -79,11 +90,25 @@ export const EditHostModalWidget = () => {
7990
return
8091
}
8192

93+
let xHttpExtraParams
94+
95+
try {
96+
if (values.xHttpExtraParams === '') {
97+
xHttpExtraParams = null
98+
} else {
99+
xHttpExtraParams = JSON.parse(values.xHttpExtraParams as unknown as string)
100+
}
101+
} catch (error) {
102+
xHttpExtraParams = null
103+
// silence
104+
}
105+
82106
updateHost({
83107
variables: {
84108
...values,
85109
isDisabled: !values.isDisabled,
86-
uuid: host.uuid
110+
uuid: host.uuid,
111+
xHttpExtraParams
87112
}
88113
})
89114
})

0 commit comments

Comments
 (0)