def soapenurl(request): from nonsuckhttp import urlopen d = urlopen(request) factory = lambda response: SOAPResponseFactory(request, response) errfactory = lambda response: SOAPErrorFactory(request, response.value) d.addCallbacks(factory, errfactory) return d
def handleSearchResponse(self, message): headers, body = self.parseSearchResponse(message) loc = headers.get('location') if not loc: log.msg("No location header in response to M-SEARCH!", system='UPnP') return loc = loc[0] d = urlopen(loc) log.msg("found a UPnP device at %s"%loc, system="UPnP") d.addCallback(self.handleIGDeviceResponse, loc).addErrback(log.err)
def handleSearchResponse(self, message): headers, body = self.parseSearchResponse(message) loc = headers.get('location') if not loc: log.msg("No location header in response to M-SEARCH!", system='UPnP') return loc = loc[0] d = urlopen(loc) log.msg("found a UPnP device at %s" % loc, system="UPnP") d.addCallback(self.handleIGDeviceResponse, loc).addErrback(log.err)
def stupidrandomdelaytoworkaroundbug(self, body, loc): """ On Mac (but not on Linux), Twisted seems to drop the ball on connecTCP(). The TCP connection gets set up (as confirmed by packet trace showing three-part handshake), but the factory object never gets buildProtocol(). Eventually (depending on the timeout value), the factory object gets its connectionFailed() method called instead. Mysteriously, this *always* happens on the urlopen in this method, and never on any of the other TCP connections that are made during Shtoom setup. Also mysteriously, inserting this stupidrandomdelay of 4 seconds fixes it. Surely I should write a minimal test case and then either give the test case to the Twisted folks or fix it myself, but some other things are way too urgent today. The sequence of events that I observed was: connect 1; connect 2; connect 3; callback 1; callback 2; connect 4; callback 3; ...timeout 4". where connect 1-3 are the "are you an IG device", and the connect 4 is this "get WAN service desc". So maybe in twisted the even of the 3rd tcp connection completing is screwing up the state of the 4th tcp connection, which has been initiated by hasn't completed yet. """ #log.msg("after stupidrandomrelaytoworkaroundbug, got an IGDevice from %s"%(loc,), system='UPnP') if self.controlURL is not None: log.msg("already found UPnP, discarding duplicate response", system="UPnP") # We already got a working one - ignore this one return data = body.read() bs = BeautifulSoap(data) manufacturer = bs.first('manufacturer') if manufacturer and manufacturer.contents: log.msg("you're behind a %s"%(manufacturer.contents[0]), system='UPnP') self.upnpInfo['manufacturer'] = manufacturer.contents[0] friendly = bs.first('friendlyName') if friendly: self.upnpInfo['friendlyName'] = str(friendly.contents[0]) urlbase = bs.first('URLBase') if urlbase and urlbase.contents: self.urlbase = str(urlbase.contents[0]) log.msg("upnp urlbase is %s"%(self.urlbase), system='UPnP') else: log.msg("upnp response has no urlbase, falling back to %s"%(loc,), system='UPnP') self.urlbase = loc wanservices = bs.fetch('service', dict(serviceType='urn:schemas-upnp-org:service:WANIPConnection:%')) for service in wanservices: scpdurl = service.get('SCPDURL') controlurl = service.get('controlURL') if scpdurl and controlurl: break else: log.msg("upnp response showed no WANIPConnections", system='UPnP') if DEBUG: print "dump of response", bs return self.controlURL = urlparse.urljoin(self.urlbase, controlurl) log.msg("upnp %r controlURL is %s"%(self, self.controlURL), system='UPnP') d = urlopen(urlparse.urljoin(self.urlbase, scpdurl)) d.addCallback(self.handleWanServiceDesc).addErrback(log.err)
def stupidrandomdelaytoworkaroundbug(self, body, loc): """ On Mac (but not on Linux), Twisted seems to drop the ball on connecTCP(). The TCP connection gets set up (as confirmed by packet trace showing three-part handshake), but the factory object never gets buildProtocol(). Eventually (depending on the timeout value), the factory object gets its connectionFailed() method called instead. Mysteriously, this *always* happens on the urlopen in this method, and never on any of the other TCP connections that are made during Shtoom setup. Also mysteriously, inserting this stupidrandomdelay of 4 seconds fixes it. Surely I should write a minimal test case and then either give the test case to the Twisted folks or fix it myself, but some other things are way too urgent today. The sequence of events that I observed was: connect 1; connect 2; connect 3; callback 1; callback 2; connect 4; callback 3; ...timeout 4". where connect 1-3 are the "are you an IG device", and the connect 4 is this "get WAN service desc". So maybe in twisted the even of the 3rd tcp connection completing is screwing up the state of the 4th tcp connection, which has been initiated by hasn't completed yet. """ #log.msg("after stupidrandomrelaytoworkaroundbug, got an IGDevice from %s"%(loc,), system='UPnP') if self.controlURL is not None: log.msg("already found UPnP, discarding duplicate response", system="UPnP") # We already got a working one - ignore this one return data = body.read() bs = BeautifulSoap(data) manufacturer = bs.first('manufacturer') if manufacturer and manufacturer.contents: log.msg("you're behind a %s" % (manufacturer.contents[0]), system='UPnP') self.upnpInfo['manufacturer'] = manufacturer.contents[0] friendly = bs.first('friendlyName') if friendly: self.upnpInfo['friendlyName'] = str(friendly.contents[0]) urlbase = bs.first('URLBase') if urlbase and urlbase.contents: self.urlbase = str(urlbase.contents[0]) log.msg("upnp urlbase is %s" % (self.urlbase), system='UPnP') else: log.msg("upnp response has no urlbase, falling back to %s" % (loc, ), system='UPnP') self.urlbase = loc wanservices = bs.fetch( 'service', dict(serviceType='urn:schemas-upnp-org:service:WANIPConnection:%')) for service in wanservices: scpdurl = service.get('SCPDURL') controlurl = service.get('controlURL') if scpdurl and controlurl: break else: log.msg("upnp response showed no WANIPConnections", system='UPnP') if DEBUG: print "dump of response", bs return self.controlURL = urlparse.urljoin(self.urlbase, controlurl) log.msg("upnp %r controlURL is %s" % (self, self.controlURL), system='UPnP') d = urlopen(urlparse.urljoin(self.urlbase, scpdurl)) d.addCallback(self.handleWanServiceDesc).addErrback(log.err)