this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

identity package tweaks (#955)

- add user-agent
- ensure we drain HTTP requests in more code paths (allows
connections/streams to be re-used more efficiently)

authored by

bnewbold and committed by
GitHub
dd179c33 8af67f52

+31 -9
+3 -1
atproto/identity/base_directory.go
··· 33 33 // 34 34 // The intended use-case for this flag is as an optimization for services which do not care about handles, but still want to use the `Directory` interface (instead of `ResolveDID`). For example, relay implementations, or services validating inter-service auth requests. 35 35 SkipHandleVerification bool 36 + // User-Agent header for HTTP requests. Optional (ignored if empty string). 37 + UserAgent string 36 38 } 37 39 38 40 var _ Directory = (*BaseDirectory)(nil) ··· 107 109 return nil, fmt.Errorf("at-identifier neither a Handle nor a DID") 108 110 } 109 111 110 - func (d *BaseDirectory) Purge(ctx context.Context, a syntax.AtIdentifier) error { 112 + func (d *BaseDirectory) Purge(ctx context.Context, atid syntax.AtIdentifier) error { 111 113 // BaseDirectory itself does not implement caching 112 114 return nil 113 115 }
+3 -3
atproto/identity/cache_directory.go
··· 250 250 return nil, fmt.Errorf("at-identifier neither a Handle nor a DID") 251 251 } 252 252 253 - func (d *CacheDirectory) Purge(ctx context.Context, a syntax.AtIdentifier) error { 254 - handle, err := a.AsHandle() 253 + func (d *CacheDirectory) Purge(ctx context.Context, atid syntax.AtIdentifier) error { 254 + handle, err := atid.AsHandle() 255 255 if nil == err { // if not an error, is a handle 256 256 handle = handle.Normalize() 257 257 d.handleCache.Remove(handle) 258 258 return nil 259 259 } 260 - did, err := a.AsDID() 260 + did, err := atid.AsDID() 261 261 if nil == err { // if not an error, is a DID 262 262 d.identityCache.Remove(did) 263 263 return nil
+12
atproto/identity/did.go
··· 98 98 if err != nil { 99 99 return nil, fmt.Errorf("constructing HTTP request for did:web resolution: %w", err) 100 100 } 101 + if d.UserAgent != "" { 102 + req.Header.Set("User-Agent", d.UserAgent) 103 + } 104 + 101 105 resp, err := d.HTTPClient.Do(req) 102 106 103 107 // look for NXDOMAIN ··· 112 116 } 113 117 defer resp.Body.Close() 114 118 if resp.StatusCode == http.StatusNotFound { 119 + io.Copy(io.Discard, resp.Body) 115 120 return nil, fmt.Errorf("%w: did:web HTTP status 404", ErrDIDNotFound) 116 121 } 117 122 if resp.StatusCode != http.StatusOK { 123 + io.Copy(io.Discard, resp.Body) 118 124 return nil, fmt.Errorf("%w: did:web HTTP status %d", ErrDIDResolutionFailed, resp.StatusCode) 119 125 } 120 126 ··· 141 147 if err != nil { 142 148 return nil, fmt.Errorf("constructing HTTP request for did:plc resolution: %w", err) 143 149 } 150 + if d.UserAgent != "" { 151 + req.Header.Set("User-Agent", d.UserAgent) 152 + } 153 + 144 154 resp, err := d.HTTPClient.Do(req) 145 155 if err != nil { 146 156 return nil, fmt.Errorf("%w: PLC directory lookup: %w", ErrDIDResolutionFailed, err) 147 157 } 148 158 defer resp.Body.Close() 149 159 if resp.StatusCode == http.StatusNotFound { 160 + io.Copy(io.Discard, resp.Body) 150 161 return nil, fmt.Errorf("%w: PLC directory 404", ErrDIDNotFound) 151 162 } 152 163 if resp.StatusCode != http.StatusOK { 164 + io.Copy(io.Discard, resp.Body) 153 165 return nil, fmt.Errorf("%w: PLC directory status %d", ErrDIDResolutionFailed, resp.StatusCode) 154 166 } 155 167
+4 -1
atproto/identity/directory.go
··· 8 8 "time" 9 9 10 10 "github.com/bluesky-social/indigo/atproto/syntax" 11 + 12 + "github.com/carlmjohnson/versioninfo" 11 13 ) 12 14 13 15 // Ergonomic interface for atproto identity lookup, by DID or handle. ··· 27 29 Lookup(ctx context.Context, atid syntax.AtIdentifier) (*Identity, error) 28 30 29 31 // Flushes any cache of the indicated identifier. If directory is not using caching, can ignore this. 30 - Purge(ctx context.Context, i syntax.AtIdentifier) error 32 + Purge(ctx context.Context, atid syntax.AtIdentifier) error 31 33 } 32 34 33 35 // Indicates that handle resolution failed. A wrapped error may provide more context. This is only returned when looking up a handle, not when looking up a DID. ··· 80 82 TryAuthoritativeDNS: true, 81 83 // primary Bluesky PDS instance only supports HTTP resolution method 82 84 SkipDNSDomainSuffixes: []string{".bsky.social"}, 85 + UserAgent: "indigo-identity/" + versioninfo.Short(), 83 86 } 84 87 cached := NewCacheDirectory(&base, 250_000, time.Hour*24, time.Minute*2, time.Minute*5) 85 88 return &cached
+9 -4
atproto/identity/handle.go
··· 131 131 if err != nil { 132 132 return "", fmt.Errorf("constructing HTTP request for handle resolution: %w", err) 133 133 } 134 + if d.UserAgent != "" { 135 + req.Header.Set("User-Agent", d.UserAgent) 136 + } 134 137 135 138 resp, err := d.HTTPClient.Do(req) 136 139 if err != nil { ··· 144 147 return "", fmt.Errorf("%w: HTTP well-known request error: %w", ErrHandleResolutionFailed, err) 145 148 } 146 149 defer resp.Body.Close() 150 + if resp.ContentLength > 2048 { 151 + // NOTE: intentionally not draining body 152 + return "", fmt.Errorf("%w: HTTP well-known body too large for %s", ErrHandleResolutionFailed, handle) 153 + } 147 154 if resp.StatusCode == http.StatusNotFound { 155 + io.Copy(io.Discard, resp.Body) 148 156 return "", fmt.Errorf("%w: HTTP 404 for %s", ErrHandleNotFound, handle) 149 157 } 150 158 if resp.StatusCode != http.StatusOK { 159 + io.Copy(io.Discard, resp.Body) 151 160 return "", fmt.Errorf("%w: HTTP well-known status %d for %s", ErrHandleResolutionFailed, resp.StatusCode, handle) 152 - } 153 - 154 - if resp.ContentLength > 2048 { 155 - return "", fmt.Errorf("%w: HTTP well-known body too large for %s", ErrHandleResolutionFailed, handle) 156 161 } 157 162 158 163 b, err := io.ReadAll(io.LimitReader(resp.Body, 2048))