Trying a product on in the shop asks api.imvu.com/product/product-<id>/uml_products for related products; the guard refused it for T5 products, and the client showed an error. Community products now get an empty list (and not found for anything else) from the proxy. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
2280ad6314
commit
af9158513b
2 files changed
+30
No files matched your search
@@ -6,6 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -33,6 +34,14 @@ func (p *Products) Intercept(x *proxy.Exchange) error {
|
|||||||
if host == "api.imvu.com" && participantPath.MatchString(path) {
|
if host == "api.imvu.com" && participantPath.MatchString(path) {
|
||||||
return p.interceptParticipant(x)
|
return p.interceptParticipant(x)
|
||||||
}
|
}
|
||||||
|
if host == "api.imvu.com" {
|
||||||
|
if m := productPath.FindStringSubmatch(path); m != nil {
|
||||||
|
if id, ok := parseID(m[1]); ok && IsCommunity(id) {
|
||||||
|
x.Response = productAPIAnswer(path, m[2])
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
switch path {
|
switch path {
|
||||||
case "/api/xmlrpc/chat.php":
|
case "/api/xmlrpc/chat.php":
|
||||||
return p.interceptChat(x)
|
return p.interceptChat(x)
|
||||||
@@ -59,6 +68,21 @@ func (p *Products) Intercept(x *proxy.Exchange) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// productPath is IMVU's REST API for a product (api.imvu.com/product/product-<id>[/<relation>]).
|
||||||
|
var productPath = regexp.MustCompile(`^/product/product-([0-9.]+)(/[a-z_]+)?$`)
|
||||||
|
|
||||||
|
// productAPIAnswer answers the REST API about a community product: no related products (uml_products, which the
|
||||||
|
// shop's recommender asks for when a product is tried on), and nothing else.
|
||||||
|
func productAPIAnswer(path, relation string) *http.Response {
|
||||||
|
id := "https://api.imvu.com" + path
|
||||||
|
if relation == "/uml_products" {
|
||||||
|
b, _ := json.Marshal(map[string]any{"status": "success", "id": id, "denormalized": map[string]any{
|
||||||
|
id: map[string]any{"data": map[string]any{"total_count": 0, "items": []any{}}, "relations": map[string]any{}}}})
|
||||||
|
return localResponse(200, "application/json", b)
|
||||||
|
}
|
||||||
|
return localResponse(404, "application/json", []byte(`{"status":"failure","error":"NOT_FOUND"}`))
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Products) interceptXMLRPC(x *proxy.Exchange) error {
|
func (p *Products) interceptXMLRPC(x *proxy.Exchange) error {
|
||||||
call, err := xmlrpc.ParseCall(x.Body)
|
call, err := xmlrpc.ParseCall(x.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -112,6 +112,12 @@ func TestShop(t *testing.T) {
|
|||||||
}
|
}
|
||||||
h.do("POST", "https://secure.imvu.com/api/xmlrpc/client.php", call("test.avatarInfoForLogin2"), false, false)
|
h.do("POST", "https://secure.imvu.com/api/xmlrpc/client.php", call("test.avatarInfoForLogin2"), false, false)
|
||||||
|
|
||||||
|
// Trying one on asks IMVU's REST API for related products: answered here, with none.
|
||||||
|
status, b := h.do("GET", fmt.Sprintf("https://api.imvu.com/product/product-%d/uml_products?limit=6", coatLocal), nil, false, false)
|
||||||
|
if status != 200 || !strings.Contains(string(b), `"total_count":0`) {
|
||||||
|
t.Fatalf("uml_products: %d %s", status, b)
|
||||||
|
}
|
||||||
|
|
||||||
// Buying a T5 product adds it to the library; IMVU hears only of its own products.
|
// Buying a T5 product adds it to the library; IMVU hears only of its own products.
|
||||||
// Product details: community ones answered here, IMVU asked only for its own.
|
// Product details: community ones answered here, IMVU asked only for its own.
|
||||||
info := func(pids ...any) []map[string]any {
|
info := func(pids ...any) []map[string]any {
|
||||||
|
|||||||
Reference in new issue
Block a user