I have a simple web application with the plugin below. It works fine with IPv4 or IPv6. The host has 2 addresses (IPv4 + IPv6 = dual stack). How can I extend the plugin to let my server listen on both addresses? Please advice, Axel PS: The plugin: from zope.interface import implementer from twisted.application.service import IServiceMaker from twisted.application import internet from twisted.plugin import IPlugin from twisted.python import usage from meteo import meteo_factory class Options(usage.Options): optParameters = [ ['port', 'p', 80, 'The port number to listen on.'], ['ipv4_address', '4', None, 'The IPv4 address to listen on.'], ['ipv6_address', '6', None, 'The IPv6 address to listen on.'], ['host', 'l', None, 'The hostname where to listen at']] @implementer(IServiceMaker, IPlugin) class MeteoServiceMaker(object): tapname = 'meteo' description = 'A web application for the meteo package' options = Options def makeService(self, options): """ Constructs a TCP server from a factory defined in meteo.py """ return internet.TCPServer( int(options['port']), meteo_factory, interface=options['ipv6_address']) serviceMaker = MeteoServiceMaker() --- PGP-Key:29E99DD6 ☀ computing @ chaos claudius
Hi Axel, makeService() returns an IService. twisted.internet.application.MultiService[1] is an IService that composes other services (it's an IServiceCollection). The implementation would be something like: def makeService(self, options): ipv4 = internet.TCPServer(int(options['port'], meteo_factory, interface=options['ipv4_address']) ipv6 = internet.TCPServer(int(options['port'], meteo_factory, interface=options['ipv6_address']) root = MultiService() ipv4.setServiceParent(root) ipv6.setServiceParent(root) return root You might prefer StreamServerEndpointService[2] to TCPServer. String endpoint descriptions[3] are pretty convenient for CLI use. [1]: https://twistedmatrix.com/documents/current/api/twisted.application.service.... [2]: https://twistedmatrix.com/documents/current/api/twisted.application.internet... [3]: https://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.h... -- Tom Most twm@freecog.net On Fri, Mar 29, 2019, at 11:39 AM, Axel Rau wrote:
I have a simple web application with the plugin below. It works fine with IPv4 or IPv6. The host has 2 addresses (IPv4 + IPv6 = dual stack). How can I extend the plugin to let my server listen on both addresses?
Please advice, Axel
PS: The plugin:
from zope.interface import implementer
from twisted.application.service import IServiceMaker from twisted.application import internet from twisted.plugin import IPlugin from twisted.python import usage
from meteo import meteo_factory
class Options(usage.Options): optParameters = [ ['port', 'p', 80, 'The port number to listen on.'], ['ipv4_address', '4', None, 'The IPv4 address to listen on.'], ['ipv6_address', '6', None, 'The IPv6 address to listen on.'], ['host', 'l', None, 'The hostname where to listen at']]
@implementer(IServiceMaker, IPlugin) class MeteoServiceMaker(object): tapname = 'meteo' description = 'A web application for the meteo package' options = Options
def makeService(self, options): """ Constructs a TCP server from a factory defined in meteo.py """ return internet.TCPServer( int(options['port']), meteo_factory, interface=options['ipv6_address'])
serviceMaker = MeteoServiceMaker()
--- PGP-Key:29E99DD6 ☀ computing @ chaos claudius
Hi Tom, thanks for the explanation. After adding some brackets, your example code works like a charm.
[1]: https://twistedmatrix.com/documents/current/api/twisted.application.service.... <https://twistedmatrix.com/documents/current/api/twisted.application.service.MultiService.html> [2]: https://twistedmatrix.com/documents/current/api/twisted.application.internet... <https://twistedmatrix.com/documents/current/api/twisted.application.internet.StreamServerEndpointService.html> [3]: https://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.h... <https://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.html#serverFromString>
Using your pointers, I tried the next step: TLS. This variant of the makeService method: ipv4_endpoint = endpoints.serverFromString( reactor, 'ssl:{}:privateKey={}:certKey={}:interface={}'.format( options['port'], endpoints.quoteStringArgument(options['cert_path']), endpoints.quoteStringArgument(options['key_path']), options['ipv4_address'])) ipv6_endpoint = endpoints.serverFromString( reactor, 'ssl:{}:privateKey={}:certKey={}:interface={}'.format( options['port'], endpoints.quoteStringArgument(options['cert_path']), endpoints.quoteStringArgument(options['key_path']), options['ipv6_address'])) ipv4 = internet.StreamServerEndpointService(ipv4_endpoint, meteo_factory) ipv6 = internet.StreamServerEndpointService(ipv6_endpoint, meteo_factory) root = MultiService() ipv4.setServiceParent(root) ipv6.setServiceParent(root) does not work. It fails with: _parseSSL() got multiple values for argument ‚interface' same with private privateKey and certKey. What did I wrong this time? Thanks, Axel --- PGP-Key:29E99DD6 ☀ computing @ chaos claudius
Hi Axel, I'm not entirely sure what's going wrong there (maybe quote the ipv6 address?), but you want to retain the various independent command-line options you should instantiate endpoints directly rather than constructing an endpoint string (the endpoint string is useful to expose *directly* as a CLI parameter). I.e., you can construct SSL4ServerEndpoint <https://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.SSL4ServerEndpoint.html> directly. Oddly SSL6ServerEndpoint doesn't exist, though, and I don't see a generic server wrapper like wrapClientTLS <https://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.html#wrapClientTLS> for the server site. I'm afraid I may have led you down the wrong path --- I didn't realize this was missing. ---Tom On Sun, Mar 31, 2019, at 8:34 AM, Axel Rau wrote:
Hi Tom,
thanks for the explanation. After adding some brackets, your example code works like a charm.
[1]: https://twistedmatrix.com/documents/current/api/twisted.application.service.... [2]: https://twistedmatrix.com/documents/current/api/twisted.application.internet... [3]: https://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.h...
Using your pointers, I tried the next step: TLS.
This variant of the makeService method:
ipv4_endpoint = endpoints.serverFromString( reactor, 'ssl:{}:privateKey={}:certKey={}:interface={}'.format( options['port'], endpoints.quoteStringArgument(options['cert_path']), endpoints.quoteStringArgument(options['key_path']), options['ipv4_address']))
ipv6_endpoint = endpoints.serverFromString( reactor, 'ssl:{}:privateKey={}:certKey={}:interface={}'.format( options['port'], endpoints.quoteStringArgument(options['cert_path']), endpoints.quoteStringArgument(options['key_path']), options['ipv6_address']))
ipv4 = internet.StreamServerEndpointService(ipv4_endpoint, meteo_factory) ipv6 = internet.StreamServerEndpointService(ipv6_endpoint, meteo_factory)
root = MultiService() ipv4.setServiceParent(root) ipv6.setServiceParent(root)
does not work. It fails with: _parseSSL() got multiple values for argument ‚interface' same with private privateKey and certKey.
What did I wrong this time?
Thanks, Axel --- PGP-Key:29E99DD6 ☀ computing @ chaos claudius
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
Hi Tom, quoting the IPv6 address resolved the issue! The error message is far away from being helpful. )-: Thanks for your patience, Axel
Am 02.04.2019 um 05:25 schrieb Tom Most <twm@freecog.net>:
Hi Axel,
I'm not entirely sure what's going wrong there (maybe quote the ipv6 address?), but you want to retain the various independent command-line options you should instantiate endpoints directly rather than constructing an endpoint string (the endpoint string is useful to expose directly as a CLI parameter).
I.e., you can construct SSL4ServerEndpoint <https://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.SSL4ServerEndpoint.html> directly. Oddly SSL6ServerEndpoint doesn't exist, though, and I don't see a generic server wrapper like wrapClientTLS <https://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.html#wrapClientTLS> for the server site. I'm afraid I may have led you down the wrong path --- I didn't realize this was missing.
---Tom
On Sun, Mar 31, 2019, at 8:34 AM, Axel Rau wrote:
Hi Tom,
thanks for the explanation. After adding some brackets, your example code works like a charm.
[1]: https://twistedmatrix.com/documents/current/api/twisted.application.service.... <https://twistedmatrix.com/documents/current/api/twisted.application.service.MultiService.html> [2]: https://twistedmatrix.com/documents/current/api/twisted.application.internet... <https://twistedmatrix.com/documents/current/api/twisted.application.internet.StreamServerEndpointService.html> [3]: https://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.h... <https://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.html#serverFromString>
Using your pointers, I tried the next step: TLS.
This variant of the makeService method:
ipv4_endpoint = endpoints.serverFromString( reactor, 'ssl:{}:privateKey={}:certKey={}:interface={}'.format( options['port'], endpoints.quoteStringArgument(options['cert_path']), endpoints.quoteStringArgument(options['key_path']), options['ipv4_address']))
ipv6_endpoint = endpoints.serverFromString( reactor, 'ssl:{}:privateKey={}:certKey={}:interface={}'.format( options['port'], endpoints.quoteStringArgument(options['cert_path']), endpoints.quoteStringArgument(options['key_path']), options['ipv6_address']))
ipv4 = internet.StreamServerEndpointService(ipv4_endpoint, meteo_factory) ipv6 = internet.StreamServerEndpointService(ipv6_endpoint, meteo_factory)
root = MultiService() ipv4.setServiceParent(root) ipv6.setServiceParent(root)
does not work. It fails with: _parseSSL() got multiple values for argument ‚interface' same with private privateKey and certKey.
What did I wrong this time?
Thanks, Axel --- PGP-Key:29E99DD6 ☀ computing @ chaos claudius
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com <mailto:Twisted-web@twistedmatrix.com> https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web <https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web>
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com <mailto:Twisted-web@twistedmatrix.com> https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web <https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web>
PGP-Key:29E99DD6 ☀ computing @ chaos claudius
participants (2)
-
Axel Rau
-
Tom Most