Files
dhkatzandClaude Opus 5.5 2280ad6314
CI / build (push) Successful in 34s
Show T5 products in the client's shop; keep float IDs and unknown paths off IMVU
The shop's T5 filter (maturity_rating "t5") is answered from the hub's products, fetched so they can be
shown and tried on; buying T5 products adds them to the hub library, and product.php details for
community products are answered here.

The client sends some product IDs as floats ("2000000008.0"): product.php passed the worn community
product to IMVU that way. Every ID is now read either way, and products.Guard refuses any request to
IMVU that still names a local ID given out. T5DE_PROXY_DUMP logs request and response bodies.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 01:15:16 -07:00

42 lines
1.4 KiB
Go

package products
import (
"net/url"
"regexp"
"strings"
"git.t5de.dev/t5de/t5de-proxy/internal/proxy"
)
// Guard is the last check before a request goes to IMVU: one that still names a community product (a local ID the
// proxy gave out, in its query or body, as an integer or a float) is refused, not sent. The interceptors take
// community products out of every request known to carry them; Guard stops the ones not known yet, and logs them
// so they can be handled.
type Guard struct{ Products *Products }
var localIDPattern = regexp.MustCompile(`(?:^|[^0-9.])(2[0-9]{9})(?:\.0+)?(?:[^0-9.]|$)`)
func (g Guard) Intercept(x *proxy.Exchange) error {
if x.Response != nil || !strings.HasSuffix(strings.ToLower(x.URL.Hostname()), ".imvu.com") {
return nil
}
query, _ := url.QueryUnescape(x.URL.RawQuery)
for _, text := range []string{query, x.URL.Path, string(x.Body)} {
for _, m := range localIDPattern.FindAllStringSubmatch(text, -1) {
id, ok := parseID(m[1])
if ok && IsCommunity(id) && g.Products.given(id) {
g.Products.logf("products: refused a request to %s%s: it names community product %d", x.URL.Host, x.URL.Path, id)
x.Response = localResponse(403, "application/json", []byte(`{"error":"t5de: community products stay off IMVU"}`))
return nil
}
}
}
return nil
}
// given reports whether a local ID was given to a product.
func (p *Products) given(local int64) bool {
_, ok := p.state.productID(local)
return ok
}