@@ -9,8 +9,10 @@ import kotlinx.serialization.json.Json
99import kotlinx.serialization.json.JsonElement
1010import kotlinx.serialization.json.JsonObject
1111import kotlinx.serialization.json.JsonObjectBuilder
12+ import kotlinx.serialization.json.JsonPrimitive
1213import kotlinx.serialization.json.add
1314import kotlinx.serialization.json.buildJsonObject
15+ import kotlinx.serialization.json.contentOrNull
1416import kotlinx.serialization.json.put
1517import kotlinx.serialization.json.putJsonArray
1618import kotlinx.serialization.json.putJsonObject
@@ -143,12 +145,10 @@ private fun JsonObjectBuilder.putRawSettings(params: V2RayParameters) {
143145
144146private fun JsonObjectBuilder.putWsSettings (params : V2RayParameters ) {
145147 putJsonObject(" wsSettings" ) {
148+ val transportHeaders = params.httpTransportHeaders(" WebSocket headers" )
146149 putIfNotBlank(" path" , params.path)
147- putIfNotBlank(" host" , params.host)
148- val headers = params.headers.toXrayJsonObjectOrNull(" WebSocket headers" )
149- if (headers != null ) {
150- put(" headers" , headers)
151- }
150+ putIfNotBlank(" host" , transportHeaders.host)
151+ transportHeaders.headers?.let { put(" headers" , it) }
152152 }
153153}
154154
@@ -164,12 +164,10 @@ private fun JsonObjectBuilder.putGrpcSettings(params: V2RayParameters) {
164164
165165private fun JsonObjectBuilder.putHttpUpgradeSettings (params : V2RayParameters ) {
166166 putJsonObject(" httpupgradeSettings" ) {
167+ val transportHeaders = params.httpTransportHeaders(" HTTPUpgrade headers" )
167168 putIfNotBlank(" path" , params.path)
168- putIfNotBlank(" host" , params.host)
169- val headers = params.headers.toXrayJsonObjectOrNull(" HTTPUpgrade headers" )
170- if (headers != null ) {
171- put(" headers" , headers)
172- }
169+ putIfNotBlank(" host" , transportHeaders.host)
170+ transportHeaders.headers?.let { put(" headers" , it) }
173171 }
174172}
175173
@@ -203,3 +201,37 @@ private fun String?.toXrayJsonObjectOrNull(fieldName: String): JsonObject? {
203201 return element as ? JsonObject
204202 ? : proxyValidationError(ProxyServerValidationError .JsonObjectRequired , fieldName)
205203}
204+
205+ private data class XrayHttpTransportHeaders (
206+ val host : String? ,
207+ val headers : JsonObject ? ,
208+ )
209+
210+ private fun V2RayParameters.httpTransportHeaders (fieldName : String ): XrayHttpTransportHeaders {
211+ val explicitHost = host?.trim()?.takeIf (String ::isNotEmpty)
212+ val parsedHeaders = headers.toXrayJsonObjectOrNull(fieldName)
213+ ? : return XrayHttpTransportHeaders (host = explicitHost, headers = null )
214+ var hostHeader: String? = null
215+ val filteredHeaders = buildJsonObject {
216+ parsedHeaders.forEach { (name, value) ->
217+ if (name.equals(" Host" , ignoreCase = true )) {
218+ if (hostHeader.isNullOrBlank()) {
219+ hostHeader = value.headerStringOrNull()
220+ }
221+ } else {
222+ put(name, value)
223+ }
224+ }
225+ }
226+ return XrayHttpTransportHeaders (
227+ host = explicitHost ? : hostHeader,
228+ headers = filteredHeaders.takeIf { it.isNotEmpty() },
229+ )
230+ }
231+
232+ private fun JsonElement.headerStringOrNull (): String? {
233+ return (this as ? JsonPrimitive )
234+ ?.contentOrNull
235+ ?.trim()
236+ ?.takeIf (String ::isNotEmpty)
237+ }
0 commit comments