MCPcopy
hub / github.com/wavetermdev/waveterm / fetchFavicon

Function fetchFavicon

pkg/faviconcache/faviconcache.go:125–178  ·  view source on GitHub ↗
(domain string)

Source from the content-addressed store, hash-verified

123}
124
125func fetchFavicon(domain string) (string, error) {
126 // Create a context that times out after 5 seconds.
127 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
128 defer cancel()
129
130 // Special case for github.com - use their dark favicon from assets domain
131 url := "https://" + domain + "/favicon.ico"
132 if domain == "github.com" {
133 url = "https://github.githubassets.com/favicons/favicon-dark.png"
134 }
135
136 // Create a new HTTP request with the context.
137 req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
138 if err != nil {
139 return "", fmt.Errorf("error creating request for %s: %w", url, err)
140 }
141
142 // Execute the HTTP request.
143 resp, err := http.DefaultClient.Do(req)
144 if err != nil {
145 return "", fmt.Errorf("error fetching favicon from %s: %w", url, err)
146 }
147 defer resp.Body.Close()
148
149 // Ensure we got a 200 OK.
150 if resp.StatusCode != http.StatusOK {
151 return "", fmt.Errorf("non-OK HTTP status: %d fetching %s", resp.StatusCode, url)
152 }
153
154 // Read the favicon bytes.
155 data, err := io.ReadAll(resp.Body)
156 if err != nil {
157 return "", fmt.Errorf("error reading favicon data from %s: %w", url, err)
158 }
159
160 // Encode the image bytes to base64.
161 b64Data := base64.StdEncoding.EncodeToString(data)
162 if len(b64Data) > maxIconSize {
163 return "", fmt.Errorf("favicon too large: %d bytes", len(b64Data))
164 }
165
166 // Try to detect MIME type from Content-Type header first
167 mimeType := resp.Header.Get("Content-Type")
168 if mimeType == "" {
169 // If no Content-Type header, detect from content
170 mimeType = http.DetectContentType(data)
171 }
172
173 if !strings.HasPrefix(mimeType, "image/") {
174 return "", fmt.Errorf("unexpected MIME type: %s", mimeType)
175 }
176
177 return "data:" + mimeType + ";base64," + b64Data, nil
178}
179
180// TODO store in blockstore
181

Callers 1

triggerAsyncFetchFunction · 0.85

Calls 3

CloseMethod · 0.65
ReadAllMethod · 0.45
GetMethod · 0.45

Tested by

no test coverage detected