diff --git a/common/convert/converter.go b/common/convert/converter.go
index 809aa94f..222dd9fa 100644
--- a/common/convert/converter.go
+++ b/common/convert/converter.go
@@ -330,7 +330,7 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) {
 
 				vmess["h2-opts"] = h2Opts
 
-			case "ws":
+			case "ws", "httpupgrade":
 				headers := make(map[string]any)
 				wsOpts := make(map[string]any)
 				wsOpts["path"] = []string{"/"}
@@ -338,7 +338,30 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) {
 					headers["Host"] = host.(string)
 				}
 				if path, ok := values["path"]; ok && path != "" {
-					wsOpts["path"] = path.(string)
+					path := path.(string)
+					pathURL, err := url.Parse(path)
+					if err == nil {
+						query := pathURL.Query()
+						if earlyData := query.Get("ed"); earlyData != "" {
+							med, err := strconv.Atoi(earlyData)
+							if err == nil {
+								switch network {
+								case "ws":
+									wsOpts["max-early-data"] = med
+									wsOpts["early-data-header-name"] = "Sec-WebSocket-Protocol"
+								case "httpupgrade":
+									wsOpts["v2ray-http-upgrade-fast-open"] = true
+								}
+								query.Del("ed")
+								pathURL.RawQuery = query.Encode()
+								path = pathURL.String()
+							}
+						}
+						if earlyDataHeader := query.Get("eh"); earlyDataHeader != "" {
+							wsOpts["early-data-header-name"] = earlyDataHeader
+						}
+					}
+					wsOpts["path"] = path
 				}
 				wsOpts["headers"] = headers
 				vmess["ws-opts"] = wsOpts
diff --git a/common/convert/v.go b/common/convert/v.go
index 2d8cf732..4102ab75 100644
--- a/common/convert/v.go
+++ b/common/convert/v.go
@@ -100,7 +100,7 @@ func handleVShareLink(names map[string]int, url *url.URL, scheme string, proxy m
 		h2Opts["headers"] = headers
 		proxy["h2-opts"] = h2Opts
 
-	case "ws":
+	case "ws", "httpupgrade":
 		headers := make(map[string]any)
 		wsOpts := make(map[string]any)
 		headers["User-Agent"] = RandUserAgent()
@@ -113,7 +113,13 @@ func handleVShareLink(names map[string]int, url *url.URL, scheme string, proxy m
 			if err != nil {
 				return fmt.Errorf("bad WebSocket max early data size: %v", err)
 			}
-			wsOpts["max-early-data"] = med
+			switch network {
+			case "ws":
+				wsOpts["max-early-data"] = med
+				wsOpts["early-data-header-name"] = "Sec-WebSocket-Protocol"
+			case "httpupgrade":
+				wsOpts["v2ray-http-upgrade-fast-open"] = true
+			}
 		}
 		if earlyDataHeader := query.Get("eh"); earlyDataHeader != "" {
 			wsOpts["early-data-header-name"] = earlyDataHeader
diff --git a/docs/config.yaml b/docs/config.yaml
index 4d0e995e..6aa06862 100644
--- a/docs/config.yaml
+++ b/docs/config.yaml
@@ -383,6 +383,7 @@ proxies: # socks5
       # headers:
       #   custom: value
       # v2ray-http-upgrade: false
+      # v2ray-http-upgrade-fast-open: false
 
   - name: "ss4-shadow-tls"
     type: ss
@@ -461,6 +462,7 @@ proxies: # socks5
       # max-early-data: 2048
       # early-data-header-name: Sec-WebSocket-Protocol
       # v2ray-http-upgrade: false
+      # v2ray-http-upgrade-fast-open: false
 
   - name: "vmess-h2"
     type: vmess
@@ -589,6 +591,7 @@ proxies: # socks5
       headers:
         Host: example.com
       # v2ray-http-upgrade: false
+      # v2ray-http-upgrade-fast-open: false
 
   # Trojan
   - name: "trojan"
@@ -633,6 +636,7 @@ proxies: # socks5
     #   headers:
     #     Host: example.com
     #   v2ray-http-upgrade: false
+    #   v2ray-http-upgrade-fast-open: false
 
   - name: "trojan-xtls"
     type: trojan