feat(providers): account calls (auth/refresh/credits) egress on the local IP
Now only the generate/video submit uses proxy.url; cookie-exchange/login, token refresh, credit-balance and project/session bootstrap all go direct. Also splits adobe GenerateVideo (submit=proxy, poll/download=local). Verified live: adobe gpt 1K cookie-exchange via local IP, submit 23.244.30.102 (proxy) vs local 76.209.9.65, 2.0MB PNG. Build+vet pass.
This commit is contained in:
@@ -74,7 +74,7 @@ func (c *Client) SetProxy(proxy string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ExchangeCookie(ctx context.Context, cookie string) (*CookieExchangeResult, error) {
|
func (c *Client) ExchangeCookie(ctx context.Context, cookie string) (*CookieExchangeResult, error) {
|
||||||
sess, err := c.newTLSClient()
|
sess, err := c.newDirectTLSClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -234,7 +234,12 @@ func (c *Client) GenerateImage(ctx context.Context, token, modelID, prompt, aspe
|
|||||||
// in meta["video_url"] — used by the async /v1/videos job, which proxies that URL
|
// in meta["video_url"] — used by the async /v1/videos job, which proxies that URL
|
||||||
// on /content instead of persisting the file.
|
// on /content instead of persisting the file.
|
||||||
func (c *Client) GenerateVideo(ctx context.Context, token, engine, prompt, aspectRatio string, durationSeconds int, resolution, referenceMode, upstreamModel string, blobIDs []string, downloadResult bool) ([]byte, map[string]any, error) {
|
func (c *Client) GenerateVideo(ctx context.Context, token, engine, prompt, aspectRatio string, durationSeconds int, resolution, referenceMode, upstreamModel string, blobIDs []string, downloadResult bool) ([]byte, map[string]any, error) {
|
||||||
sess, err := c.newTLSClient()
|
// Only the submit goes through the proxy; polling + download run on the local IP.
|
||||||
|
submitSess, err := c.newTLSClient()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pollSess, err := c.newDirectTLSClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -244,12 +249,12 @@ func (c *Client) GenerateVideo(ctx context.Context, token, engine, prompt, aspec
|
|||||||
if engine == "firefly-video" {
|
if engine == "firefly-video" {
|
||||||
endpoint = fireflyVideoSubmitURL
|
endpoint = fireflyVideoSubmitURL
|
||||||
}
|
}
|
||||||
respBody, pollURL, err := c.submitVideo(ctx, sess, token, endpoint, payload)
|
respBody, pollURL, err := c.submitVideo(ctx, submitSess, token, endpoint, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
_ = respBody
|
_ = respBody
|
||||||
meta, data, pollErr := c.pollVideo(ctx, sess, token, pollURL, downloadResult)
|
meta, data, pollErr := c.pollVideo(ctx, pollSess, token, pollURL, downloadResult)
|
||||||
if pollErr != nil {
|
if pollErr != nil {
|
||||||
return nil, nil, pollErr
|
return nil, nil, pollErr
|
||||||
}
|
}
|
||||||
@@ -261,7 +266,7 @@ func (c *Client) FetchAccountProfile(ctx context.Context, token string) (map[str
|
|||||||
if token == "" {
|
if token == "" {
|
||||||
return map[string]any{}, nil
|
return map[string]any{}, nil
|
||||||
}
|
}
|
||||||
sess, err := c.newTLSClient()
|
sess, err := c.newDirectTLSClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -346,7 +351,7 @@ func (c *Client) FetchCreditsBalance(ctx context.Context, token string) (map[str
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sess, err := c.newTLSClient()
|
sess, err := c.newDirectTLSClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ func ExtractAccountInfo(token string) map[string]any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) FetchImageQuota(ctx context.Context, accessToken string) (map[string]any, error) {
|
func (c *Client) FetchImageQuota(ctx context.Context, accessToken string) (map[string]any, error) {
|
||||||
session, err := c.newSession(accessToken)
|
session, err := c.newDirectSession(accessToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ func (c *Client) RefreshIfNeeded(ctx context.Context, cred string) (string, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) refreshPost(ctx context.Context, refreshToken string) ([]byte, int, error) {
|
func (c *Client) refreshPost(ctx context.Context, refreshToken string) ([]byte, int, error) {
|
||||||
client, err := c.newTLSClient()
|
client, err := c.newDirectTLSClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
@@ -305,7 +305,7 @@ func (c *Client) FetchCreditsBalance(ctx context.Context, cred string) (map[stri
|
|||||||
return unknownBalance("bad credential"), nil
|
return unknownBalance("bad credential"), nil
|
||||||
}
|
}
|
||||||
userID := userIDFromToken(cr.Token)
|
userID := userIDFromToken(cr.Token)
|
||||||
body, status, err := c.apiGet(ctx, cr.Token, apiBase+"/v1/credit?org_id="+userID)
|
body, status, err := c.apiGetP(ctx, cr.Token, apiBase+"/v1/credit?org_id="+userID, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return unknownBalance("network: " + err.Error()), nil
|
return unknownBalance("network: " + err.Error()), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ func (c *Client) RefreshIfNeeded(ctx context.Context, cookie string) (string, bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) refreshPost(ctx context.Context, refreshToken string) ([]byte, int, error) {
|
func (c *Client) refreshPost(ctx context.Context, refreshToken string) ([]byte, int, error) {
|
||||||
client, err := c.newTLSClient()
|
client, err := c.newDirectTLSClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
@@ -307,7 +307,7 @@ func (c *Client) FetchCreditsBalance(ctx context.Context, cookie string) (map[st
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
// NOTE: no /app here — the heavy SSR activation is done separately (on recovery
|
// NOTE: no /app here — the heavy SSR activation is done separately (on recovery
|
||||||
// and at generation via Activate). This probe just reads the current balance.
|
// and at generation via Activate). This probe just reads the current balance.
|
||||||
body, status, err := c.apiGet(probeCtx, cookie, "/api/billing-data")
|
body, status, err := c.apiGetP(probeCtx, cookie, "/api/billing-data", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return unknownBalance("network: " + err.Error()), nil
|
return unknownBalance("network: " + err.Error()), nil
|
||||||
}
|
}
|
||||||
@@ -366,7 +366,7 @@ func (c *Client) Activate(ctx context.Context, cookie string) {
|
|||||||
}
|
}
|
||||||
actCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 60*time.Second)
|
actCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 60*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
_, _, _ = c.apiGet(actCtx, cookie, "/app")
|
_, _, _ = c.apiGetP(actCtx, cookie, "/app", false)
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
c.actAt[key] = time.Now().Unix()
|
c.actAt[key] = time.Now().Unix()
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const (
|
|||||||
// ensureProject returns a flux project id for the account: the first existing
|
// ensureProject returns a flux project id for the account: the first existing
|
||||||
// project, or a freshly created one. Generation requires a project.
|
// project, or a freshly created one. Generation requires a project.
|
||||||
func (c *Client) ensureProject(ctx context.Context, cookie string) (string, error) {
|
func (c *Client) ensureProject(ctx context.Context, cookie string) (string, error) {
|
||||||
body, status, err := c.apiGet(ctx, cookie, "/api/flux-projects")
|
body, status, err := c.apiGetP(ctx, cookie, "/api/flux-projects", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("%w: list projects: %s", ErrTemporaryUpstream, err.Error())
|
return "", fmt.Errorf("%w: list projects: %s", ErrTemporaryUpstream, err.Error())
|
||||||
}
|
}
|
||||||
@@ -309,6 +309,7 @@ func (c *Client) apiPostP(ctx context.Context, cookie, path, contentType string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) apiPostJSON(ctx context.Context, cookie, path string, payload any) ([]byte, int, error) {
|
func (c *Client) apiPostJSON(ctx context.Context, cookie, path string, payload any) ([]byte, int, error) {
|
||||||
|
// project bootstrap runs on the local IP; only the generate submit uses the proxy.
|
||||||
b, _ := json.Marshal(payload)
|
b, _ := json.Marshal(payload)
|
||||||
return c.apiPost(ctx, cookie, path, "application/json", b)
|
return c.apiPostP(ctx, cookie, path, "application/json", b, false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ func (c *Client) GetSession(ctx context.Context, cookie string) (*Session, error
|
|||||||
}
|
}
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
|
|
||||||
client, err := c.newTLSClient()
|
client, err := c.newDirectTLSClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -205,7 +205,7 @@ func (c *Client) FetchCreditsBalance(ctx context.Context, cookie string) (map[st
|
|||||||
"variables": map[string]any{"sub": sess.CognitoSub},
|
"variables": map[string]any{"sub": sess.CognitoSub},
|
||||||
"query": qGetTokens,
|
"query": qGetTokens,
|
||||||
})
|
})
|
||||||
body, status, err := c.graphql(ctx, sess.AccessToken, payload)
|
body, status, err := c.graphqlP(ctx, sess.AccessToken, payload, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return unknownBalance("network: " + err.Error()), nil
|
return unknownBalance("network: " + err.Error()), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ func (c *Client) FetchCreditsBalance(ctx context.Context, token string) (map[str
|
|||||||
return unknownBalance("no team id"), nil
|
return unknownBalance("no team id"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := c.newTLSClient()
|
client, err := c.newDirectTLSClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user