waitForAnalysisResults calls every PollFrequency seconds to the VT API and checks whether an analysis is completed or not. When the analysis is completed it is returned.
(cli *utils.APIClient, analysisId string, ds *utils.DoerState)
| 40 | // checks whether an analysis is completed or not. When the analysis is completed |
| 41 | // it is returned. |
| 42 | func waitForAnalysisResults(cli *utils.APIClient, analysisId string, ds *utils.DoerState) (*vt.Object, error) { |
| 43 | ds.Progress = "Waiting for analysis completion..." |
| 44 | ticker := time.NewTicker(PollFrequency) |
| 45 | defer ticker.Stop() |
| 46 | ctx, cancel := context.WithTimeout(context.Background(), TimeoutLimit) |
| 47 | defer cancel() |
| 48 | i := 1 |
| 49 | |
| 50 | for { |
| 51 | select { |
| 52 | case <-ctx.Done(): |
| 53 | return nil, ctx.Err() |
| 54 | case <-ticker.C: |
| 55 | ds.Progress = fmt.Sprintf("Waiting for analysis completion...%s", strings.Repeat(".", i)) |
| 56 | i++ |
| 57 | if obj, err := cli.GetObject(vt.URL(fmt.Sprintf("analyses/%s", analysisId))); err != nil { |
| 58 | // If the API returned an error 503 (transient error) retry; otherwise just return |
| 59 | // the error to the user. |
| 60 | if e, ok := err.(*vt.Error); !ok || e.Code != "TransientError" { |
| 61 | ds.Progress = "" |
| 62 | return nil, fmt.Errorf("error retrieving analysis result: %v", err) |
| 63 | } |
| 64 | } else if status, _ := obj.Get("status"); status == "completed" { |
| 65 | ds.Progress = "" |
| 66 | // Request the full object report and return it instead of just |
| 67 | // the analysis results. |
| 68 | return cli.GetObject(vt.URL(fmt.Sprintf("analyses/%s/item", analysisId))) |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | type fileScanner struct { |
| 75 | scanner *vt.FileScanner |