MCPcopy Create free account
hub / github.com/eventure/hide.client.linux / serverList

Method serverList

control/methods.go:212–252  ·  view source on GitHub ↗
(writer http.ResponseWriter, request *http.Request )

Source from the content-addressed store, hash-verified

210var cacheControlRegex = regexp.MustCompile( "[[:space:]]*max-age[[:space:]]*=[[:space:]]*([[:digit:]]+)" )
211
212func ( s *Server ) serverList(writer http.ResponseWriter, request *http.Request ) {
213 if request.Method != "GET" { http.Error( writer, http.StatusText( http.StatusNotFound ), http.StatusNotFound ); return }
214 select {
215 case s.connectionOpsLock<-struct{}{}: defer func() { <-s.connectionOpsLock }(); break
216 case <-time.NewTimer( time.Second ).C: http.Error( writer, http.StatusText( http.StatusConflict ), http.StatusConflict ); return
217 }
218
219 if slb := s.serverListBytes.Load(); slb != nil { writer.Header().Add( "content-type", "application/json" ); writer.Write( *slb ); log.Println( "sLst: ServerList sent" ); return }
220
221 s.connection.Lock(); defer s.connection.Unlock()
222
223 client := rest.New( s.connection.Config.Rest ) // Create a REST client ( must be a new one since FetchServerList changes client's configuration )
224
225 dohResolver := doh.New( s.connection.Config.DoH ) // Create a DoH resolver
226 dohResolver.Init()
227 client.SetDohResolver(dohResolver)
228
229 plainResolver := plain.New( s.connection.Config.Plain ) // Create a Plain resolver
230 if err := plainResolver.Init(); err != nil { log.Println( "sLst: [ERR] Plain resolver init failed", err ); http.Error( writer, err.Error(), http.StatusBadGateway ); return }
231 client.SetPlainResolver(plainResolver)
232
233 ctx, cancel := context.WithTimeout( context.Background(), s.connection.Config.Rest.RestTimeout )
234 defer cancel()
235
236 response, headers, err := client.FetchServerList( ctx )
237 if err != nil { log.Println( "sLst: [ERR] Server list fetch failed:", err ); http.Error( writer, err.Error(), http.StatusBadGateway ); return }
238
239 if maxAgeMatches := cacheControlRegex.FindStringSubmatch( headers.Get( "cache-control" ) ); len( maxAgeMatches ) > 1 {
240 if maxAge, err := strconv.ParseInt( maxAgeMatches[1], 10, 64 ); err == nil {
241 s.serverListBytes.Store( &response )
242 ttl := time.Duration( maxAge ) * time.Second
243 time.AfterFunc( ttl, func() { s.serverListBytes.Store( nil ); log.Println( "sLst: Server list expired" ) } )
244 log.Println( "sLst: Caching server list for", ttl )
245 }
246 }
247
248 writer.Header().Add( "content-type", "application/json" )
249 writer.Write( response )
250
251 log.Println( "sLst: ServerList sent" )
252}
253
254func ( s *Server ) externalIps(writer http.ResponseWriter, request *http.Request ) {
255 if request.Method != "GET" { http.Error( writer, http.StatusText( http.StatusNotFound ), http.StatusNotFound ); return }

Callers

nothing calls this directly

Calls 9

NewFunction · 0.92
NewFunction · 0.92
NewFunction · 0.92
WriteMethod · 0.80
SetDohResolverMethod · 0.80
SetPlainResolverMethod · 0.80
FetchServerListMethod · 0.80
ErrorMethod · 0.45
InitMethod · 0.45

Tested by

no test coverage detected