A stored legacy URL ending in /json now gets HTTP 400 from impio. The fetcher must retry the toggled URL (suffix stripped) and succeed.
(t *testing.T)
| 173 | // A stored legacy URL ending in /json now gets HTTP 400 from impio. The |
| 174 | // fetcher must retry the toggled URL (suffix stripped) and succeed. |
| 175 | func TestFetchSubscriptionImpioJSONFallback(t *testing.T) { |
| 176 | var paths []string |
| 177 | ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 178 | // Icon discovery re-fetches the page with a browser UA; only count |
| 179 | // actual subscription fetches (ResultV UA). |
| 180 | if strings.HasPrefix(r.Header.Get("User-Agent"), "ResultV/") { |
| 181 | paths = append(paths, r.URL.Path) |
| 182 | } |
| 183 | if r.URL.Path != "/api/sub/raw/abc" { |
| 184 | w.WriteHeader(http.StatusBadRequest) |
| 185 | return |
| 186 | } |
| 187 | w.Header().Set("Content-Type", "text/plain; charset=utf-8") |
| 188 | _, _ = w.Write([]byte("vless://af815621-b245-4149-89da-dd184cfc4b3d@example.com:443?type=tcp&security=none#Node")) |
| 189 | })) |
| 190 | defer ts.Close() |
| 191 | |
| 192 | oldHost := impioSubscriptionHost |
| 193 | impioSubscriptionHost = strings.TrimPrefix(ts.URL, "http://") |
| 194 | defer func() { impioSubscriptionHost = oldHost }() |
| 195 | |
| 196 | app := NewApp() |
| 197 | entries, _, _, _, _, _, _, err := app.fetchSubscriptionFromURL(ts.URL+"/api/sub/raw/abc/json", true) |
| 198 | if err != nil { |
| 199 | t.Fatalf("expected fallback to strip /json and succeed, got %v (paths: %v)", err, paths) |
| 200 | } |
| 201 | if len(entries) != 1 { |
| 202 | t.Fatalf("expected 1 entry after fallback, got %d", len(entries)) |
| 203 | } |
| 204 | if len(paths) != 2 || paths[0] != "/api/sub/raw/abc/json" || paths[1] != "/api/sub/raw/abc" { |
| 205 | t.Fatalf("expected /json first then stripped retry, got %v", paths) |
| 206 | } |
| 207 | if entries[0].SubscriptionURL != ts.URL+"/api/sub/raw/abc" { |
| 208 | t.Fatalf("entries must carry the working URL, got %q", entries[0].SubscriptionURL) |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | // A fresh raw impio URL (no /json) must be fetched as-is with no suffix |
| 213 | // rewriting — this is the deep-link import path that used to 400. |
nothing calls this directly
no test coverage detected