diff --git a/api/playback/allanime_client.go b/api/playback/allanime_client.go index 2b7f790..9ecc599 100644 --- a/api/playback/allanime_client.go +++ b/api/playback/allanime_client.go @@ -98,7 +98,7 @@ func (rt *utlsRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) var allAnimeUTLSClient = &http.Client{ Transport: &utlsRoundTripper{}, - Timeout: 15 * time.Second, + Timeout: 30 * time.Second, } type searchResult struct { @@ -115,7 +115,7 @@ type allAnimeClient struct { func newAllAnimeClient() *allAnimeClient { return &allAnimeClient{ httpClient: &http.Client{ - Timeout: 12 * time.Second, + Timeout: 30 * time.Second, }, extractor: newProviderExtractor(), } @@ -305,7 +305,7 @@ func min(a, b int) int { return b } -func (c *allAnimeClient) extractSourceURLsFromData(data map[string]any) []StreamSource { +func (c *allAnimeClient) extractSourceURLsFromData(ctx context.Context, data map[string]any) []StreamSource { episodeData, ok := data["episode"].(map[string]any) if !ok { return nil @@ -357,9 +357,6 @@ func (c *allAnimeClient) extractSourceURLsFromData(data map[string]any) []Stream decoded = "/" + decoded } - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - extracted, err := c.extractor.ExtractVideoLinks(ctx, decoded) if err != nil { log.Printf("source extraction failed for %s: %v", decoded, err) @@ -510,7 +507,7 @@ func (c *allAnimeClient) GetEpisodeSources(ctx context.Context, showID string, e result, err := c.graphqlRequestWithHash(ctx, showID, episode, mode) if err == nil { // Result is already in shape {"episode": {"sourceUrls": [...]}} - sources := c.extractSourceURLsFromData(result) + sources := c.extractSourceURLsFromData(ctx, result) if len(sources) > 0 { return sources, nil } diff --git a/api/playback/provider_extractor.go b/api/playback/provider_extractor.go index c46e545..f0221cf 100644 --- a/api/playback/provider_extractor.go +++ b/api/playback/provider_extractor.go @@ -19,18 +19,37 @@ type providerExtractor struct { func newProviderExtractor() *providerExtractor { return &providerExtractor{ - httpClient: &http.Client{Timeout: 12 * time.Second}, - baseURL: "https://allanime.day", + httpClient: &http.Client{Timeout: 30 * time.Second}, + baseURL: allAnimeBaseURL, referer: allAnimeReferer, } } func (e *providerExtractor) ExtractVideoLinks(ctx context.Context, providerPath string) ([]StreamSource, error) { endpoint := e.baseURL + providerPath - resp, err := doProxiedRequest(ctx, e.httpClient, endpoint, e.referer) - if err != nil { - return nil, fmt.Errorf("fetch provider response: %w", err) + + var resp *http.Response + var err error + + for attempt := 0; attempt < 3; attempt++ { + if attempt > 0 { + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-time.After(time.Duration(attempt) * 2 * time.Second): + } + } + + resp, err = doProxiedRequest(ctx, e.httpClient, endpoint, e.referer) + if err == nil { + break + } + + if attempt == 2 { + return nil, fmt.Errorf("fetch provider response: %w", err) + } } + defer resp.Body.Close() body, err := io.ReadAll(io.LimitReader(resp.Body, 2*1024*1024)) diff --git a/cmd/server/main.go b/cmd/server/main.go index d98414e..d517747 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -127,7 +127,7 @@ func main() { Handler: server.NewRouter(app), ReadHeaderTimeout: 5 * time.Second, ReadTimeout: 10 * time.Second, - WriteTimeout: 30 * time.Second, + WriteTimeout: 120 * time.Second, IdleTimeout: 120 * time.Second, }