package ssdpimport ()const ( ssdpDiscover = `"ssdp:discover"` ntsAlive = `ssdp:alive` ntsByebye = `ssdp:byebye` ntsUpdate = `ssdp:update` ssdpUDP4Addr = "239.255.255.250:1900" ssdpSearchPort = 1900 methodSearch = "M-SEARCH" methodNotify = "NOTIFY"// SSDPAll is a value for searchTarget that searches for all devices and services.SSDPAll = "ssdp:all"// UPNPRootDevice is a value for searchTarget that searches for all root devices.UPNPRootDevice = "upnp:rootdevice")// HTTPUClient is the interface required to perform HTTP-over-UDP requests.typeHTTPUClientinterface {Do( req *http.Request, timeout time.Duration, numSends int, ) ([]*http.Response, error)}// HTTPUClientCtx is an optional interface that will be used to perform// HTTP-over-UDP requests if the client implements it.typeHTTPUClientCtxinterface {DoWithContext( req *http.Request, numSends int, ) ([]*http.Response, error)}// SSDPRawSearchCtx performs a fairly raw SSDP search request, and returns the// unique response(s) that it receives. Each response has the requested// searchTarget, a USN, and a valid location. maxWaitSeconds states how long to// wait for responses in seconds, and must be a minimum of 1 (the// implementation waits an additional 100ms for responses to arrive), 2 is a// reasonable value for this. numSends is the number of requests to send - 3 is// a reasonable value for this.func (context.Context,HTTPUClient,string,int,int,) ([]*http.Response, error) { , := prepareRequest(, , )if != nil {returnnil, } , := .Do(, time.Duration()*time.Second+100*time.Millisecond, )if != nil {returnnil, }returnprocessSSDPResponses(, )}// RawSearch performs a fairly raw SSDP search request, and returns the// unique response(s) that it receives. Each response has the requested// searchTarget, a USN, and a valid location. If the provided context times out// or is canceled, the search will be aborted. numSends is the number of// requests to send - 3 is a reasonable value for this.//// The provided context should have a deadline, since the SSDP protocol// requires the max wait time be included in search requests. If the context// has no deadline, then a default deadline of 3 seconds will be applied.func (context.Context,HTTPUClientCtx,string,int,) ([]*http.Response, error) {// We need a timeout value to include in the SSDP request; get it by // checking the deadline on the context.varintif , := .Deadline(); { = int(.Sub(time.Now()) / time.Second) } else {// Pick a default timeout of 3 seconds if none was provided. = 3varfunc() , = context.WithTimeout(, time.Duration()*time.Second)defer () } , := prepareRequest(, , )if != nil {returnnil, } , := .DoWithContext(, )if != nil {returnnil, }returnprocessSSDPResponses(, )}// prepareRequest checks the provided parameters and constructs a SSDP search// request to be sent.func prepareRequest( context.Context, string, int) (*http.Request, error) {if < 1 {returnnil, errors.New("ssdp: request timeout must be at least 1s") } := (&http.Request{Method: methodSearch,// TODO: Support both IPv4 and IPv6.Host: ssdpUDP4Addr,URL: &url.URL{Opaque: "*"},Header: http.Header{// Putting headers in here avoids them being title-cased. // (The UPnP discovery protocol uses case-sensitive headers)"HOST": []string{ssdpUDP4Addr},"MX": []string{strconv.FormatInt(int64(), 10)},"MAN": []string{ssdpDiscover},"ST": []string{}, }, }).WithContext()return , nil}func processSSDPResponses(string, []*http.Response,) ([]*http.Response, error) { := != SSDPAll && != UPNPRootDevice := make(map[string]bool)var []*http.Responsefor , := range {if .StatusCode != 200 {log.Printf("ssdp: got response status code %q in search response", .Status)continue }if := .Header.Get("ST"); && != {continue } := .Header.Get("USN") , := .Location()if != nil {// No usable location in search response - discard.continue } := .String() + "\x00" + if , := []; ! { [] = true = append(, ) } }return , nil}// SSDPRawSearch is the legacy version of SSDPRawSearchCtx, but uses// context.Background() as the context.func ( HTTPUClient, string, int, int) ([]*http.Response, error) {returnSSDPRawSearchCtx(context.Background(), , , , )}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.