├── 9781430230038.jpg ├── LICENSE.txt ├── README.md ├── contributing.md └── foundations-of-python-network-programming ├── README.txt ├── python2 ├── 10 │ ├── excerpt.html │ ├── fetch_mechanize.py │ ├── fetch_urllib2.py │ ├── phoenix-tidied.html │ ├── phoenix.html │ └── weather.py ├── 11 │ ├── bottle_app.py │ ├── bottle_template.html │ └── wsgi_app.py ├── 12 │ ├── message.txt │ ├── mime_decode.py │ ├── mime_gen_alt.py │ ├── mime_gen_basic.py │ ├── mime_gen_both.py │ ├── mime_headers.py │ ├── mime_parse_headers.py │ ├── mime_structure.py │ ├── test.txt │ ├── test.txt.gz │ ├── trad_gen_newhdrs.py │ ├── trad_gen_simple.py │ └── trad_parse.py ├── 13 │ ├── debug.py │ ├── ehlo.py │ ├── login.py │ ├── simple.py │ └── tls.py ├── 14 │ ├── download-and-delete.py │ ├── mailbox.py │ └── popconn.py ├── 15 │ ├── folder_info.py │ ├── mailbox_summary.py │ ├── open_imap.py │ ├── open_imap.txt │ ├── open_imaplib.py │ ├── open_imaplib.txt │ └── simple_client.py ├── 16 │ ├── fabfile.py │ ├── sftp.py │ ├── shell.py │ ├── ssh_commands.py │ ├── ssh_simple.py │ ├── ssh_simple.txt │ ├── ssh_threads.py │ ├── telnet_codes.py │ └── telnet_login.py ├── 17 │ ├── advbinarydl.py │ ├── advbinaryul.py │ ├── asciidl.py │ ├── binarydl.py │ ├── binaryul.py │ ├── connect.py │ ├── dir.py │ ├── nlst.py │ └── recursedl.py ├── 18 │ ├── jsonrpc_client.py │ ├── jsonrpc_server.py │ ├── rpyc_client.py │ ├── rpyc_server.py │ ├── testfile.txt │ ├── xmlrpc_client.py │ ├── xmlrpc_introspect.py │ ├── xmlrpc_multicall.py │ └── xmlrpc_server.py ├── 01 │ ├── getname.py │ ├── search1.py │ ├── search2.py │ ├── search3.py │ ├── search4.py │ └── search4.txt ├── 02 │ ├── big_sender.py │ ├── udp_broadcast.py │ ├── udp_local.py │ └── udp_remote.py ├── 03 │ ├── tcp_deadlock.py │ └── tcp_sixteen.py ├── 04 │ ├── dns_basic.py │ ├── dns_mx.py │ ├── forward_reverse.py │ └── www_ping.py ├── 05 │ ├── blocks.py │ └── streamer.py ├── 06 │ ├── certfiles.crt │ └── sslclient.py ├── 07 │ ├── Bench.sh │ ├── Test.sh │ ├── TestLancelot.conf │ ├── client.py │ ├── lancelot.py │ ├── lancelot_tests.py │ ├── my_trace.py │ ├── server_SocketServer.py │ ├── server_async.py │ ├── server_multi.py │ ├── server_poll.py │ ├── server_simple.py │ └── server_twisted.py ├── 08 │ ├── hashing.py │ ├── queuecrazy.py │ └── squares.py └── 09 │ ├── get_rfc2616.py │ └── verbose_http.py └── python3 ├── 10 ├── excerpt.html ├── fetch_mechanize.py ├── fetch_urllib2.py ├── phoenix-tidied.html ├── phoenix.html └── weather.py ├── 11 ├── bottle_app.py ├── bottle_template.html └── wsgi_app.py ├── 12 ├── message.txt ├── mime_decode.py ├── mime_gen_alt.py ├── mime_gen_basic.py ├── mime_gen_both.py ├── mime_headers.py ├── mime_parse_headers.py ├── mime_structure.py ├── test.txt ├── test.txt.gz ├── trad_gen_newhdrs.py ├── trad_gen_simple.py └── trad_parse.py ├── 13 ├── debug.py ├── ehlo.py ├── login.py ├── simple.py └── tls.py ├── 14 ├── download-and-delete.py ├── mailbox.py └── popconn.py ├── 15 ├── folder_info.py ├── mailbox_summary.py ├── open_imap.py ├── open_imap.txt ├── open_imaplib.py ├── open_imaplib.txt └── simple_client.py ├── 16 ├── fabfile.py ├── sftp.py ├── shell.py ├── ssh_commands.py ├── ssh_simple.py ├── ssh_simple.txt ├── ssh_threads.py ├── telnet_codes.py └── telnet_login.py ├── 17 ├── advbinarydl.py ├── advbinaryul.py ├── asciidl.py ├── binarydl.py ├── binaryul.py ├── connect.py ├── dir.py ├── nlst.py └── recursedl.py ├── 18 ├── jsonrpc_client.py ├── jsonrpc_server.py ├── rpyc_client.py ├── rpyc_server.py ├── testfile.txt ├── xmlrpc_client.py ├── xmlrpc_introspect.py ├── xmlrpc_multicall.py └── xmlrpc_server.py ├── 01 ├── getname.py ├── search1.py ├── search2.py ├── search3.py ├── search4.py └── search4.txt ├── 02 ├── big_sender.py ├── udp_broadcast.py ├── udp_local.py └── udp_remote.py ├── 03 ├── tcp_deadlock.py └── tcp_sixteen.py ├── 04 ├── dns_basic.py ├── dns_mx.py ├── forward_reverse.py └── www_ping.py ├── 05 ├── blocks.py └── streamer.py ├── 06 ├── certfiles.crt └── sslclient.py ├── 07 ├── Bench.sh ├── Test.sh ├── TestLancelot.conf ├── client.py ├── lancelot.py ├── lancelot_tests.py ├── my_trace.py ├── server_SocketServer.py ├── server_async.py ├── server_multi.py ├── server_poll.py ├── server_simple.py └── server_twisted.py ├── 08 ├── hashing.py ├── queuecrazy.py └── squares.py └── 09 ├── get_rfc2616.py └── verbose_http.py /9781430230038.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/foundations-of-python-network-programming/f9e2f1f9fd424da3880c94258134ab3e9fa54969/9781430230038.jpg -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/foundations-of-python-network-programming/f9e2f1f9fd424da3880c94258134ab3e9fa54969/LICENSE.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apress Source Code 2 | 3 | This repository accompanies [*Foundations of Python Network Programming*](http://www.apress.com/9781430230038) by John Goerzen, Tim Bower, and Brandon Rhodes (Apress, 2010). 4 | 5 | ![Cover image](9781430230038.jpg) 6 | 7 | Download the files as a zip using the green button, or clone the repository to your machine using Git. 8 | 9 | ## Releases 10 | 11 | Release v1.0 corresponds to the code in the published book, without corrections or updates. 12 | 13 | ## Contributions 14 | 15 | See the file Contributing.md for more information on how you can contribute to this repository. 16 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Apress Source Code 2 | 3 | Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. 4 | 5 | ## How to Contribute 6 | 7 | 1. Make sure you have a GitHub account. 8 | 2. Fork the repository for the relevant book. 9 | 3. Create a new branch on which to make your change, e.g. 10 | `git checkout -b my_code_contribution` 11 | 4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. 12 | 5. Submit a pull request. 13 | 14 | Thank you for your contribution! -------------------------------------------------------------------------------- /foundations-of-python-network-programming/README.txt: -------------------------------------------------------------------------------- 1 | This archive contains the example programs for the Apress book: 2 | 3 | Foundations of Python Network Programming 4 | The Comprehensive Guide to Building Network Applications with Python 5 | Second Edition 6 | 7 | The examples for each chapter are in individual directories for that 8 | chapter. Please refer to the comments in the book's introduction for 9 | information on running these examples, and platform-specific notes. 10 | 11 | If errors are found in the examples after the book goes to print, 12 | updated examples will be posted here. 13 | 14 | -- Brandon Rhodes 15 | January, 2011 16 | 17 | 18 | STATUS OF PYTHON 3 EXAMPLES 19 | As of January 2011 20 | 21 | 01/getname.py - OK 22 | 01/search1.py - waiting on port of "googlemaps" to Python 3 23 | 01/search2.py - OK 24 | 01/search3.py - OK 25 | 01/search4.py - OK 26 | 27 | 02/big_sender.py - OK 28 | 02/udp_broadcast.py - OK 29 | 02/udp_local.py - OK 30 | 02/udp_remote.py - OK 31 | 32 | 03/tcp_deadlock.py - OK 33 | 03/tcp_sixteen.py - OK 34 | 35 | 04/dns_basic.py - waiting on port of "pydns" to Python 3 36 | 04/dns_mx.py - waiting on port of "pydns" to Python 3 37 | 04/forward_reverse.py - OK 38 | 04/www_ping.py - OK 39 | 40 | 05/blocks.py - OK 41 | 05/streamer.py - OK 42 | 43 | 06/sslclient.py - OK 44 | 45 | 07/client.py - OK 46 | 07/lancelot.py - OK 47 | 07/lancelot_tests.py - waiting on port of "funkload" to Python 3 48 | 07/my_trace.py - OK 49 | 07/server_SocketServer.py - OK 50 | 07/server_async.py - OK 51 | 07/server_multi.py - OK 52 | 07/server_poll.py - OK 53 | 07/server_simple.py - OK 54 | 07/server_twisted.py - waiting on port of "Twisted" to Python 3 55 | 56 | 08/hashing.py - OK 57 | 08/queuecrazy.py - waiting on port of "pyzmq" to Python 3 58 | 08/squares.py - waiting on port of "python-memcached" to Python 3 59 | 60 | 09/get_rfc2616.py - OK 61 | 09/verbose_handler.py - OK 62 | 63 | 10/fetch_mechanize.py - waiting on port of "mechanize" to Python 3 64 | 10/fetch_urllib2.py - OK 65 | 10/weather.py - "lxml" part works great; "BeautifulSoup" is commented out 66 | 67 | 11/bottle_app.py - OK 68 | 11/wsgi_app.py - OK 69 | 70 | 12/mime_decode.py - OK 71 | 12/mime_gen_alt.py - OK 72 | 12/mime_gen_basic.py - OK 73 | 12/mime_gen_both.py - OK 74 | 12/mime_headers.py - OK 75 | 12/mime_parse_headers.py - OK (but why does the space character disappear?) 76 | 12/mime_structure.py - OK 77 | 12/trad_gen_newhdrs.py - OK 78 | 12/trad_gen_simple.py - OK 79 | 12/trad_parse.py - OK 80 | 81 | 13/debug.py - OK 82 | 13/ehlo.py - OK 83 | 13/login.py - OK 84 | 13/simple.py - OK 85 | 13/tls.py - OK 86 | 87 | 14/download-and-delete.py - OK 88 | 14/mailbox.py - OK 89 | 14/popconn.py - OK 90 | 91 | 15/folder_info.py - waiting on port of "imapclient" to Python 3 92 | 15/mailbox_summary.py - waiting on port of "imapclient" to Python 3 93 | 15/open_imap.py - waiting on port of "imapclient" to Python 3 94 | 15/open_imaplib.py - OK 95 | 15/simple_client.py - waiting on port of "imapclient" to Python 3 96 | 97 | 16/fabfile.py - waiting on port of "fabric" to Python 3 98 | 16/sftp.py - waiting on port of "paramiko" to Python 3 99 | 16/shell.py - OK 100 | 16/ssh_commands.py - waiting on port of "paramiko" to Python 3 101 | 16/ssh_simple.py - waiting on port of "paramiko" to Python 3 102 | 16/ssh_threads.py - waiting on port of "paramiko" to Python 3 103 | 16/telnet_codes.py - OK 104 | 16/telnet_login.py - OK 105 | 106 | 17/advbinarydl.py - OK 107 | 17/advbinaryul.py - OK 108 | 17/asciidl.py - OK 109 | 17/binarydl.py - OK 110 | 17/binaryul.py - OK 111 | 17/connect.py - OK 112 | 17/dir.py - OK 113 | 17/nlst.py - OK 114 | 17/recursedl.py - OK 115 | 116 | 18/jsonrpc_client.py - waiting on port of "lovely.jsonrpc" to Python 3 117 | 18/jsonrpc_server.py - waiting on port of "lovely.jsonrpc" to Python 3 118 | 18/rpyc_client.py - waiting on port of "rpyc" to Python 3 119 | 18/rpyc_server.py - waiting on port of "rpyc" to Python 3 120 | 18/xmlrpc_client.py - OK 121 | 18/xmlrpc_introspect.py - OK 122 | 18/xmlrpc_multicall.py - OK 123 | 18/xmlrpc_server.py - OK 124 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/01/getname.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 1 - getname.py 3 | 4 | import socket 5 | hostname = 'maps.google.com' 6 | addr = socket.gethostbyname(hostname) 7 | print 'The address of', hostname, 'is', addr 8 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/01/search1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 1 - search1.py 3 | 4 | from googlemaps import GoogleMaps 5 | address = '207 N. Defiance St, Archbold, OH' 6 | print GoogleMaps().address_to_latlng(address) 7 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/01/search2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 1 - search2.py 3 | 4 | import urllib, urllib2 5 | try: 6 | import json 7 | except ImportError: # for Python 2.5 8 | import simplejson as json 9 | 10 | params = {'q': '207 N. Defiance St, Archbold, OH', 11 | 'output': 'json', 'oe': 'utf8'} 12 | url = 'http://maps.google.com/maps/geo?' + urllib.urlencode(params) 13 | 14 | rawreply = urllib2.urlopen(url).read() 15 | 16 | reply = json.loads(rawreply) 17 | print reply['Placemark'][0]['Point']['coordinates'][:-1] 18 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/01/search3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 1 - search3.py 3 | 4 | import httplib 5 | try: 6 | import json 7 | except ImportError: # for Python 2.5 8 | import simplejson as json 9 | 10 | path = ('/maps/geo?q=207+N.+Defiance+St%2C+Archbold%2C+OH' 11 | '&output=json&oe=utf8') 12 | 13 | connection = httplib.HTTPConnection('maps.google.com') 14 | connection.request('GET', path) 15 | rawreply = connection.getresponse().read() 16 | 17 | reply = json.loads(rawreply) 18 | print reply['Placemark'][0]['Point']['coordinates'][:-1] 19 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/01/search4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 1 - search4.py 3 | 4 | import socket 5 | sock = socket.socket() 6 | sock.connect(('maps.google.com', 80)) 7 | sock.sendall( 8 | 'GET /maps/geo?q=207+N.+Defiance+St%2C+Archbold%2C+OH' 9 | '&output=json&oe=utf8&sensor=false HTTP/1.1\r\n' 10 | 'Host: maps.google.com:80\r\n' 11 | 'User-Agent: search4.py\r\n' 12 | 'Connection: close\r\n' 13 | '\r\n') 14 | rawreply = sock.recv(4096) 15 | print rawreply 16 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/01/search4.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: text/javascript; charset=UTF-8 3 | Vary: Accept-Language 4 | Date: Wed, 21 Jul 2010 16:10:38 GMT 5 | Server: mafe 6 | Cache-Control: private, x-gzip-ok="" 7 | X-XSS-Protection: 1; mode=block 8 | Connection: close 9 | 10 | { 11 | "name": "207 N. Defiance St, Archbold, OH", 12 | "Status": { 13 | "code": 200, 14 | "request": "geocode" 15 | }, 16 | "Placemark": [ { 17 | ... 18 | "Point": { 19 | "coordinates": [ -84.3063479, 41.5228242, 0 ] 20 | } 21 | } ] 22 | } 23 | 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/02/big_sender.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 2 - big_sender.py 3 | # Send a big UDP packet to our server. 4 | 5 | import IN, socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 7 | 8 | MAX = 65535 9 | PORT = 1060 10 | 11 | if len(sys.argv) != 2: 12 | print >>sys.stderr, 'usage: big_sender.py host' 13 | sys.exit(2) 14 | 15 | hostname = sys.argv[1] 16 | s.connect((hostname, PORT)) 17 | s.setsockopt(socket.IPPROTO_IP, IN.IP_MTU_DISCOVER, IN.IP_PMTUDISC_DO) 18 | try: 19 | s.send('#' * 65000) 20 | except socket.error: 21 | print 'The message did not make it' 22 | option = getattr(IN, 'IP_MTU', 14) # constant taken from 23 | print 'MTU:', s.getsockopt(socket.IPPROTO_IP, option) 24 | else: 25 | print 'The big message was sent! Your network supports really big packets!' 26 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/02/udp_broadcast.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 2 - udp_broadcast.py 3 | # UDP client and server for broadcast messages on a local LAN 4 | 5 | import socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 7 | s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 8 | 9 | MAX = 65535 10 | PORT = 1060 11 | 12 | if 2 <= len(sys.argv) <= 3 and sys.argv[1] == 'server': 13 | s.bind(('', PORT)) 14 | print 'Listening for broadcasts at', s.getsockname() 15 | while True: 16 | data, address = s.recvfrom(MAX) 17 | print 'The client at %r says: %r' % (address, data) 18 | 19 | elif len(sys.argv) == 3 and sys.argv[1] == 'client': 20 | network = sys.argv[2] 21 | s.sendto('Broadcast message!', (network, PORT)) 22 | 23 | else: 24 | print >>sys.stderr, 'usage: udp_broadcast.py server' 25 | print >>sys.stderr, ' or: udp_broadcast.py client ' 26 | sys.exit(2) 27 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/02/udp_local.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 2 - udp_local.py 3 | # UDP client and server on localhost 4 | 5 | import socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 7 | 8 | MAX = 65535 9 | PORT = 1060 10 | 11 | if sys.argv[1:] == ['server']: 12 | s.bind(('127.0.0.1', PORT)) 13 | print 'Listening at', s.getsockname() 14 | while True: 15 | data, address = s.recvfrom(MAX) 16 | print 'The client at', address, 'says', repr(data) 17 | s.sendto('Your data was %d bytes' % len(data), address) 18 | 19 | elif sys.argv[1:] == ['client']: 20 | print 'Address before sending:', s.getsockname() 21 | s.sendto('This is my message', ('127.0.0.1', PORT)) 22 | print 'Address after sending', s.getsockname() 23 | data, address = s.recvfrom(MAX) # overly promiscuous - see Chapter 2 24 | print 'The server', address, 'says', repr(data) 25 | 26 | else: 27 | print >>sys.stderr, 'usage: udp_local.py server|client' 28 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/02/udp_remote.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 2 - udp_remote.py 3 | # UDP client and server for talking over the network 4 | 5 | import random, socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 7 | 8 | MAX = 65535 9 | PORT = 1060 10 | 11 | if 2 <= len(sys.argv) <= 3 and sys.argv[1] == 'server': 12 | interface = sys.argv[2] if len(sys.argv) > 2 else '' 13 | s.bind((interface, PORT)) 14 | print 'Listening at', s.getsockname() 15 | while True: 16 | data, address = s.recvfrom(MAX) 17 | if random.randint(0, 1): 18 | print 'The client at', address, 'says:', repr(data) 19 | s.sendto('Your data was %d bytes' % len(data), address) 20 | else: 21 | print 'Pretending to drop packet from', address 22 | 23 | elif len(sys.argv) == 3 and sys.argv[1] == 'client': 24 | hostname = sys.argv[2] 25 | s.connect((hostname, PORT)) 26 | print 'Client socket name is', s.getsockname() 27 | delay = 0.1 28 | while True: 29 | s.send('This is another message') 30 | print 'Waiting up to', delay, 'seconds for a reply' 31 | s.settimeout(delay) 32 | try: 33 | data = s.recv(MAX) 34 | except socket.timeout: 35 | delay *= 2 # wait even longer for the next request 36 | if delay > 2.0: 37 | raise RuntimeError('I think the server is down') 38 | else: 39 | break # we are done, and can stop looping 40 | 41 | print 'The server says', repr(data) 42 | 43 | else: 44 | print >>sys.stderr, 'usage: udp_remote.py server [ ]' 45 | print >>sys.stderr, ' or: udp_remote.py client ' 46 | sys.exit(2) 47 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/03/tcp_deadlock.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 3 - tcp_deadlock.py 3 | # TCP client and server that leave too much data waiting 4 | 5 | import socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | 8 | HOST = '127.0.0.1' 9 | PORT = 1060 10 | 11 | if sys.argv[1:] == ['server']: 12 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 13 | s.bind((HOST, PORT)) 14 | s.listen(1) 15 | while True: 16 | print 'Listening at', s.getsockname() 17 | sc, sockname = s.accept() 18 | print 'Processing up to 1024 bytes at a time from', sockname 19 | n = 0 20 | while True: 21 | message = sc.recv(1024) 22 | if not message: 23 | break 24 | sc.sendall(message.upper()) # send it back uppercase 25 | n += len(message) 26 | print '\r%d bytes processed so far' % (n,), 27 | sys.stdout.flush() 28 | print 29 | sc.close() 30 | print 'Completed processing' 31 | 32 | elif len(sys.argv) == 3 and sys.argv[1] == 'client' and sys.argv[2].isdigit(): 33 | 34 | bytes = (int(sys.argv[2]) + 15) // 16 * 16 # round up to // 16 35 | message = 'capitalize this!' # 16-byte message to repeat over and over 36 | 37 | print 'Sending', bytes, 'bytes of data, in chunks of 16 bytes' 38 | s.connect((HOST, PORT)) 39 | 40 | sent = 0 41 | while sent < bytes: 42 | s.sendall(message) 43 | sent += len(message) 44 | print '\r%d bytes sent' % (sent,), 45 | sys.stdout.flush() 46 | 47 | print 48 | s.shutdown(socket.SHUT_WR) 49 | 50 | print 'Receiving all the data the server sends back' 51 | 52 | received = 0 53 | while True: 54 | data = s.recv(42) 55 | if not received: 56 | print 'The first data received says', repr(data) 57 | received += len(data) 58 | if not data: 59 | break 60 | print '\r%d bytes received' % (received,), 61 | 62 | s.close() 63 | 64 | else: 65 | print >>sys.stderr, 'usage: tcp_deadlock.py server | client ' 66 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/03/tcp_sixteen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 3 - tcp_sixteen.py 3 | # Simple TCP client and server that send and receive 16 octets 4 | 5 | import socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | 8 | HOST = sys.argv.pop() if len(sys.argv) == 3 else '127.0.0.1' 9 | PORT = 1060 10 | 11 | def recvall(sock, length): 12 | data = '' 13 | while len(data) < length: 14 | more = sock.recv(length - len(data)) 15 | if not more: 16 | raise EOFError('socket closed %d bytes into a %d-byte message' 17 | % (len(data), length)) 18 | data += more 19 | return data 20 | 21 | if sys.argv[1:] == ['server']: 22 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 23 | s.bind((HOST, PORT)) 24 | s.listen(1) 25 | while True: 26 | print 'Listening at', s.getsockname() 27 | sc, sockname = s.accept() 28 | print 'We have accepted a connection from', sockname 29 | print 'Socket connects', sc.getsockname(), 'and', sc.getpeername() 30 | message = recvall(sc, 16) 31 | print 'The incoming sixteen-octet message says', repr(message) 32 | sc.sendall('Farewell, client') 33 | sc.close() 34 | print 'Reply sent, socket closed' 35 | 36 | elif sys.argv[1:] == ['client']: 37 | s.connect((HOST, PORT)) 38 | print 'Client has been assigned socket name', s.getsockname() 39 | s.sendall('Hi there, server') 40 | reply = recvall(s, 16) 41 | print 'The server said', repr(reply) 42 | s.close() 43 | 44 | else: 45 | print >>sys.stderr, 'usage: tcp_local.py server|client [host]' 46 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/04/dns_basic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 4 - dns_basic.py 3 | # Basic DNS query 4 | 5 | import sys, DNS 6 | 7 | if len(sys.argv) != 2: 8 | print >>sys.stderr, 'usage: dns_basic.py ' 9 | sys.exit(2) 10 | 11 | DNS.DiscoverNameServers() 12 | request = DNS.Request() 13 | for qt in DNS.Type.A, DNS.Type.AAAA, DNS.Type.CNAME, DNS.Type.MX, DNS.Type.NS: 14 | reply = request.req(name=sys.argv[1], qtype=qt) 15 | for answer in reply.answers: 16 | print answer['name'], answer['classstr'], answer['typename'], \ 17 | repr(answer['data']) 18 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/04/dns_mx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 4 - dns_mx.py 3 | # Looking up a mail domain - the part of an email address after the `@` 4 | 5 | import sys, DNS 6 | 7 | if len(sys.argv) != 2: 8 | print >>sys.stderr, 'usage: dns_basic.py ' 9 | sys.exit(2) 10 | 11 | def resolve_hostname(hostname, indent=0): 12 | """Print an A or AAAA record for `hostname`; follow CNAMEs if necessary.""" 13 | indent = indent + 4 14 | istr = ' ' * indent 15 | request = DNS.Request() 16 | reply = request.req(name=sys.argv[1], qtype=DNS.Type.A) 17 | if reply.answers: 18 | for answer in reply.answers: 19 | print istr, 'Hostname', hostname, '= A', answer['data'] 20 | return 21 | reply = request.req(name=sys.argv[1], qtype=DNS.Type.AAAA) 22 | if reply.answers: 23 | for answer in reply.answers: 24 | print istr, 'Hostname', hostname, '= AAAA', answer['data'] 25 | return 26 | reply = request.req(name=sys.argv[1], qtype=DNS.Type.CNAME) 27 | if reply.answers: 28 | cname = reply.answers[0]['data'] 29 | print istr, 'Hostname', hostname, 'is an alias for', cname 30 | resolve_hostname(cname, indent) 31 | return 32 | print istr, 'ERROR: no records for', hostname 33 | 34 | def resolve_email_domain(domain): 35 | """Print mail server IP addresses for an email address @ `domain`.""" 36 | request = DNS.Request() 37 | reply = request.req(name=sys.argv[1], qtype=DNS.Type.MX) 38 | if reply.answers: 39 | print 'The domain %r has explicit MX records!' % (domain,) 40 | print 'Try the servers in this order:' 41 | datalist = [ answer['data'] for answer in reply.answers ] 42 | datalist.sort() # lower-priority integers go first 43 | for data in datalist: 44 | priority = data[0] 45 | hostname = data[1] 46 | print 'Priority:', priority, ' Hostname:', hostname 47 | resolve_hostname(hostname) 48 | else: 49 | print 'Drat, this domain has no explicit MX records' 50 | print 'We will have to try resolving it as an A, AAAA, or CNAME' 51 | resolve_hostname(domain) 52 | 53 | DNS.DiscoverNameServers() 54 | resolve_email_domain(sys.argv[1]) 55 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/04/forward_reverse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 4 - forward_reverse.py 3 | # Checking whether a host name works both forwards and backwards. 4 | 5 | import socket, sys 6 | 7 | if len(sys.argv) != 2: 8 | print >>sys.stderr, 'usage: forward_reverse.py ' 9 | sys.exit(2) 10 | 11 | hostname = sys.argv[1] 12 | 13 | try: 14 | infolist = socket.getaddrinfo( 15 | hostname, 0, 0, socket.SOCK_STREAM, 0, 16 | socket.AI_ADDRCONFIG | socket.AI_V4MAPPED | socket.AI_CANONNAME, 17 | ) 18 | except socket.gaierror, e: 19 | print 'Forward name service failure:', e.args[1] 20 | sys.exit(1) 21 | 22 | info = infolist[0] # choose the first, if there are several addresses 23 | canonical = info[3] 24 | socketname = info[4] 25 | ip = socketname[0] 26 | 27 | if not canonical: 28 | print 'WARNING! The IP address', ip, 'has no reverse name' 29 | sys.exit(1) 30 | 31 | print hostname, 'has IP address', ip 32 | print ip, 'has the canonical hostname', canonical 33 | 34 | # Lowercase for case-insensitive comparison, and chop off hostnames. 35 | 36 | forward = hostname.lower().split('.') 37 | reverse = canonical.lower().split('.') 38 | 39 | if forward == reverse: 40 | print 'Wow, the names agree completely!' 41 | sys.exit(0) 42 | 43 | # Truncate the domain names, which now look like ['www', mit', 'edu'], 44 | # to the same length and compare. Failing that, be willing to try a 45 | # compare with the first element (the hostname?) lopped off if both of 46 | # they are the same length. 47 | 48 | length = min(len(forward), len(reverse)) 49 | if (forward[-length:] == reverse[-length:] 50 | or (len(forward) == len(reverse) 51 | and forward[-length+1:] == reverse[-length+1:] 52 | and len(forward[-2]) > 2)): # avoid thinking '.co.uk' means a match! 53 | print 'The forward and reverse names have a lot in common' 54 | else: 55 | print 'WARNING! The reverse name belongs to a different organization' 56 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/04/www_ping.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 4 - www_ping.py 3 | # Find the WWW service of an arbitrary host using getaddrinfo(). 4 | 5 | import socket, sys 6 | 7 | if len(sys.argv) != 2: 8 | print >>sys.stderr, 'usage: www_ping.py ' 9 | sys.exit(2) 10 | 11 | hostname_or_ip = sys.argv[1] 12 | 13 | try: 14 | infolist = socket.getaddrinfo( 15 | hostname_or_ip, 'www', 0, socket.SOCK_STREAM, 0, 16 | socket.AI_ADDRCONFIG | socket.AI_V4MAPPED | socket.AI_CANONNAME, 17 | ) 18 | except socket.gaierror, e: 19 | print 'Name service failure:', e.args[1] 20 | sys.exit(1) 21 | 22 | info = infolist[0] # per standard recommendation, try the first one 23 | socket_args = info[0:3] 24 | address = info[4] 25 | s = socket.socket(*socket_args) 26 | try: 27 | s.connect(address) 28 | except socket.error, e: 29 | print 'Network failure:', e.args[1] 30 | else: 31 | print 'Success: host', info[3], 'is listening on port 80' 32 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/05/blocks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 5 - blocks.py 3 | # Sending data one block at a time. 4 | 5 | import socket, struct, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | 8 | HOST = sys.argv.pop() if len(sys.argv) == 3 else '127.0.0.1' 9 | PORT = 1060 10 | format = struct.Struct('!I') # for messages up to 2**32 - 1 in length 11 | 12 | def recvall(sock, length): 13 | data = '' 14 | while len(data) < length: 15 | more = sock.recv(length - len(data)) 16 | if not more: 17 | raise EOFError('socket closed %d bytes into a %d-byte message' 18 | % (len(data), length)) 19 | data += more 20 | return data 21 | 22 | def get(sock): 23 | lendata = recvall(sock, format.size) 24 | (length,) = format.unpack(lendata) 25 | return recvall(sock, length) 26 | 27 | def put(sock, message): 28 | sock.send(format.pack(len(message)) + message) 29 | 30 | if sys.argv[1:] == ['server']: 31 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 32 | s.bind((HOST, PORT)) 33 | s.listen(1) 34 | print 'Listening at', s.getsockname() 35 | sc, sockname = s.accept() 36 | print 'Accepted connection from', sockname 37 | sc.shutdown(socket.SHUT_WR) 38 | while True: 39 | message = get(sc) 40 | if not message: 41 | break 42 | print 'Message says:', repr(message) 43 | sc.close() 44 | s.close() 45 | 46 | elif sys.argv[1:] == ['client']: 47 | s.connect((HOST, PORT)) 48 | s.shutdown(socket.SHUT_RD) 49 | put(s, 'Beautiful is better than ugly.') 50 | put(s, 'Explicit is better than implicit.') 51 | put(s, 'Simple is better than complex.') 52 | put(s, '') 53 | s.close() 54 | 55 | else: 56 | print >>sys.stderr, 'usage: streamer.py server|client [host]' 57 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/05/streamer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 5 - streamer.py 3 | # Client that sends data then closes the socket, not expecting a reply. 4 | 5 | import socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | 8 | HOST = sys.argv.pop() if len(sys.argv) == 3 else '127.0.0.1' 9 | PORT = 1060 10 | 11 | if sys.argv[1:] == ['server']: 12 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 13 | s.bind((HOST, PORT)) 14 | s.listen(1) 15 | print 'Listening at', s.getsockname() 16 | sc, sockname = s.accept() 17 | print 'Accepted connection from', sockname 18 | sc.shutdown(socket.SHUT_WR) 19 | message = '' 20 | while True: 21 | more = sc.recv(8192) # arbitrary value of 8k 22 | if not more: # socket has closed when recv() returns '' 23 | break 24 | message += more 25 | print 'Done receiving the message; it says:' 26 | print message 27 | sc.close() 28 | s.close() 29 | 30 | elif sys.argv[1:] == ['client']: 31 | s.connect((HOST, PORT)) 32 | s.shutdown(socket.SHUT_RD) 33 | s.sendall('Beautiful is better than ugly.\n') 34 | s.sendall('Explicit is better than implicit.\n') 35 | s.sendall('Simple is better than complex.\n') 36 | s.close() 37 | 38 | else: 39 | print >>sys.stderr, 'usage: streamer.py server|client [host]' 40 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/06/sslclient.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 6 - sslclient.py 3 | # Using SSL to protect a socket in Python 2.6 or later 4 | 5 | import os, socket, ssl, sys 6 | from backports.ssl_match_hostname import match_hostname, CertificateError 7 | 8 | try: 9 | script_name, hostname = sys.argv 10 | except ValueError: 11 | print >>sys.stderr, 'usage: sslclient.py ' 12 | sys.exit(2) 13 | 14 | # First we connect, as usual, with a socket. 15 | 16 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 17 | sock.connect((hostname, 443)) 18 | 19 | # Next, we turn the socket over to the SSL library! 20 | 21 | ca_certs_path = os.path.join(os.path.dirname(script_name), 'certfiles.crt') 22 | sslsock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_SSLv3, 23 | cert_reqs=ssl.CERT_REQUIRED, ca_certs=ca_certs_path) 24 | 25 | # Does the certificate that the server proffered *really* match the 26 | # hostname to which we are trying to connect? We need to check. 27 | 28 | try: 29 | match_hostname(sslsock.getpeercert(), hostname) 30 | except CertificateError, ce: 31 | print 'Certificate error:', str(ce) 32 | sys.exit(1) 33 | 34 | # From here on, our `sslsock` works like a normal socket. We can, for 35 | # example, make an impromptu HTTP call. 36 | 37 | sslsock.sendall('GET / HTTP/1.0\r\n\r\n') 38 | result = sslsock.makefile().read() # quick way to read until EOF 39 | sslsock.close() 40 | print 'The document https://%s/ is %d bytes long' % (hostname, len(result)) 41 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/Bench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for SERVER in server_*.py 4 | do 5 | echo '===========' $SERVER '===========' 6 | python $SERVER '' & 7 | ssh kenaniah <<'EOF' 8 | cd ~/apress 9 | source v/bin/activate 10 | cd fopnp/source/07 11 | LAUNCELOT_SERVER=192.168.5.130 fl-run-bench launcelot_tests.py TestLauncelot.test_dialog > OUT 2>&1 12 | EOF 13 | kill %1 14 | wait %1 2>/dev/null 15 | kill $(lsof | grep 'TCP.*1060' | awk '{print$2}') 16 | scp kenaniah:apress/fopnp/source/07/bench.xml ~/apress/bench 17 | (cd ~/apress/bench; fl-build-report --html bench.xml; rm -rf $SERVER; mv test_* $SERVER) 18 | done 19 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/Test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for SERVER in server_*.py 4 | do 5 | echo '===========' $SERVER '===========' 6 | python $SERVER localhost & 7 | sleep 1 8 | python client.py localhost 1060 9 | kill %1 10 | wait %1 2>/dev/null || true 11 | kill $(lsof | grep 'TCP.*1060' | awk '{print$2}') 12 | done 13 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/TestLancelot.conf: -------------------------------------------------------------------------------- 1 | # TestLauncelot.conf 2 | [main] 3 | title=Load Test For Chapter 7 4 | description=From the Foundations of Python Network Programming 5 | url=http://localhost:1060/ 6 | 7 | [ftest] 8 | log_path = ftest.log 9 | result_path = ftest.xml 10 | sleep_time_min = 0 11 | sleep_time_max = 0 12 | 13 | [bench] 14 | log_to = file 15 | log_path = bench.log 16 | result_path = bench.xml 17 | cycles = 1:2:3:5:7:10:13:16:20 18 | duration = 8 19 | startup_delay = 0.1 20 | sleep_time = 0.01 21 | cycle_time = 10 22 | sleep_time_min = 0 23 | sleep_time_max = 0 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - client.py 3 | # Simple Lancelot client that asks three questions then disconnects. 4 | 5 | import socket, sys, lancelot 6 | 7 | def client(hostname, port): 8 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 9 | s.connect((hostname, port)) 10 | s.sendall(lancelot.qa[0][0]) 11 | answer1 = lancelot.recv_until(s, '.') # answers end with '.' 12 | s.sendall(lancelot.qa[1][0]) 13 | answer2 = lancelot.recv_until(s, '.') 14 | s.sendall(lancelot.qa[2][0]) 15 | answer3 = lancelot.recv_until(s, '.') 16 | s.close() 17 | print answer1 18 | print answer2 19 | print answer3 20 | 21 | if __name__ == '__main__': 22 | if not 2 <= len(sys.argv) <= 3: 23 | print >>sys.stderr, 'usage: client.py hostname [port]' 24 | sys.exit(2) 25 | port = int(sys.argv[2]) if len(sys.argv) > 2 else lancelot.PORT 26 | client(sys.argv[1], port) 27 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/lancelot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - lancelot.py 3 | # Constants and routines for supporting a certain network conversation. 4 | 5 | import socket, sys 6 | 7 | PORT = 1060 8 | qa = (('What is your name?', 'My name is Sir Lancelot of Camelot.'), 9 | ('What is your quest?', 'To seek the Holy Grail.'), 10 | ('What is your favorite color?', 'Blue.')) 11 | qadict = dict(qa) 12 | 13 | def recv_until(sock, suffix): 14 | message = '' 15 | while not message.endswith(suffix): 16 | data = sock.recv(4096) 17 | if not data: 18 | raise EOFError('socket closed before we saw %r' % suffix) 19 | message += data 20 | return message 21 | 22 | def setup(): 23 | if len(sys.argv) != 2: 24 | print >>sys.stderr, 'usage: %s interface' % sys.argv[0] 25 | exit(2) 26 | interface = sys.argv[1] 27 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 28 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 29 | sock.bind((interface, PORT)) 30 | sock.listen(128) 31 | print 'Ready and listening at %r port %d' % (interface, PORT) 32 | return sock 33 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/lancelot_tests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - lancelot_tests.py 3 | # Test suite that can be run against the Lancelot servers. 4 | 5 | from funkload.FunkLoadTestCase import FunkLoadTestCase 6 | import socket, os, unittest, lancelot 7 | 8 | SERVER_HOST = os.environ.get('LAUNCELOT_SERVER', 'localhost') 9 | 10 | class TestLancelot(FunkLoadTestCase): 11 | def test_dialog(self): 12 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 13 | sock.connect((SERVER_HOST, lancelot.PORT)) 14 | for i in range(10): 15 | question, answer = lancelot.qa[i % len(launcelot.qa)] 16 | sock.sendall(question) 17 | reply = lancelot.recv_until(sock, '.') 18 | self.assertEqual(reply, answer) 19 | sock.close() 20 | 21 | if __name__ == '__main__': 22 | unittest.main() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/my_trace.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - my_trace.py 3 | # Command-line tool for tracing a single function in a program. 4 | 5 | import linecache, sys, time 6 | 7 | def make_tracer(funcname): 8 | def mytrace(frame, event, arg): 9 | if frame.f_code.co_name == funcname: 10 | if event == 'line': 11 | _events.append((time.time(), frame.f_code.co_filename, 12 | frame.f_lineno)) 13 | return mytrace 14 | return mytrace 15 | 16 | if __name__ == '__main__': 17 | _events = [] 18 | if len(sys.argv) < 3: 19 | print >>sys.stderr, 'usage: my_trace.py funcname other_script.py ...' 20 | sys.exit(2) 21 | sys.settrace(make_tracer(sys.argv[1])) 22 | del sys.argv[0:2] # show the script only its own name and arguments 23 | try: 24 | execfile(sys.argv[0]) 25 | finally: 26 | for t, filename, lineno in _events: 27 | s = linecache.getline(filename, lineno) 28 | sys.stdout.write('%9.6f %s' % (t % 60.0, s)) 29 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/server_SocketServer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_SocketServer.py 3 | # Answering Lancelot requests with a SocketServer. 4 | 5 | from SocketServer import ThreadingMixIn, TCPServer, BaseRequestHandler 6 | import lancelot, server_simple, socket 7 | 8 | class MyHandler(BaseRequestHandler): 9 | def handle(self): 10 | server_simple.handle_client(self.request) 11 | 12 | class MyServer(ThreadingMixIn, TCPServer): 13 | allow_reuse_address = 1 14 | # address_family = socket.AF_INET6 # if you need IPv6 15 | 16 | server = MyServer(('', lancelot.PORT), MyHandler) 17 | server.serve_forever() 18 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/server_async.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_async.py 3 | # Using the ancient "asyncore" framework to write a server. 4 | 5 | import asyncore, asynchat, lancelot 6 | 7 | class LancelotRequestHandler(asynchat.async_chat): 8 | 9 | def __init__(self, sock): 10 | asynchat.async_chat.__init__(self, sock) 11 | self.set_terminator('?') 12 | self.data = '' 13 | 14 | def collect_incoming_data(self, more_data): 15 | self.data += more_data 16 | 17 | def found_terminator(self): 18 | answer = dict(lancelot.qa)[self.data + '?'] 19 | self.push(answer) 20 | self.initiate_send() 21 | self.data = '' 22 | 23 | class LancelotServer(asyncore.dispatcher): 24 | def handle_accept(self): 25 | sock, address = self.accept() 26 | LancelotRequestHandler(sock) 27 | 28 | sock = lancelot.setup() 29 | ls = LancelotServer(sock) 30 | ls.accepting = True # since we already called listen() 31 | asyncore.loop() 32 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/server_multi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_multi.py 3 | # Using multiple threads or processes to serve several clients in parallel. 4 | 5 | import sys, time, lancelot 6 | from multiprocessing import Process 7 | from server_simple import server_loop 8 | from threading import Thread 9 | 10 | WORKER_CLASSES = {'thread': Thread, 'process': Process} 11 | WORKER_MAX = 10 12 | 13 | def start_worker(Worker, listen_sock): 14 | worker = Worker(target=server_loop, args=(listen_sock,)) 15 | worker.daemon = True # exit when the main process does 16 | worker.start() 17 | return worker 18 | 19 | if __name__ == '__main__': 20 | if len(sys.argv) != 3 or sys.argv[2] not in WORKER_CLASSES: 21 | print >>sys.stderr, 'usage: server_multi.py interface thread|process' 22 | sys.exit(2) 23 | Worker = WORKER_CLASSES[sys.argv.pop()] # setup() wants len(argv)==2 24 | 25 | # Every worker will accept() forever on the same listening socket. 26 | 27 | listen_sock = lancelot.setup() 28 | workers = [] 29 | for i in range(WORKER_MAX): 30 | workers.append(start_worker(Worker, listen_sock)) 31 | 32 | # Check every two seconds for dead workers, and replace them. 33 | 34 | while True: 35 | time.sleep(2) 36 | for worker in workers: 37 | if not worker.is_alive(): 38 | print worker.name, "died; starting replacement worker" 39 | workers.remove(worker) 40 | workers.append(start_worker(Worker, listen_sock)) 41 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/server_poll.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_poll.py 3 | # An event-driven approach to serving several clients with poll(). 4 | 5 | import lancelot 6 | import select 7 | 8 | listen_sock = lancelot.setup() 9 | sockets = { listen_sock.fileno(): listen_sock } 10 | requests = {} 11 | responses = {} 12 | 13 | poll = select.poll() 14 | poll.register(listen_sock, select.POLLIN) 15 | 16 | while True: 17 | for fd, event in poll.poll(): 18 | sock = sockets[fd] 19 | 20 | # Removed closed sockets from our list. 21 | if event & (select.POLLHUP | select.POLLERR | select.POLLNVAL): 22 | poll.unregister(fd) 23 | del sockets[fd] 24 | requests.pop(sock, None) 25 | responses.pop(sock, None) 26 | 27 | # Accept connections from new sockets. 28 | elif sock is listen_sock: 29 | newsock, sockname = sock.accept() 30 | newsock.setblocking(False) 31 | fd = newsock.fileno() 32 | sockets[fd] = newsock 33 | poll.register(fd, select.POLLIN) 34 | requests[newsock] = '' 35 | 36 | # Collect incoming data until it forms a question. 37 | elif event & select.POLLIN: 38 | data = sock.recv(4096) 39 | if not data: # end-of-file 40 | sock.close() # makes POLLNVAL happen next time 41 | continue 42 | requests[sock] += data 43 | if '?' in requests[sock]: 44 | question = requests.pop(sock) 45 | answer = dict(lancelot.qa)[question] 46 | poll.modify(sock, select.POLLOUT) 47 | responses[sock] = answer 48 | 49 | # Send out pieces of each reply until they are all sent. 50 | elif event & select.POLLOUT: 51 | response = responses.pop(sock) 52 | n = sock.send(response) 53 | if n < len(response): 54 | responses[sock] = response[n:] 55 | else: 56 | poll.modify(sock, select.POLLIN) 57 | requests[sock] = '' 58 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/server_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_simple.py 3 | # Simple server that only serves one client at a time; others have to wait. 4 | 5 | import lancelot 6 | 7 | def handle_client(client_sock): 8 | try: 9 | while True: 10 | question = lancelot.recv_until(client_sock, '?') 11 | answer = lancelot.qadict[question] 12 | client_sock.sendall(answer) 13 | except EOFError: 14 | client_sock.close() 15 | 16 | def server_loop(listen_sock): 17 | while True: 18 | client_sock, sockname = listen_sock.accept() 19 | handle_client(client_sock) 20 | 21 | if __name__ == '__main__': 22 | listen_sock = lancelot.setup() 23 | server_loop(listen_sock) 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/07/server_twisted.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_twisted.py 3 | # Using Twisted to serve Lancelot users. 4 | 5 | from twisted.internet.protocol import Protocol, ServerFactory 6 | from twisted.internet import reactor 7 | import lancelot 8 | 9 | class Lancelot(Protocol): 10 | def connectionMade(self): 11 | self.question = '' 12 | 13 | def dataReceived(self, data): 14 | self.question += data 15 | if self.question.endswith('?'): 16 | self.transport.write(dict(lancelot.qa)[self.question]) 17 | self.question = '' 18 | 19 | factory = ServerFactory() 20 | factory.protocol = Lancelot 21 | reactor.listenTCP(1060, factory) 22 | reactor.run() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/08/hashing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 8 - hashing.py 3 | # Hashes are a great way to divide work. 4 | 5 | import hashlib 6 | 7 | def alpha_shard(word): 8 | """Do a poor job of assigning data to servers by using first letters.""" 9 | if word[0] in 'abcdef': 10 | return 'server0' 11 | elif word[0] in 'ghijklm': 12 | return 'server1' 13 | elif word[0] in 'nopqrs': 14 | return 'server2' 15 | else: 16 | return 'server3' 17 | 18 | def hash_shard(word): 19 | """Do a great job of assigning data to servers using a hash value.""" 20 | return 'server%d' % (hash(word) % 4) 21 | 22 | def md5_shard(word): 23 | """Do a great job of assigning data to servers using a hash value.""" 24 | # digest() is a byte string, so we ord() its last character 25 | return 'server%d' % (ord(hashlib.md5(word).digest()[-1]) % 4) 26 | 27 | words = open('/usr/share/dict/words').read().split() 28 | 29 | for function in alpha_shard, hash_shard, md5_shard: 30 | d = {'server0': 0, 'server1': 0, 'server2': 0, 'server3': 0} 31 | for word in words: 32 | d[function(word.lower())] += 1 33 | print function.__name__[:-6], d 34 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/08/queuecrazy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 8 - queuecrazy.py 3 | # Small application that uses several different message queues 4 | 5 | import random, threading, time, zmq 6 | zcontext = zmq.Context() 7 | 8 | def fountain(url): 9 | """Produces a steady stream of words.""" 10 | zsock = zcontext.socket(zmq.PUSH) 11 | zsock.bind(url) 12 | words = [ w for w in dir(__builtins__) if w.islower() ] 13 | while True: 14 | zsock.send(random.choice(words)) 15 | time.sleep(0.4) 16 | 17 | def responder(url, function): 18 | """Performs a string operation on each word received.""" 19 | zsock = zcontext.socket(zmq.REP) 20 | zsock.bind(url) 21 | while True: 22 | word = zsock.recv() 23 | zsock.send(function(word)) # send the modified word back 24 | 25 | def processor(n, fountain_url, responder_urls): 26 | """Read words as they are produced; get them processed; print them.""" 27 | zpullsock = zcontext.socket(zmq.PULL) 28 | zpullsock.connect(fountain_url) 29 | 30 | zreqsock = zcontext.socket(zmq.REQ) 31 | for url in responder_urls: 32 | zreqsock.connect(url) 33 | 34 | while True: 35 | word = zpullsock.recv() 36 | zreqsock.send(word) 37 | print n, zreqsock.recv() 38 | 39 | def start_thread(function, *args): 40 | thread = threading.Thread(target=function, args=args) 41 | thread.daemon = True # so you can easily Control-C the whole program 42 | thread.start() 43 | 44 | start_thread(fountain, 'tcp://127.0.0.1:6700') 45 | start_thread(responder, 'tcp://127.0.0.1:6701', str.upper) 46 | start_thread(responder, 'tcp://127.0.0.1:6702', str.lower) 47 | for n in range(3): 48 | start_thread(processor, n + 1, 'tcp://127.0.0.1:6700', 49 | ['tcp://127.0.0.1:6701', 'tcp://127.0.0.1:6702']) 50 | time.sleep(30) 51 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/08/squares.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 8 - squares.py 3 | # Using memcached to cache expensive results. 4 | 5 | import memcache, random, time, timeit 6 | mc = memcache.Client(['127.0.0.1:11211']) 7 | 8 | def compute_square(n): 9 | value = mc.get('sq:%d' % n) 10 | if value is None: 11 | time.sleep(0.001) # pretend that computing a square is expensive 12 | value = n * n 13 | mc.set('sq:%d' % n, value) 14 | return value 15 | 16 | def make_request(): 17 | compute_square(random.randint(0, 5000)) 18 | 19 | print 'Ten successive runs:', 20 | for i in range(1, 11): 21 | print '%.2fs' % timeit.timeit(make_request, number=2000), 22 | print 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/09/get_rfc2616.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 9 - verbose_handler.py 3 | # Example use of the verbose HTTP request handler. 4 | 5 | import urllib, urllib2 6 | from verbose_http import VerboseHTTPHandler 7 | opener = urllib2.build_opener(VerboseHTTPHandler) 8 | opener.open('http://www.ietf.org/rfc/rfc2616.txt') 9 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/09/verbose_http.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 9 - verbose_http.py 3 | # HTTP request handler for urllib2 that prints requests and responses. 4 | 5 | import StringIO, httplib, urllib2 6 | 7 | class VerboseHTTPResponse(httplib.HTTPResponse): 8 | def _read_status(self): 9 | s = self.fp.read() 10 | print '-' * 20, 'Response', '-' * 20 11 | print s.split('\r\n\r\n')[0] 12 | self.fp = StringIO.StringIO(s) 13 | return httplib.HTTPResponse._read_status(self) 14 | 15 | class VerboseHTTPConnection(httplib.HTTPConnection): 16 | response_class = VerboseHTTPResponse 17 | def send(self, s): 18 | print '-' * 50 19 | print s.strip() 20 | httplib.HTTPConnection.send(self, s) 21 | 22 | class VerboseHTTPHandler(urllib2.HTTPHandler): 23 | def http_open(self, req): 24 | return self.do_open(VerboseHTTPConnection, req) 25 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/10/excerpt.html: -------------------------------------------------------------------------------- 1 | 2 | 7-Day Forecast for Latitude 33.45°N and Longitude 112.07°W (Elev. 1132 ft) 3 | ... 4 |
5 | 6 | 10 | 11 | 12 |
7 | Phoenix, Phoenix Sky Harbor International Airport
8 | Last Update on 29 Oct 7:51 MST

9 |
13 | 14 | 15 | 19 |
16 | 17 | A Few Clouds
18 |
71°F
(22°C)
20 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
Humidity:30 %
Wind Speed:SE 5 MPH
26 |
Barometer:30.05 in (1015.90 mb)
Dewpoint:38°F (3°C)
Visibility:10.00 Miles
More Local Wx: 3 Day History:
40 | ... 41 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/10/fetch_mechanize.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 10 - fetch_mechanize.py 3 | # Submitting a form and retrieving a page with mechanize 4 | 5 | import mechanize 6 | br = mechanize.Browser() 7 | br.open('http://www.weather.gov/') 8 | br.select_form(predicate=lambda(form): 'zipcity' in form.action) 9 | br['inputstring'] = 'Phoenix, AZ' 10 | response = br.submit() 11 | content = response.read() 12 | open('phoenix.html', 'w').write(content) 13 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/10/fetch_urllib2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 10 - fetch_urllib2.py 3 | # Submitting a form and retrieving a page with urllib2 4 | 5 | import urllib, urllib2 6 | data = urllib.urlencode({'inputstring': 'Phoenix, AZ'}) 7 | info = urllib2.urlopen('http://forecast.weather.gov/zipcity.php', data) 8 | content = info.read() 9 | open('phoenix.html', 'w').write(content) 10 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/10/weather.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 10 - weather.py 3 | # Fetch the weather forecast from the National Weather Service. 4 | 5 | import sys, urllib, urllib2 6 | import lxml.etree 7 | from lxml.cssselect import CSSSelector 8 | from BeautifulSoup import BeautifulSoup 9 | 10 | if len(sys.argv) < 2: 11 | print >>sys.stderr, 'usage: weather.py CITY, STATE' 12 | exit(2) 13 | 14 | data = urllib.urlencode({'inputstring': ' '.join(sys.argv[1:])}) 15 | info = urllib2.urlopen('http://forecast.weather.gov/zipcity.php', data) 16 | content = info.read() 17 | 18 | # Solution #1 19 | parser = lxml.etree.HTMLParser(encoding='utf-8') 20 | tree = lxml.etree.fromstring(content, parser) 21 | big = CSSSelector('td.big')(tree)[0] 22 | if big.find('font') is not None: 23 | big = big.find('font') 24 | print 'Condition:', big.text.strip() 25 | print 'Temperature:', big.findall('br')[1].tail 26 | tr = tree.xpath('.//td[b="Humidity"]')[0].getparent() 27 | print 'Humidity:', tr.findall('td')[1].text 28 | print 29 | 30 | # Solution #2 31 | soup = BeautifulSoup(content) # doctest: +SKIP 32 | big = soup.find('td', 'big') 33 | if big.font is not None: 34 | big = big.font 35 | print 'Condition:', big.contents[0].string.strip() 36 | temp = big.contents[3].string or big.contents[4].string # can be either 37 | print 'Temperature:', temp.replace('°', ' ') 38 | tr = soup.find('b', text='Humidity').parent.parent.parent 39 | print 'Humidity:', tr('td')[1].string 40 | print 41 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/11/bottle_app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 11 - bottle_app.py 3 | # A simple web application built using the Bottle micro-framework. 4 | 5 | import base64, bottle 6 | bottle.debug(True) 7 | app = bottle.Bottle() 8 | 9 | @app.route('/encode') 10 | @bottle.view('bottle_template.html') 11 | def encode(): 12 | mystring = bottle.request.GET.get('mystring') 13 | if mystring is None: 14 | bottle.abort(400, 'This form requires a "mystring" parameter') 15 | return dict(mystring=mystring, myb=base64.b64encode(mystring)) 16 | 17 | @app.route('/') 18 | @bottle.view('bottle_template.html') 19 | def index(): 20 | return dict(mystring=None) 21 | 22 | bottle.run(app=app, host='localhost', port=8080) 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/11/bottle_template.html: -------------------------------------------------------------------------------- 1 | %#!/usr/bin/env python 2 | %# Foundations of Python Network Programming - Chapter 11 - bottle_template.py 3 | %# The page template that goes with bottle_app.py. 4 | %# 5 | bottle_app.py 6 | 7 | %if mystring is None: 8 | Welcome! Enter a string: 9 |
10 | %else: 11 | {{mystring}} base64 encoded is: {{myb}}
12 | Return to the home page 13 | %end 14 | 15 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/11/wsgi_app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 11 - wsgi_app.py 3 | # A simple web application built directly against the low-level WSGI spec. 4 | 5 | import cgi, base64 6 | from wsgiref.simple_server import make_server 7 | 8 | def page(content, *args): 9 | yield 'wsgi_app.py' 10 | yield content % args 11 | yield '' 12 | 13 | def simple_app(environ, start_response): 14 | gohome = '
Return to the home page' 15 | q = cgi.parse_qs(environ['QUERY_STRING']) 16 | 17 | if environ['PATH_INFO'] == '/': 18 | 19 | if environ['REQUEST_METHOD'] != 'GET' or environ['QUERY_STRING']: 20 | start_response('400 Bad Request', [('Content-Type', 'text/plain')]) 21 | return ['Error: the front page is not a form'] 22 | 23 | start_response('200 OK', [('Content-Type', 'text/html')]) 24 | return page('Welcome! Enter a string:
' 25 | '
') 26 | 27 | elif environ['PATH_INFO'] == '/encode': 28 | 29 | if environ['REQUEST_METHOD'] != 'GET': 30 | start_response('400 Bad Request', [('Content-Type', 'text/plain')]) 31 | return ['Error: this form does not support POST parameters'] 32 | 33 | if 'mystring' not in q or not q['mystring'][0]: 34 | start_response('400 Bad Request', [('Content-Type', 'text/plain')]) 35 | return ['Error: this form requires a "mystring" parameter'] 36 | 37 | my = q['mystring'][0] 38 | start_response('200 OK', [('Content-Type', 'text/html')]) 39 | return page('%s base64 encoded is: %s' + gohome, 40 | cgi.escape(repr(my)), cgi.escape(base64.b64encode(my))) 41 | 42 | else: 43 | start_response('404 Not Found', [('Content-Type', 'text/plain')]) 44 | return ['That URL is not valid'] 45 | 46 | print 'Listening on localhost:8000' 47 | make_server('localhost', 8000, simple_app).serve_forever() 48 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/message.txt: -------------------------------------------------------------------------------- 1 | To: recipient@example.com 2 | From: Test Sender 3 | Subject: Test Message, Chapter 12 4 | Date: Mon, 02 Aug 2010 10:05:55 -0400 5 | Message-ID: <20100802140555.11734.89229@guinness.ten22> 6 | 7 | Hello, 8 | 9 | This is a test message from Chapter 12. I hope you enjoy it! 10 | 11 | -- Anonymous 12 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/mime_decode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_decode.py 3 | # This program requires Python 2.2.2 or above 4 | 5 | import sys, email 6 | counter = 0 7 | parts = [] 8 | 9 | def printmsg(msg, level = 0): 10 | global counter 11 | l = "| " * level 12 | if msg.is_multipart(): 13 | print l + "Found multipart:" 14 | for item in msg.get_payload(): 15 | printmsg(item, level + 1) 16 | else: 17 | disp = ['%d. Decodable part' % (counter + 1)] 18 | if 'content-type' in msg: 19 | disp.append(msg['content-type']) 20 | if 'content-disposition' in msg: 21 | disp.append(msg['content-disposition']) 22 | print l + ", ".join(disp) 23 | counter += 1 24 | parts.append(msg) 25 | 26 | inputfd = open(sys.argv[1]) 27 | msg = email.message_from_file(inputfd) 28 | printmsg(msg) 29 | 30 | while 1: 31 | print "Select part number to decode or q to quit: " 32 | part = sys.stdin.readline().strip() 33 | if part == 'q': 34 | sys.exit(0) 35 | try: 36 | part = int(part) 37 | msg = parts[part - 1] 38 | except: 39 | print "Invalid selection." 40 | continue 41 | 42 | print "Select file to write to:" 43 | filename = sys.stdin.readline().strip() 44 | try: 45 | fd = open(filename, 'wb') 46 | except: 47 | print "Invalid filename." 48 | continue 49 | 50 | fd.write(msg.get_payload(decode = 1)) 51 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/mime_gen_alt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_gen_alt.py 3 | # This program requires Python 2.2.2 or above 4 | 5 | from email.mime.base import MIMEBase 6 | from email.mime.multipart import MIMEMultipart 7 | from email.mime.text import MIMEText 8 | from email import utils, encoders 9 | 10 | def alternative(data, contenttype): 11 | maintype, subtype = contenttype.split('/') 12 | if maintype == 'text': 13 | retval = MIMEText(data, _subtype=subtype) 14 | else: 15 | retval = MIMEBase(maintype, subtype) 16 | retval.set_payload(data) 17 | encoders.encode_base64(retval) 18 | return retval 19 | 20 | messagetext = """Hello, 21 | 22 | This is a *great* test message from Chapter 12. I hope you enjoy it! 23 | 24 | -- Anonymous""" 25 | messagehtml = """Hello,

26 | This is a great test message from Chapter 12. I hope you enjoy 27 | it!

28 | -- Anonymous""" 29 | 30 | 31 | msg = MIMEMultipart('alternative') 32 | msg['To'] = 'recipient@example.com' 33 | msg['From'] = 'Test Sender ' 34 | msg['Subject'] = 'Test Message, Chapter 12' 35 | msg['Date'] = utils.formatdate(localtime = 1) 36 | msg['Message-ID'] = utils.make_msgid() 37 | 38 | msg.attach(alternative(messagetext, 'text/plain')) 39 | msg.attach(alternative(messagehtml, 'text/html')) 40 | print msg.as_string() 41 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/mime_gen_basic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_gen_basic.py 3 | # This program requires Python 2.5 or above 4 | 5 | from email.mime.base import MIMEBase 6 | from email.mime.multipart import MIMEMultipart 7 | from email.mime.text import MIMEText 8 | from email import utils, encoders 9 | import mimetypes, sys 10 | 11 | def attachment(filename): 12 | fd = open(filename, 'rb') 13 | mimetype, mimeencoding = mimetypes.guess_type(filename) 14 | if mimeencoding or (mimetype is None): 15 | mimetype = 'application/octet-stream' 16 | maintype, subtype = mimetype.split('/') 17 | if maintype == 'text': 18 | retval = MIMEText(fd.read(), _subtype=subtype) 19 | else: 20 | retval = MIMEBase(maintype, subtype) 21 | retval.set_payload(fd.read()) 22 | encoders.encode_base64(retval) 23 | retval.add_header('Content-Disposition', 'attachment', 24 | filename = filename) 25 | fd.close() 26 | return retval 27 | 28 | message = """Hello, 29 | 30 | This is a test message from Chapter 12. I hope you enjoy it! 31 | 32 | -- Anonymous""" 33 | 34 | msg = MIMEMultipart() 35 | msg['To'] = 'recipient@example.com' 36 | msg['From'] = 'Test Sender ' 37 | msg['Subject'] = 'Test Message, Chapter 12' 38 | msg['Date'] = utils.formatdate(localtime = 1) 39 | msg['Message-ID'] = utils.make_msgid() 40 | 41 | body = MIMEText(message, _subtype='plain') 42 | msg.attach(body) 43 | for filename in sys.argv[1:]: 44 | msg.attach(attachment(filename)) 45 | print msg.as_string() 46 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/mime_gen_both.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_gen_both.py 3 | 4 | from email.mime.text import MIMEText 5 | from email.mime.multipart import MIMEMultipart 6 | from email.mime.base import MIMEBase 7 | from email import utils, encoders 8 | import mimetypes, sys 9 | 10 | def genpart(data, contenttype): 11 | maintype, subtype = contenttype.split('/') 12 | if maintype == 'text': 13 | retval = MIMEText(data, _subtype=subtype) 14 | else: 15 | retval = MIMEBase(maintype, subtype) 16 | retval.set_payload(data) 17 | encoders.encode_base64(retval) 18 | return retval 19 | 20 | 21 | def attachment(filename): 22 | fd = open(filename, 'rb') 23 | mimetype, mimeencoding = mimetypes.guess_type(filename) 24 | if mimeencoding or (mimetype is None): 25 | mimetype = 'application/octet-stream' 26 | retval = genpart(fd.read(), mimetype) 27 | retval.add_header('Content-Disposition', 'attachment', 28 | filename = filename) 29 | fd.close() 30 | return retval 31 | 32 | messagetext = """Hello, 33 | 34 | This is a *great* test message from Chapter 12. I hope you enjoy it! 35 | 36 | -- Anonymous""" 37 | messagehtml = """Hello,

38 | This is a great test message from Chapter 12. I hope you enjoy 39 | it!

40 | -- Anonymous""" 41 | 42 | msg = MIMEMultipart() 43 | msg['To'] = 'recipient@example.com' 44 | msg['From'] = 'Test Sender ' 45 | msg['Subject'] = 'Test Message, Chapter 12' 46 | msg['Date'] = utils.formatdate(localtime = 1) 47 | msg['Message-ID'] = utils.make_msgid() 48 | 49 | body = MIMEMultipart('alternative') 50 | body.attach(genpart(messagetext, 'text/plain')) 51 | body.attach(genpart(messagehtml, 'text/html')) 52 | msg.attach(body) 53 | 54 | for filename in sys.argv[1:]: 55 | msg.attach(attachment(filename)) 56 | print msg.as_string() 57 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/mime_headers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_headers.py 3 | # This program requires Python 2.5 or above 4 | 5 | from email.mime.text import MIMEText 6 | from email.header import Header 7 | 8 | message = """Hello, 9 | 10 | This is a test message from Chapter 12. I hope you enjoy it! 11 | 12 | -- Anonymous""" 13 | 14 | msg = MIMEText(message) 15 | msg['To'] = 'recipient@example.com' 16 | fromhdr = Header() 17 | fromhdr.append(u"Michael M\xfcller") 18 | fromhdr.append('') 19 | msg['From'] = fromhdr 20 | msg['Subject'] = 'Test Message, Chapter 12' 21 | 22 | print msg.as_string() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/mime_parse_headers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_parse_headers.py 3 | 4 | import sys, email, codecs 5 | from email import Header 6 | 7 | msg = email.message_from_file(sys.stdin) 8 | for header, value in msg.items(): 9 | headerparts = Header.decode_header(value) 10 | headerval = [] 11 | for part in headerparts: 12 | data, charset = part 13 | if charset is None: 14 | charset = 'ascii' 15 | dec = codecs.getdecoder(charset) 16 | enc = codecs.getencoder('iso-8859-1') 17 | data = enc(dec(data)[0])[0] 18 | headerval.append(data) 19 | print "%s: %s" % (header, " ".join(headerval)) 20 | 21 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/mime_structure.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_structure.py 3 | # This program requires Python 2.2.2 or above 4 | 5 | import sys, email 6 | 7 | def printmsg(msg, level = 0): 8 | prefix = "| " * level 9 | prefix2 = prefix + "|" 10 | print prefix + "+ Message Headers:" 11 | for header, value in msg.items(): 12 | print prefix2, header + ":", value 13 | if msg.is_multipart(): 14 | for item in msg.get_payload(): 15 | printmsg(item, level + 1) 16 | 17 | msg = email.message_from_file(sys.stdin) 18 | printmsg(msg) 19 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/test.txt: -------------------------------------------------------------------------------- 1 | This is a test 2 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/test.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/foundations-of-python-network-programming/f9e2f1f9fd424da3880c94258134ab3e9fa54969/foundations-of-python-network-programming/python2/12/test.txt.gz -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/trad_gen_newhdrs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - trad_gen_newhdrs.py 3 | # Traditional Message Generation with Date and Message-ID 4 | # This program requires Python 2.5 or above 5 | 6 | import email.utils 7 | from email.message import Message 8 | 9 | message = """Hello, 10 | 11 | This is a test message from Chapter 12. I hope you enjoy it! 12 | 13 | -- Anonymous""" 14 | 15 | msg = Message() 16 | msg['To'] = 'recipient@example.com' 17 | msg['From'] = 'Test Sender ' 18 | msg['Subject'] = 'Test Message, Chapter 12' 19 | msg['Date'] = email.utils.formatdate(localtime = 1) 20 | msg['Message-ID'] = email.utils.make_msgid() 21 | msg.set_payload(message) 22 | 23 | print msg.as_string() 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/trad_gen_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - trad_gen_simple.py 3 | # Traditional Message Generation, Simple 4 | # This program requires Python 2.5 or above 5 | 6 | from email.message import Message 7 | text = """Hello, 8 | 9 | This is a test message from Chapter 12. I hope you enjoy it! 10 | 11 | -- Anonymous""" 12 | 13 | msg = Message() 14 | msg['To'] = 'recipient@example.com' 15 | msg['From'] = 'Test Sender ' 16 | msg['Subject'] = 'Test Message, Chapter 12' 17 | msg.set_payload(text) 18 | 19 | print msg.as_string() 20 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/12/trad_parse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - trad_parse.py 3 | # Traditional Message Parsing 4 | # This program requires Python 2.5 or above 5 | 6 | import email 7 | 8 | banner = '-' * 48 9 | popular_headers = ('From', 'To', 'Subject', 'Date') 10 | msg = email.message_from_file(open('message.txt')) 11 | headers = sorted(msg.keys()) 12 | 13 | print banner 14 | for header in headers: 15 | if header not in popular_headers: 16 | print header + ':', msg[header] 17 | print banner 18 | for header in headers: 19 | if header in popular_headers: 20 | print header + ':', msg[header] 21 | 22 | print banner 23 | if msg.is_multipart(): 24 | print "This program cannot handle MIME multipart messages." 25 | else: 26 | print msg.get_payload() 27 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/13/debug.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SMTP transmission with debugging - Chapter 13 - debug.py 3 | 4 | import sys, smtplib, socket 5 | 6 | if len(sys.argv) < 4: 7 | print "usage: %s server fromaddr toaddr [toaddr...]" % sys.argv[0] 8 | sys.exit(2) 9 | 10 | server, fromaddr, toaddrs = sys.argv[1], sys.argv[2], sys.argv[3:] 11 | 12 | message = """To: %s 13 | From: %s 14 | Subject: Test Message from simple.py 15 | 16 | Hello, 17 | 18 | This is a test message sent to you from the debug.py program 19 | in Foundations of Python Network Programming. 20 | """ % (', '.join(toaddrs), fromaddr) 21 | 22 | try: 23 | s = smtplib.SMTP(server) 24 | s.set_debuglevel(1) 25 | s.sendmail(fromaddr, toaddrs, message) 26 | except (socket.gaierror, socket.error, socket.herror, 27 | smtplib.SMTPException), e: 28 | print " *** Your message may not have been sent!" 29 | print e 30 | sys.exit(1) 31 | else: 32 | print "Message successfully sent to %d recipient(s)" % len(toaddrs) 33 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/13/ehlo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SMTP transmission with manual EHLO - Chapter 13 - ehlo.py 3 | 4 | import sys, smtplib, socket 5 | 6 | if len(sys.argv) < 4: 7 | print "usage: %s server fromaddr toaddr [toaddr...]" % sys.argv[0] 8 | sys.exit(2) 9 | 10 | server, fromaddr, toaddrs = sys.argv[1], sys.argv[2], sys.argv[3:] 11 | 12 | message = """To: %s 13 | From: %s 14 | Subject: Test Message from simple.py 15 | 16 | Hello, 17 | 18 | This is a test message sent to you from the ehlo.py program 19 | in Foundations of Python Network Programming. 20 | """ % (', '.join(toaddrs), fromaddr) 21 | 22 | try: 23 | s = smtplib.SMTP(server) 24 | code = s.ehlo()[0] 25 | uses_esmtp = (200 <= code <= 299) 26 | if not uses_esmtp: 27 | code = s.helo()[0] 28 | if not (200 <= code <= 299): 29 | print "Remote server refused HELO; code:", code 30 | sys.exit(1) 31 | 32 | if uses_esmtp and s.has_extn('size'): 33 | print "Maximum message size is", s.esmtp_features['size'] 34 | if len(message) > int(s.esmtp_features['size']): 35 | print "Message too large; aborting." 36 | sys.exit(1) 37 | 38 | s.sendmail(fromaddr, toaddrs, message) 39 | 40 | except (socket.gaierror, socket.error, socket.herror, 41 | smtplib.SMTPException), e: 42 | print " *** Your message may not have been sent!" 43 | print e 44 | sys.exit(1) 45 | else: 46 | print "Message successfully sent to %d recipient(s)" % len(toaddrs) 47 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/13/login.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SMTP transmission with authentication - Chapter 13 - login.py 3 | 4 | import sys, smtplib, socket 5 | from getpass import getpass 6 | 7 | if len(sys.argv) < 4: 8 | print "Syntax: %s server fromaddr toaddr [toaddr...]" % sys.argv[0] 9 | sys.exit(2) 10 | 11 | server, fromaddr, toaddrs = sys.argv[1], sys.argv[2], sys.argv[3:] 12 | 13 | message = """To: %s 14 | From: %s 15 | Subject: Test Message from simple.py 16 | 17 | Hello, 18 | 19 | This is a test message sent to you from the login.py program 20 | in Foundations of Python Network Programming. 21 | """ % (', '.join(toaddrs), fromaddr) 22 | 23 | sys.stdout.write("Enter username: ") 24 | username = sys.stdin.readline().strip() 25 | password = getpass("Enter password: ") 26 | 27 | try: 28 | s = smtplib.SMTP(server) 29 | try: 30 | s.login(username, password) 31 | except smtplib.SMTPException, e: 32 | print "Authentication failed:", e 33 | sys.exit(1) 34 | s.sendmail(fromaddr, toaddrs, message) 35 | except (socket.gaierror, socket.error, socket.herror, 36 | smtplib.SMTPException), e: 37 | print " *** Your message may not have been sent!" 38 | print e 39 | sys.exit(1) 40 | else: 41 | print "Message successfully sent to %d recipient(s)" % len(toaddrs) 42 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/13/simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Basic SMTP transmission - Chapter 13 - simple.py 3 | 4 | import sys, smtplib 5 | 6 | if len(sys.argv) < 4: 7 | print "usage: %s server fromaddr toaddr [toaddr...]" % sys.argv[0] 8 | sys.exit(2) 9 | 10 | server, fromaddr, toaddrs = sys.argv[1], sys.argv[2], sys.argv[3:] 11 | 12 | message = """To: %s 13 | From: %s 14 | Subject: Test Message from simple.py 15 | 16 | Hello, 17 | 18 | This is a test message sent to you from the simple.py program 19 | in Foundations of Python Network Programming. 20 | """ % (', '.join(toaddrs), fromaddr) 21 | 22 | s = smtplib.SMTP(server) 23 | s.sendmail(fromaddr, toaddrs, message) 24 | 25 | print "Message successfully sent to %d recipient(s)" % len(toaddrs) 26 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/13/tls.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SMTP transmission with TLS - Chapter 13 - tls.py 3 | 4 | import sys, smtplib, socket 5 | 6 | if len(sys.argv) < 4: 7 | print "Syntax: %s server fromaddr toaddr [toaddr...]" % sys.argv[0] 8 | sys.exit(2) 9 | 10 | server, fromaddr, toaddrs = sys.argv[1], sys.argv[2], sys.argv[3:] 11 | 12 | message = """To: %s 13 | From: %s 14 | Subject: Test Message from simple.py 15 | 16 | Hello, 17 | 18 | This is a test message sent to you from the tls.py program 19 | in Foundations of Python Network Programming. 20 | """ % (', '.join(toaddrs), fromaddr) 21 | 22 | try: 23 | s = smtplib.SMTP(server) 24 | code = s.ehlo()[0] 25 | uses_esmtp = (200 <= code <= 299) 26 | if not uses_esmtp: 27 | code = s.helo()[0] 28 | if not (200 <= code <= 299): 29 | print "Remove server refused HELO; code:", code 30 | sys.exit(1) 31 | 32 | if uses_esmtp and s.has_extn('starttls'): 33 | print "Negotiating TLS...." 34 | s.starttls() 35 | code = s.ehlo()[0] 36 | if not (200 <= code <= 299): 37 | print "Couldn't EHLO after STARTTLS" 38 | sys.exit(5) 39 | print "Using TLS connection." 40 | else: 41 | print "Server does not support TLS; using normal connection." 42 | s.sendmail(fromaddr, toaddrs, message) 43 | 44 | except (socket.gaierror, socket.error, socket.herror, 45 | smtplib.SMTPException), e: 46 | print " *** Your message may not have been sent!" 47 | print e 48 | sys.exit(1) 49 | else: 50 | print "Message successfully sent to %d recipient(s)" % len(toaddrs) 51 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/14/download-and-delete.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # POP mailbox downloader with deletion - Chapter 14 3 | # download-and-delete.py 4 | 5 | import email, getpass, poplib, sys 6 | 7 | if len(sys.argv) != 3: 8 | print 'usage: %s hostname user' % sys.argv[0] 9 | exit(2) 10 | 11 | hostname, user = sys.argv[1:] 12 | passwd = getpass.getpass() 13 | 14 | p = poplib.POP3_SSL(hostname) 15 | try: 16 | p.user(user) 17 | p.pass_(passwd) 18 | except poplib.error_proto, e: 19 | print "Login failed:", e 20 | else: 21 | response, listings, octets = p.list() 22 | for listing in listings: 23 | number, size = listing.split() 24 | print 'Message', number, '(size is', size, 'bytes):' 25 | print 26 | response, lines, octets = p.top(number, 0) 27 | message = email.message_from_string('\n'.join(lines)) 28 | for header in 'From', 'To', 'Subject', 'Date': 29 | if header in message: 30 | print header + ':', message[header] 31 | print 32 | print 'Read this message [ny]?' 33 | answer = raw_input() 34 | if answer.lower().startswith('y'): 35 | response, lines, octets = p.retr(number) 36 | message = email.message_from_string('\n'.join(lines)) 37 | print '-' * 72 38 | for part in message.walk(): 39 | if part.get_content_type() == 'text/plain': 40 | print part.get_payload() 41 | print '-' * 72 42 | print 43 | print 'Delete this message [ny]?' 44 | answer = raw_input() 45 | if answer.lower().startswith('y'): 46 | p.dele(number) 47 | print 'Deleted.' 48 | finally: 49 | p.quit() 50 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/14/mailbox.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # POP mailbox scanning - Chapter 14 - mailbox.py 3 | 4 | import getpass, poplib, sys 5 | 6 | if len(sys.argv) != 3: 7 | print 'usage: %s hostname user' % sys.argv[0] 8 | exit(2) 9 | 10 | hostname, user = sys.argv[1:] 11 | passwd = getpass.getpass() 12 | 13 | p = poplib.POP3_SSL(hostname) 14 | try: 15 | p.user(user) 16 | p.pass_(passwd) 17 | except poplib.error_proto, e: 18 | print "Login failed:", e 19 | else: 20 | response, listings, octet_count = p.list() 21 | for listing in listings: 22 | number, size = listing.split() 23 | print "Message %s has %s bytes" % (number, size) 24 | finally: 25 | p.quit() 26 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/14/popconn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # POP connection and authentication - Chapter 14 - popconn.py 3 | 4 | import getpass, poplib, sys 5 | 6 | if len(sys.argv) != 3: 7 | print 'usage: %s hostname user' % sys.argv[0] 8 | exit(2) 9 | 10 | hostname, user = sys.argv[1:] 11 | passwd = getpass.getpass() 12 | 13 | p = poplib.POP3_SSL(hostname) # or "POP3" if SSL is not supported 14 | try: 15 | p.user(user) 16 | p.pass_(passwd) 17 | except poplib.error_proto, e: 18 | print "Login failed:", e 19 | else: 20 | status = p.stat() 21 | print "You have %d messages totaling %d bytes" % status 22 | finally: 23 | p.quit() 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/15/folder_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 15 - folder_info.py 3 | # Opening an IMAP connection with IMAPClient and listing folder information. 4 | 5 | import getpass, sys 6 | from imapclient import IMAPClient 7 | 8 | try: 9 | hostname, username = sys.argv[1:] 10 | except ValueError: 11 | print 'usage: %s hostname username' % sys.argv[0] 12 | sys.exit(2) 13 | 14 | c = IMAPClient(hostname, ssl=True) 15 | try: 16 | c.login(username, getpass.getpass()) 17 | except c.Error, e: 18 | print 'Could not log in:', e 19 | sys.exit(1) 20 | else: 21 | select_dict = c.select_folder('INBOX', readonly=True) 22 | for k, v in select_dict.items(): 23 | print '%s: %r' % (k, v) 24 | c.logout() 25 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/15/mailbox_summary.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 15 - mailbox_summary.py 3 | # Opening an IMAP connection with IMAPClient and retrieving mailbox messages. 4 | 5 | import email, getpass, sys 6 | from imapclient import IMAPClient 7 | 8 | try: 9 | hostname, username, foldername = sys.argv[1:] 10 | except ValueError: 11 | print 'usage: %s hostname username folder' % sys.argv[0] 12 | sys.exit(2) 13 | 14 | c = IMAPClient(hostname, ssl=True) 15 | try: 16 | c.login(username, getpass.getpass()) 17 | except c.Error, e: 18 | print 'Could not log in:', e 19 | sys.exit(1) 20 | 21 | c.select_folder(foldername, readonly=True) 22 | msgdict = c.fetch('1:*', ['BODY.PEEK[]']) 23 | for message_id, message in msgdict.items(): 24 | e = email.message_from_string(message['BODY[]']) 25 | print message_id, e['From'] 26 | payload = e.get_payload() 27 | if isinstance(payload, list): 28 | part_content_types = [ part.get_content_type() for part in payload ] 29 | print ' Parts:', ' '.join(part_content_types) 30 | else: 31 | print ' ', ' '.join(payload[:60].split()), '...' 32 | 33 | c.logout() 34 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/15/open_imap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 15 - open_imap.py 3 | # Opening an IMAP connection with the powerful IMAPClient 4 | 5 | import getpass, sys 6 | from imapclient import IMAPClient 7 | 8 | try: 9 | hostname, username = sys.argv[1:] 10 | except ValueError: 11 | print 'usage: %s hostname username' % sys.argv[0] 12 | sys.exit(2) 13 | 14 | c = IMAPClient(hostname, ssl=True) 15 | try: 16 | c.login(username, getpass.getpass()) 17 | except c.Error, e: 18 | print 'Could not log in:', e 19 | sys.exit(1) 20 | 21 | print 'Capabilities:', c.capabilities() 22 | print 'Listing mailboxes:' 23 | data = c.list_folders() 24 | for flags, delimiter, folder_name in data: 25 | print ' %-30s%s %s' % (' '.join(flags), delimiter, folder_name) 26 | c.logout() 27 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/15/open_imap.txt: -------------------------------------------------------------------------------- 1 | Capabilities: ('IMAP4REV1', 'UNSELECT', 'IDLE', 'NAMESPACE', 'QUOTA', 'XLIST', 'CHILDREN', 'XYZZY', 'SASL-IR', 'AUTH=XOAUTH') 2 | Listing mailboxes: 3 | \HasNoChildren / INBOX 4 | \HasNoChildren / Personal 5 | \HasNoChildren / Receipts 6 | \HasNoChildren / Travel 7 | \HasNoChildren / Work 8 | \Noselect \HasChildren / [Gmail] 9 | \HasChildren \HasNoChildren / [Gmail]/All Mail 10 | \HasNoChildren / [Gmail]/Drafts 11 | \HasChildren \HasNoChildren / [Gmail]/Sent Mail 12 | \HasNoChildren / [Gmail]/Spam 13 | \HasNoChildren / [Gmail]/Starred 14 | \HasChildren \HasNoChildren / [Gmail]/Trash 15 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/15/open_imaplib.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 15 - open_imaplib.py 3 | # Opening an IMAP connection with the pitiful Python Standard Library 4 | 5 | import getpass, imaplib, sys 6 | 7 | try: 8 | hostname, username = sys.argv[1:] 9 | except ValueError: 10 | print 'usage: %s hostname username' % sys.argv[0] 11 | sys.exit(2) 12 | 13 | m = imaplib.IMAP4_SSL(hostname) 14 | m.login(username, getpass.getpass()) 15 | print 'Capabilities:', m.capabilities 16 | print 'Listing mailboxes ' 17 | status, data = m.list() 18 | print 'Status:', repr(status) 19 | print 'Data:' 20 | for datum in data: 21 | print repr(datum) 22 | m.logout() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/15/open_imaplib.txt: -------------------------------------------------------------------------------- 1 | Capabilities: ('IMAP4REV1', 'UNSELECT', 'IDLE', 'NAMESPACE', 'QUOTA', 2 | 'XLIST', 'CHILDREN', 'XYZZY', 'SASL-IR', 'AUTH=XOAUTH') 3 | Listing mailboxes 4 | Status: 'OK' 5 | Data: 6 | '(\\HasNoChildren) "/" "INBOX"' 7 | '(\\HasNoChildren) "/" "Personal"' 8 | '(\\HasNoChildren) "/" "Receipts"' 9 | '(\\HasNoChildren) "/" "Travel"' 10 | '(\\HasNoChildren) "/" "Work"' 11 | '(\\Noselect \\HasChildren) "/" "[Gmail]"' 12 | '(\\HasChildren \\HasNoChildren) "/" "[Gmail]/All Mail"' 13 | '(\\HasNoChildren) "/" "[Gmail]/Drafts"' 14 | '(\\HasChildren \\HasNoChildren) "/" "[Gmail]/Sent Mail"' 15 | '(\\HasNoChildren) "/" "[Gmail]/Spam"' 16 | '(\\HasNoChildren) "/" "[Gmail]/Starred"' 17 | '(\\HasChildren \\HasNoChildren) "/" "[Gmail]/Trash"' 18 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/15/simple_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 15 - simple_client.py 3 | # Letting a user browse folders, messages, and message parts. 4 | 5 | import getpass, sys 6 | from imapclient import IMAPClient 7 | 8 | try: 9 | hostname, username = sys.argv[1:] 10 | except ValueError: 11 | print 'usage: %s hostname username' % sys.argv[0] 12 | sys.exit(2) 13 | 14 | banner = '-' * 72 15 | 16 | c = IMAPClient(hostname, ssl=True) 17 | try: 18 | c.login(username, getpass.getpass()) 19 | except c.Error, e: 20 | print 'Could not log in:', e 21 | sys.exit(1) 22 | 23 | def display_structure(structure, parentparts=[]): 24 | """Attractively display a given message structure.""" 25 | 26 | # The whole body of the message is named 'TEXT'. 27 | 28 | if parentparts: 29 | name = '.'.join(parentparts) 30 | else: 31 | print 'HEADER' 32 | name = 'TEXT' 33 | 34 | # Print this part's designation and its MIME type. 35 | 36 | is_multipart = isinstance(structure[0], list) 37 | if is_multipart: 38 | parttype = 'multipart/%s' % structure[1].lower() 39 | else: 40 | parttype = ('%s/%s' % structure[:2]).lower() 41 | print '%-9s' % name, parttype, 42 | 43 | # For a multipart part, print all of its subordinate parts; for 44 | # other parts, print their disposition (if available). 45 | 46 | if is_multipart: 47 | print 48 | subparts = structure[0] 49 | for i in range(len(subparts)): 50 | display_structure(subparts[i], parentparts + [ str(i + 1) ]) 51 | else: 52 | if structure[6]: 53 | print 'size=%s' % structure[6], 54 | if structure[8]: 55 | disposition, namevalues = structure[8] 56 | print disposition, 57 | for i in range(0, len(namevalues), 2): 58 | print '%s=%r' % namevalues[i:i+2] 59 | print 60 | 61 | def explore_message(c, uid): 62 | """Let the user view various parts of a given message.""" 63 | 64 | msgdict = c.fetch(uid, ['BODYSTRUCTURE', 'FLAGS']) 65 | 66 | while True: 67 | print 68 | print 'Flags:', 69 | flaglist = msgdict[uid]['FLAGS'] 70 | if flaglist: 71 | print ' '.join(flaglist) 72 | else: 73 | print 'none' 74 | display_structure(msgdict[uid]['BODYSTRUCTURE']) 75 | print 76 | reply = raw_input('Message %s - type a part name, or "q" to quit: ' 77 | % uid).strip() 78 | print 79 | if reply.lower().startswith('q'): 80 | break 81 | key = 'BODY[%s]' % reply 82 | try: 83 | msgdict2 = c.fetch(uid, [key]) 84 | except c._imap.error: 85 | print 'Error - cannot fetch section %r' % reply 86 | else: 87 | content = msgdict2[uid][key] 88 | if content: 89 | print banner 90 | print content.strip() 91 | print banner 92 | else: 93 | print '(No such section)' 94 | 95 | def explore_folder(c, name): 96 | """List the messages in folder `name` and let the user choose one.""" 97 | 98 | while True: 99 | c.select_folder(name, readonly=True) 100 | msgdict = c.fetch('1:*', ['BODY.PEEK[HEADER.FIELDS (FROM SUBJECT)]', 101 | 'FLAGS', 'INTERNALDATE', 'RFC822.SIZE']) 102 | print 103 | for uid in sorted(msgdict): 104 | items = msgdict[uid] 105 | print '%6d %20s %6d bytes %s' % ( 106 | uid, items['INTERNALDATE'], items['RFC822.SIZE'], 107 | ' '.join(items['FLAGS'])) 108 | for i in items['BODY[HEADER.FIELDS (FROM SUBJECT)]'].splitlines(): 109 | print ' ' * 6, i.strip() 110 | 111 | reply = raw_input('Folder %s - type a message UID, or "q" to quit: ' 112 | % name).strip() 113 | if reply.lower().startswith('q'): 114 | break 115 | try: 116 | reply = int(reply) 117 | except ValueError: 118 | print 'Please type an integer or "q" to quit' 119 | else: 120 | if reply in msgdict: 121 | explore_message(c, reply) 122 | 123 | c.close_folder() 124 | 125 | def explore_account(c): 126 | """Display the folders in this IMAP account and let the user choose one.""" 127 | 128 | while True: 129 | 130 | print 131 | folderflags = {} 132 | data = c.list_folders() 133 | for flags, delimiter, name in data: 134 | folderflags[name] = flags 135 | for name in sorted(folderflags.keys()): 136 | print '%-30s %s' % (name, ' '.join(folderflags[name])) 137 | print 138 | 139 | reply = raw_input('Type a folder name, or "q" to quit: ').strip() 140 | if reply.lower().startswith('q'): 141 | break 142 | if reply in folderflags: 143 | explore_folder(c, reply) 144 | else: 145 | print 'Error: no folder named', repr(reply) 146 | 147 | if __name__ == '__main__': 148 | explore_account(c) 149 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/16/fabfile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - fabfile.py 3 | # A sample Fabric script 4 | 5 | # Even though this chapter will not cover Fabric, you might want to try 6 | # using Fabric to automate your SSH commands instead of re-inventing the 7 | # wheel. Here is a script that checks for Python on remote machines. 8 | # Fabric finds this "fabfile.py" automatically if you are in the same 9 | # directory. Try running both verbosely, and with most messages off: 10 | # 11 | # $ fab versions:host=server.example.com 12 | # $ fab --hide=everything versions:host=server.example.com 13 | 14 | from fabric.api import * 15 | 16 | def versions(): 17 | with cd('/usr/bin'): 18 | with settings(hide('warnings'), warn_only=True): 19 | for version in '2.4', '2.5', '2.6', '2.7', '3.0', '3.1': 20 | result = run('python%s -c "None"' % version) 21 | if not result.failed: 22 | print "Host", env.host, "has Python", version 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/16/sftp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - sftp.py 3 | # Fetching files with SFTP 4 | 5 | import functools 6 | import paramiko 7 | 8 | class AllowAnythingPolicy(paramiko.MissingHostKeyPolicy): 9 | def missing_host_key(self, client, hostname, key): 10 | return 11 | 12 | client = paramiko.SSHClient() 13 | client.set_missing_host_key_policy(AllowAnythingPolicy()) 14 | client.connect('127.0.0.1', username='test') # password='') 15 | 16 | def my_callback(filename, bytes_so_far, bytes_total): 17 | print 'Transfer of %r is at %d/%d bytes (%.1f%%)' % ( 18 | filename, bytes_so_far, bytes_total, 100. * bytes_so_far / bytes_total) 19 | 20 | sftp = client.open_sftp() 21 | sftp.chdir('/var/log') 22 | for filename in sorted(sftp.listdir()): 23 | if filename.startswith('messages.'): 24 | callback_for_filename = functools.partial(my_callback, filename) 25 | sftp.get(filename, filename, callback=callback_for_filename) 26 | 27 | client.close() 28 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/16/shell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - shell.py 3 | # A simple shell, so you can try running commands in the absence of 4 | # any special characters (except for whitespace, used for splitting). 5 | 6 | import subprocess 7 | 8 | while True: 9 | args = raw_input('] ').split() 10 | if not args: 11 | pass 12 | elif args == ['exit']: 13 | break 14 | elif args[0] == 'show': 15 | print "Arguments:", args[1:] 16 | else: 17 | subprocess.call(args) 18 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/16/ssh_commands.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - ssh_commands.py 3 | # Running separate commands instead of using a shell 4 | 5 | import paramiko 6 | 7 | class AllowAnythingPolicy(paramiko.MissingHostKeyPolicy): 8 | def missing_host_key(self, client, hostname, key): 9 | return 10 | 11 | client = paramiko.SSHClient() 12 | client.set_missing_host_key_policy(AllowAnythingPolicy()) 13 | client.connect('127.0.0.1', username='test') # password='') 14 | 15 | for command in 'echo "Hello, world!"', 'uname', 'uptime': 16 | stdin, stdout, stderr = client.exec_command(command) 17 | stdin.close() 18 | print repr(stdout.read()) 19 | stdout.close() 20 | stderr.close() 21 | 22 | client.close() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/16/ssh_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - ssh_simple.py 3 | # Using SSH like Telnet: connecting and running two commands 4 | 5 | import paramiko 6 | 7 | class AllowAnythingPolicy(paramiko.MissingHostKeyPolicy): 8 | def missing_host_key(self, client, hostname, key): 9 | return 10 | 11 | client = paramiko.SSHClient() 12 | client.set_missing_host_key_policy(AllowAnythingPolicy()) 13 | client.connect('127.0.0.1', username='test') # password='') 14 | 15 | channel = client.invoke_shell() 16 | stdin = channel.makefile('wb') 17 | stdout = channel.makefile('rb') 18 | 19 | stdin.write('echo Hello, world\rexit\r') 20 | print stdout.read() 21 | 22 | client.close() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/16/ssh_simple.txt: -------------------------------------------------------------------------------- 1 | Linux guinness 2.6.32-24-generic #42-Ubuntu SMP Fri Aug 20 14:24:04 UTC 2 | 2010 i686 GNU/Linux 3 | Ubuntu 10.04.1 LTS 4 | 5 | Welcome to Ubuntu! 6 | * Documentation: https://help.ubuntu.com/ 7 | 8 | Last login: Mon Sep 6 01:02:46 2010 from localhost 9 | echo Hello, world 10 | exit 11 | test@guinness:~$ echo Hello, world 12 | Hello, world 13 | test@guinness:~$ exit 14 | logout 15 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/16/ssh_threads.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - ssh_threads.py 3 | # Running two remote commands simultaneously in different channels 4 | 5 | import threading 6 | import paramiko 7 | 8 | class AllowAnythingPolicy(paramiko.MissingHostKeyPolicy): 9 | def missing_host_key(self, client, hostname, key): 10 | return 11 | 12 | client = paramiko.SSHClient() 13 | client.set_missing_host_key_policy(AllowAnythingPolicy()) 14 | client.connect('127.0.0.1', username='test') # password='') 15 | 16 | def read_until_EOF(fileobj): 17 | s = fileobj.readline() 18 | while s: 19 | print s.strip() 20 | s = fileobj.readline() 21 | 22 | out1 = client.exec_command('echo One;sleep 2;echo Two;sleep 1;echo Three')[1] 23 | out2 = client.exec_command('echo A;sleep 1;echo B;sleep 2;echo C')[1] 24 | thread1 = threading.Thread(target=read_until_EOF, args=(out1,)) 25 | thread2 = threading.Thread(target=read_until_EOF, args=(out2,)) 26 | thread1.start() 27 | thread2.start() 28 | thread1.join() 29 | thread2.join() 30 | 31 | client.close() 32 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/16/telnet_codes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - telnet_codes.py 3 | # How your code might look if you intercept Telnet options yourself 4 | 5 | from telnetlib import Telnet, IAC, DO, DONT, WILL, WONT, SB, SE, TTYPE 6 | 7 | def process_option(tsocket, command, option): 8 | if command == DO and option == TTYPE: 9 | tsocket.sendall(IAC + WILL + TTYPE) 10 | print 'Sending terminal type "mypython"' 11 | tsocket.sendall(IAC + SB + TTYPE + '\0' + 'mypython' + IAC + SE) 12 | elif command in (DO, DONT): 13 | print 'Will not', ord(option) 14 | tsocket.sendall(IAC + WONT + option) 15 | elif command in (WILL, WONT): 16 | print 'Do not', ord(option) 17 | tsocket.sendall(IAC + DONT + option) 18 | 19 | t = Telnet('localhost') 20 | # t.set_debuglevel(1) # uncomment this for debugging messages 21 | 22 | t.set_option_negotiation_callback(process_option) 23 | t.read_until('login:', 5) 24 | t.write('brandon\n') 25 | t.read_until('assword:', 5) # so P can be capitalized or not 26 | t.write('mypass\n') 27 | n, match, previous_text = t.expect([r'Login incorrect', r'\$'], 10) 28 | if n == 0: 29 | print "Username and password failed - giving up" 30 | else: 31 | t.write('exec echo $TERM\n') 32 | print t.read_all() 33 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/16/telnet_login.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - telnet_login.py 3 | # Connect to localhost, watch for a login prompt, and try logging in 4 | 5 | import telnetlib 6 | 7 | t = telnetlib.Telnet('localhost') 8 | # t.set_debuglevel(1) # uncomment this for debugging messages 9 | 10 | t.read_until('login:') 11 | t.write('brandon\n') 12 | t.read_until('assword:') # let "P" be capitalized or not 13 | t.write('mypass\n') 14 | n, match, previous_text = t.expect([r'Login incorrect', r'\$'], 10) 15 | if n == 0: 16 | print "Username and password failed - giving up" 17 | else: 18 | t.write('exec uptime\n') 19 | print t.read_all() # keep reading until the connection closes 20 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/17/advbinarydl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Advanced binary download - Chapter 17 - advbinarydl.py 3 | 4 | import os, sys 5 | from ftplib import FTP 6 | 7 | if os.path.exists('linux-1.0.tar.gz'): 8 | raise IOError('refusing to overwrite your linux-1.0.tar.gz file') 9 | 10 | f = FTP('ftp.kernel.org') 11 | f.login() 12 | 13 | f.cwd('/pub/linux/kernel/v1.0') 14 | f.voidcmd("TYPE I") 15 | 16 | datasock, size = f.ntransfercmd("RETR linux-1.0.tar.gz") 17 | bytes_so_far = 0 18 | fd = open('linux-1.0.tar.gz', 'wb') 19 | 20 | while 1: 21 | buf = datasock.recv(2048) 22 | if not buf: 23 | break 24 | fd.write(buf) 25 | bytes_so_far += len(buf) 26 | print "\rReceived", bytes_so_far, 27 | if size: 28 | print "of %d total bytes (%.1f%%)" % ( 29 | size, 100 * bytes_so_far / float(size)), 30 | else: 31 | print "bytes", 32 | sys.stdout.flush() 33 | 34 | print 35 | fd.close() 36 | datasock.close() 37 | f.voidresp() 38 | f.quit() 39 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/17/advbinaryul.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Advanced binary upload - Chapter 17 - advbinaryul.py 3 | 4 | from ftplib import FTP 5 | import sys, getpass, os.path 6 | 7 | BLOCKSIZE = 8192 # chunk size to read and transmit: 8 kB 8 | 9 | if len(sys.argv) != 5: 10 | print "usage: %s " % ( 11 | sys.argv[0]) 12 | exit(2) 13 | 14 | host, username, localfile, remotedir = sys.argv[1:] 15 | password = getpass.getpass("Enter password for %s on %s: " % \ 16 | (username, host)) 17 | f = FTP(host) 18 | f.login(username, password) 19 | 20 | f.cwd(remotedir) 21 | f.voidcmd("TYPE I") 22 | 23 | fd = open(localfile, 'rb') 24 | datasock, esize = f.ntransfercmd('STOR %s' % os.path.basename(localfile)) 25 | size = os.stat(localfile)[6] 26 | bytes_so_far = 0 27 | 28 | while 1: 29 | buf = fd.read(BLOCKSIZE) 30 | if not buf: 31 | break 32 | datasock.sendall(buf) 33 | bytes_so_far += len(buf) 34 | print "\rSent", bytes_so_far, "of", size, "bytes", \ 35 | "(%.1f%%)\r" % (100 * bytes_so_far / float(size)) 36 | sys.stdout.flush() 37 | 38 | print 39 | datasock.close() 40 | fd.close() 41 | f.voidresp() 42 | f.quit() 43 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/17/asciidl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # ASCII download - Chapter 17 - asciidl.py 3 | # Downloads README from remote and writes it to disk. 4 | 5 | import os 6 | from ftplib import FTP 7 | 8 | if os.path.exists('README'): 9 | raise IOError('refusing to overwrite your README file') 10 | 11 | def writeline(data): 12 | fd.write(data) 13 | fd.write(os.linesep) 14 | 15 | f = FTP('ftp.kernel.org') 16 | f.login() 17 | f.cwd('/pub/linux/kernel') 18 | 19 | fd = open('README', 'w') 20 | f.retrlines('RETR README', writeline) 21 | fd.close() 22 | 23 | f.quit() 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/17/binarydl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Binary upload - Chapter 17 - binarydl.py 3 | 4 | import os 5 | from ftplib import FTP 6 | 7 | if os.path.exists('patch8.gz'): 8 | raise IOError('refusing to overwrite your patch8.gz file') 9 | 10 | f = FTP('ftp.kernel.org') 11 | f.login() 12 | f.cwd('/pub/linux/kernel/v1.0') 13 | 14 | fd = open('patch8.gz', 'wb') 15 | f.retrbinary('RETR patch8.gz', fd.write) 16 | fd.close() 17 | 18 | f.quit() 19 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/17/binaryul.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Binary download - Chapter 17 - binaryul.py 3 | 4 | from ftplib import FTP 5 | import sys, getpass, os.path 6 | 7 | if len(sys.argv) != 5: 8 | print "usage: %s " % ( 9 | sys.argv[0]) 10 | exit(2) 11 | 12 | host, username, localfile, remotedir = sys.argv[1:] 13 | password = getpass.getpass( 14 | "Enter password for %s on %s: " % (username, host)) 15 | 16 | f = FTP(host) 17 | f.login(username, password) 18 | f.cwd(remotedir) 19 | 20 | fd = open(localfile, 'rb') 21 | f.storbinary('STOR %s' % os.path.basename(localfile), fd) 22 | fd.close() 23 | 24 | f.quit() 25 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/17/connect.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Basic connection - Chapter 17 - connect.py 3 | 4 | from ftplib import FTP 5 | 6 | f = FTP('ftp.ibiblio.org') 7 | print "Welcome:", f.getwelcome() 8 | f.login() 9 | 10 | print "Current working directory:", f.pwd() 11 | f.quit() 12 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/17/dir.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # dir() example - Chapter 17 - dir.py 3 | 4 | from ftplib import FTP 5 | 6 | f = FTP('ftp.ibiblio.org') 7 | f.login() 8 | f.cwd('/pub/academic/astronomy/') 9 | entries = [] 10 | f.dir(entries.append) 11 | print "%d entries:" % len(entries) 12 | for entry in entries: 13 | print entry 14 | f.quit() 15 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/17/nlst.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # NLST example - Chapter 17 - nlst.py 3 | 4 | from ftplib import FTP 5 | 6 | f = FTP('ftp.ibiblio.org') 7 | f.login() 8 | f.cwd('/pub/academic/astronomy/') 9 | entries = f.nlst() 10 | entries.sort() 11 | print len(entries), "entries:" 12 | for entry in entries: 13 | print entry 14 | f.quit() 15 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/17/recursedl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Recursive downloader - Chapter 17 - recursedl.py 3 | 4 | import os, sys 5 | from ftplib import FTP, error_perm 6 | 7 | def walk_dir(f, dirpath): 8 | original_dir = f.pwd() 9 | try: 10 | f.cwd(dirpath) 11 | except error_perm: 12 | return # ignore non-directores and ones we cannot enter 13 | print dirpath 14 | names = f.nlst() 15 | for name in names: 16 | walk_dir(f, dirpath + '/' + name) 17 | f.cwd(original_dir) # return to cwd of our caller 18 | 19 | f = FTP('ftp.kernel.org') 20 | f.login() 21 | walk_dir(f, '/pub/linux/kernel/Historic/old-versions') 22 | f.quit() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/18/jsonrpc_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - jsonrpc_client.py 3 | # JSON-RPC client 4 | 5 | from lovely.jsonrpc import proxy 6 | proxy = proxy.ServerProxy('http://localhost:7002') 7 | print proxy.lengths((1,2,3), 27, {'Sirius': -1.46, 'Rigel': 0.12}) 8 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/18/jsonrpc_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - jsonrpc_server.py 3 | # JSON-RPC server 4 | 5 | from wsgiref.simple_server import make_server 6 | import lovely.jsonrpc.dispatcher, lovely.jsonrpc.wsgi 7 | 8 | def lengths(*args): 9 | results = [] 10 | for arg in args: 11 | try: 12 | arglen = len(arg) 13 | except TypeError: 14 | arglen = None 15 | results.append((arglen, arg)) 16 | return results 17 | 18 | dispatcher = lovely.jsonrpc.dispatcher.JSONRPCDispatcher() 19 | dispatcher.register_method(lengths) 20 | app = lovely.jsonrpc.wsgi.WSGIJSONRPCApplication({'': dispatcher}) 21 | server = make_server('localhost', 7002, app) 22 | print "Starting server" 23 | while True: 24 | server.handle_request() 25 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/18/rpyc_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - rpyc_client.py 3 | # RPyC client 4 | 5 | import rpyc 6 | 7 | def noisy(string): 8 | print 'Noisy:', repr(string) 9 | 10 | proxy = rpyc.connect('localhost', 18861, config={'allow_public_attrs': True}) 11 | fileobj = open('testfile.txt') 12 | linecount = proxy.root.line_counter(fileobj, noisy) 13 | print 'The number of lines in the file was', linecount 14 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/18/rpyc_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - rpyc_server.py 3 | # RPyC server 4 | 5 | import rpyc 6 | 7 | class MyService(rpyc.Service): 8 | def exposed_line_counter(self, fileobj, function): 9 | for linenum, line in enumerate(fileobj.readlines()): 10 | function(line) 11 | return linenum + 1 12 | 13 | from rpyc.utils.server import ThreadedServer 14 | t = ThreadedServer(MyService, port = 18861) 15 | t.start() 16 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/18/testfile.txt: -------------------------------------------------------------------------------- 1 | Simple 2 | is 3 | better 4 | than 5 | complex. 6 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/18/xmlrpc_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Foundations of Python Network Programming - Chapter 18 - xmlrpc_client.py 4 | # XML-RPC client 5 | 6 | import xmlrpclib 7 | proxy = xmlrpclib.ServerProxy('http://127.0.0.1:7001') 8 | print proxy.addtogether('x', 'ÿ', 'z') 9 | print proxy.addtogether(20, 30, 4, 1) 10 | print proxy.quadratic(2, -4, 0) 11 | print proxy.quadratic(1, 2, 1) 12 | print proxy.remote_repr((1, 2.0, 'three')) 13 | print proxy.remote_repr([1, 2.0, 'three']) 14 | print proxy.remote_repr({'name': 'Arthur', 'data': {'age': 42, 'sex': 'M'}}) 15 | print proxy.quadratic(1, 0, 1) 16 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/18/xmlrpc_introspect.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - xmlrpc_introspect.py 3 | # XML-RPC client 4 | 5 | import xmlrpclib 6 | proxy = xmlrpclib.ServerProxy('http://127.0.0.1:7001') 7 | 8 | print 'Here are the functions supported by this server:' 9 | for method_name in proxy.system.listMethods(): 10 | 11 | if method_name.startswith('system.'): 12 | continue 13 | 14 | signatures = proxy.system.methodSignature(method_name) 15 | if isinstance(signatures, list) and signatures: 16 | for signature in signatures: 17 | print '%s(%s)' % (method_name, signature) 18 | else: 19 | print '%s(...)' % (method_name,) 20 | 21 | method_help = proxy.system.methodHelp(method_name) 22 | if method_help: 23 | print ' ', method_help 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/18/xmlrpc_multicall.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - xmlrpc_multicall.py 3 | # XML-RPC client performing a multicall 4 | 5 | import xmlrpclib 6 | proxy = xmlrpclib.ServerProxy('http://127.0.0.1:7001') 7 | multicall = xmlrpclib.MultiCall(proxy) 8 | multicall.addtogether('a', 'b', 'c') 9 | multicall.quadratic(2, -4, 0) 10 | multicall.remote_repr([1, 2.0, 'three']) 11 | for answer in multicall(): 12 | print answer 13 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python2/18/xmlrpc_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - xmlrpc_server.py 3 | # XML-RPC server 4 | 5 | import operator, math 6 | from SimpleXMLRPCServer import SimpleXMLRPCServer 7 | 8 | def addtogether(*things): 9 | """Add together everything in the list `things`.""" 10 | return reduce(operator.add, things) 11 | 12 | def quadratic(a, b, c): 13 | """Determine `x` values satisfying: `a` * x*x + `b` * x + c == 0""" 14 | b24ac = math.sqrt(b*b - 4.0*a*c) 15 | return list(set([ (-b-b24ac) / 2.0*a, 16 | (-b+b24ac) / 2.0*a ])) 17 | 18 | def remote_repr(arg): 19 | """Return the `repr()` rendering of the supplied `arg`.""" 20 | return arg 21 | 22 | server = SimpleXMLRPCServer(('127.0.0.1', 7001)) 23 | server.register_introspection_functions() 24 | server.register_multicall_functions() 25 | server.register_function(addtogether) 26 | server.register_function(quadratic) 27 | server.register_function(remote_repr) 28 | print "Server ready" 29 | server.serve_forever() 30 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/01/getname.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 1 - getname.py 3 | 4 | import socket 5 | hostname = 'maps.google.com' 6 | addr = socket.gethostbyname(hostname) 7 | print('The address of', hostname, 'is', addr) 8 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/01/search1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 1 - search1.py 3 | 4 | from googlemaps import GoogleMaps 5 | address = '207 N. Defiance St, Archbold, OH' 6 | print(GoogleMaps().address_to_latlng(address)) 7 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/01/search2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 1 - search2.py 3 | 4 | import json 5 | import urllib, urllib.request, urllib.error, urllib.parse 6 | 7 | params = {'q': '207 N. Defiance St, Archbold, OH', 8 | 'output': 'json', 'oe': 'utf8'} 9 | url = 'http://maps.google.com/maps/geo?' + urllib.parse.urlencode(params) 10 | 11 | rawreply = urllib.request.urlopen(url).read() 12 | 13 | reply = json.loads(rawreply.decode('utf-8')) 14 | print(reply['Placemark'][0]['Point']['coordinates'][:-1]) 15 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/01/search3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 1 - search3.py 3 | 4 | import http.client 5 | import json 6 | 7 | path = ('/maps/geo?q=207+N.+Defiance+St%2C+Archbold%2C+OH' 8 | '&output=json&oe=utf8') 9 | 10 | connection = http.client.HTTPConnection('maps.google.com') 11 | connection.request('GET', path) 12 | rawreply = connection.getresponse().read() 13 | 14 | reply = json.loads(rawreply.decode('utf-8')) 15 | print(reply['Placemark'][0]['Point']['coordinates'][:-1]) 16 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/01/search4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 1 - search4.py 3 | 4 | import socket 5 | sock = socket.socket() 6 | sock.connect(('maps.google.com', 80)) 7 | sock.sendall( 8 | b'GET /maps/geo?q=207+N.+Defiance+St%2C+Archbold%2C+OH' 9 | b'&output=json&oe=utf8&sensor=false HTTP/1.1\r\n' 10 | b'Host: maps.google.com:80\r\n' 11 | b'User-Agent: search4.py\r\n' 12 | b'Connection: close\r\n' 13 | b'\r\n') 14 | rawreply = sock.recv(4096) 15 | print(rawreply.decode('utf-8')) 16 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/01/search4.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Content-Type: text/javascript; charset=UTF-8 3 | Vary: Accept-Language 4 | Date: Wed, 21 Jul 2010 16:10:38 GMT 5 | Server: mafe 6 | Cache-Control: private, x-gzip-ok="" 7 | X-XSS-Protection: 1; mode=block 8 | Connection: close 9 | 10 | { 11 | "name": "207 N. Defiance St, Archbold, OH", 12 | "Status": { 13 | "code": 200, 14 | "request": "geocode" 15 | }, 16 | "Placemark": [ { 17 | ... 18 | "Point": { 19 | "coordinates": [ -84.3063479, 41.5228242, 0 ] 20 | } 21 | } ] 22 | } 23 | 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/02/big_sender.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 2 - big_sender.py 3 | # Send a big UDP packet to our server. 4 | 5 | import IN, socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 7 | 8 | MAX = 65535 9 | PORT = 1060 10 | 11 | if len(sys.argv) != 2: 12 | print('usage: big_sender.py host', file=sys.stderr) 13 | sys.exit(2) 14 | 15 | hostname = sys.argv[1] 16 | s.connect((hostname, PORT)) 17 | s.setsockopt(socket.IPPROTO_IP, IN.IP_MTU_DISCOVER, IN.IP_PMTUDISC_DO) 18 | try: 19 | s.send(b'#' * 65000) 20 | except socket.error: 21 | print('The message did not make it') 22 | option = getattr(IN, 'IP_MTU', 14) # constant taken from 23 | print('MTU:', s.getsockopt(socket.IPPROTO_IP, option)) 24 | else: 25 | print('The big message was sent! Your network supports really big packets!') 26 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/02/udp_broadcast.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 2 - udp_broadcast.py 3 | # UDP client and server for broadcast messages on a local LAN 4 | 5 | import socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 7 | s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 8 | 9 | MAX = 65535 10 | PORT = 1060 11 | 12 | if 2 <= len(sys.argv) <= 3 and sys.argv[1] == 'server': 13 | s.bind(('', PORT)) 14 | print('Listening for broadcasts at', s.getsockname()) 15 | while True: 16 | data, address = s.recvfrom(MAX) 17 | print('The client at %r says: %r' % (address, data)) 18 | 19 | elif len(sys.argv) == 3 and sys.argv[1] == 'client': 20 | network = sys.argv[2] 21 | s.sendto(b'Broadcast message!', (network, PORT)) 22 | 23 | else: 24 | print('usage: udp_broadcast.py server', file=sys.stderr) 25 | print(' or: udp_broadcast.py client ', file=sys.stderr) 26 | sys.exit(2) 27 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/02/udp_local.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 2 - udp_local.py 3 | # UDP client and server on localhost 4 | 5 | import socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 7 | 8 | MAX = 65535 9 | PORT = 1060 10 | 11 | if sys.argv[1:] == ['server']: 12 | s.bind(('127.0.0.1', PORT)) 13 | print('Listening at', s.getsockname()) 14 | while True: 15 | data, address = s.recvfrom(MAX) 16 | print('The client at', address, 'says', repr(data)) 17 | message = 'Your data was %d bytes' % len(data) 18 | s.sendto(message.encode('ascii'), address) 19 | 20 | elif sys.argv[1:] == ['client']: 21 | print('Address before sending:', s.getsockname()) 22 | s.sendto(b'This is my message', ('127.0.0.1', PORT)) 23 | print('Address after sending', s.getsockname()) 24 | data, address = s.recvfrom(MAX) # overly promiscuous - see Chapter 2 25 | print('The server', address, 'says', data) 26 | 27 | else: 28 | print('usage: udp_local.py server|client', file=sys.stderr) 29 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/02/udp_remote.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 2 - udp_remote.py 3 | # UDP client and server for talking over the network 4 | 5 | import random, socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 7 | 8 | MAX = 65535 9 | PORT = 1060 10 | 11 | if 2 <= len(sys.argv) <= 3 and sys.argv[1] == 'server': 12 | interface = sys.argv[2] if len(sys.argv) > 2 else '' 13 | s.bind((interface, PORT)) 14 | print('Listening at', s.getsockname()) 15 | while True: 16 | data, address = s.recvfrom(MAX) 17 | if random.randint(0, 1): 18 | print('The client at', address, 'says:', repr(data)) 19 | message = 'Your data was %d bytes' % len(data) 20 | s.sendto(message.encode('ascii'), address) 21 | else: 22 | print('Pretending to drop packet from', address) 23 | 24 | elif len(sys.argv) == 3 and sys.argv[1] == 'client': 25 | hostname = sys.argv[2] 26 | s.connect((hostname, PORT)) 27 | print('Client socket name is', s.getsockname()) 28 | delay = 0.1 29 | while True: 30 | s.send(b'This is another message') 31 | print('Waiting up to', delay, 'seconds for a reply') 32 | s.settimeout(delay) 33 | try: 34 | data = s.recv(MAX) 35 | except socket.timeout: 36 | delay *= 2 # wait even longer for the next request 37 | if delay > 2.0: 38 | raise RuntimeError('I think the server is down') 39 | else: 40 | break # we are done, and can stop looping 41 | 42 | print('The server says', repr(data)) 43 | 44 | else: 45 | print('usage: udp_remote.py server [ ]', file=sys.stderr) 46 | print(' or: udp_remote.py client ', file=sys.stderr) 47 | sys.exit(2) 48 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/03/tcp_deadlock.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 3 - tcp_deadlock.py 3 | # TCP client and server that leave too much data waiting 4 | 5 | import socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | 8 | HOST = '127.0.0.1' 9 | PORT = 1060 10 | 11 | if sys.argv[1:] == ['server']: 12 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 13 | s.bind((HOST, PORT)) 14 | s.listen(1) 15 | while True: 16 | print('Listening at', s.getsockname()) 17 | sc, sockname = s.accept() 18 | print('Processing up to 1024 bytes at a time from', sockname) 19 | n = 0 20 | while True: 21 | data = sc.recv(1024) 22 | if not data: 23 | break 24 | output = data.decode('ascii').upper().encode('ascii') 25 | sc.sendall(output) # send it back uppercase 26 | n += len(data) 27 | print('\r%d bytes processed so far' % (n,), end=' ') 28 | sys.stdout.flush() 29 | print() 30 | sc.close() 31 | print('Completed processing') 32 | 33 | elif len(sys.argv) == 3 and sys.argv[1] == 'client' and sys.argv[2].isdigit(): 34 | 35 | bytecount = (int(sys.argv[2]) + 15) // 16 * 16 # round up to // 16 36 | message = b'capitalize this!' # 16-byte message to repeat over and over 37 | 38 | print('Sending', bytecount, 'bytes of data, in chunks of 16 bytes') 39 | s.connect((HOST, PORT)) 40 | 41 | sent = 0 42 | while sent < bytecount: 43 | s.sendall(message) 44 | sent += len(message) 45 | print('\r%d bytes sent' % (sent,), end=' ') 46 | sys.stdout.flush() 47 | 48 | print() 49 | s.shutdown(socket.SHUT_WR) 50 | 51 | print('Receiving all the data the server sends back') 52 | 53 | received = 0 54 | while True: 55 | data = s.recv(42) 56 | if not received: 57 | print('The first data received says', repr(data)) 58 | received += len(data) 59 | if not data: 60 | break 61 | print('\r%d bytes received' % (received,), end=' ') 62 | 63 | print() 64 | s.close() 65 | 66 | else: 67 | print('usage: tcp_deadlock.py server | client ', file=sys.stderr) 68 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/03/tcp_sixteen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 3 - tcp_sixteen.py 3 | # Simple TCP client and server that send and receive 16 octets 4 | 5 | import socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | 8 | HOST = sys.argv.pop() if len(sys.argv) == 3 else '127.0.0.1' 9 | PORT = 1060 10 | 11 | def recvall(sock, length): 12 | data = b'' 13 | while len(data) < length: 14 | more = sock.recv(length - len(data)) 15 | if not more: 16 | raise EOFError('socket closed %d bytes into a %d-byte message' 17 | % (len(data), length)) 18 | data += more 19 | return data 20 | 21 | if sys.argv[1:] == ['server']: 22 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 23 | s.bind((HOST, PORT)) 24 | s.listen(1) 25 | while True: 26 | print('Listening at', s.getsockname()) 27 | sc, sockname = s.accept() 28 | print('We have accepted a connection from', sockname) 29 | print('Socket connects', sc.getsockname(), 'and', sc.getpeername()) 30 | message = recvall(sc, 16) 31 | print('The incoming sixteen-octet message says', repr(message)) 32 | sc.sendall(b'Farewell, client') 33 | sc.close() 34 | print('Reply sent, socket closed') 35 | 36 | elif sys.argv[1:] == ['client']: 37 | s.connect((HOST, PORT)) 38 | print('Client has been assigned socket name', s.getsockname()) 39 | s.sendall(b'Hi there, server') 40 | reply = recvall(s, 16) 41 | print('The server said', repr(reply)) 42 | s.close() 43 | 44 | else: 45 | print('usage: tcp_local.py server|client [host]', file=sys.stderr) 46 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/04/dns_basic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 4 - dns_basic.py 3 | # Basic DNS query 4 | 5 | import sys, DNS 6 | 7 | if len(sys.argv) != 2: 8 | print('usage: dns_basic.py ', file=sys.stderr) 9 | sys.exit(2) 10 | 11 | DNS.DiscoverNameServers() 12 | request = DNS.Request() 13 | for qt in DNS.Type.A, DNS.Type.AAAA, DNS.Type.CNAME, DNS.Type.MX, DNS.Type.NS: 14 | reply = request.req(name=sys.argv[1], qtype=qt) 15 | for answer in reply.answers: 16 | print(answer['name'], answer['classstr'], answer['typename'], \ 17 | repr(answer['data'])) 18 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/04/dns_mx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 4 - dns_mx.py 3 | # Looking up a mail domain - the part of an email address after the `@` 4 | 5 | import sys, DNS 6 | 7 | if len(sys.argv) != 2: 8 | print('usage: dns_basic.py ', file=sys.stderr) 9 | sys.exit(2) 10 | 11 | def resolve_hostname(hostname, indent=0): 12 | """Print an A or AAAA record for `hostname`; follow CNAMEs if necessary.""" 13 | indent = indent + 4 14 | istr = ' ' * indent 15 | request = DNS.Request() 16 | reply = request.req(name=sys.argv[1], qtype=DNS.Type.A) 17 | if reply.answers: 18 | for answer in reply.answers: 19 | print(istr, 'Hostname', hostname, '= A', answer['data']) 20 | return 21 | reply = request.req(name=sys.argv[1], qtype=DNS.Type.AAAA) 22 | if reply.answers: 23 | for answer in reply.answers: 24 | print(istr, 'Hostname', hostname, '= AAAA', answer['data']) 25 | return 26 | reply = request.req(name=sys.argv[1], qtype=DNS.Type.CNAME) 27 | if reply.answers: 28 | cname = reply.answers[0]['data'] 29 | print(istr, 'Hostname', hostname, 'is an alias for', cname) 30 | resolve_hostname(cname, indent) 31 | return 32 | print(istr, 'ERROR: no records for', hostname) 33 | 34 | def resolve_email_domain(domain): 35 | """Print mail server IP addresses for an email address @ `domain`.""" 36 | request = DNS.Request() 37 | reply = request.req(name=sys.argv[1], qtype=DNS.Type.MX) 38 | if reply.answers: 39 | print('The domain %r has explicit MX records!' % (domain,)) 40 | print('Try the servers in this order:') 41 | datalist = [ answer['data'] for answer in reply.answers ] 42 | datalist.sort() # lower-priority integers go first 43 | for data in datalist: 44 | priority = data[0] 45 | hostname = data[1] 46 | print('Priority:', priority, ' Hostname:', hostname) 47 | resolve_hostname(hostname) 48 | else: 49 | print('Drat, this domain has no explicit MX records') 50 | print('We will have to try resolving it as an A, AAAA, or CNAME') 51 | resolve_hostname(domain) 52 | 53 | DNS.DiscoverNameServers() 54 | resolve_email_domain(sys.argv[1]) 55 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/04/forward_reverse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 4 - forward_reverse.py 3 | # Checking whether a host name works both forwards and backwards. 4 | 5 | import socket, sys 6 | 7 | if len(sys.argv) != 2: 8 | print('usage: forward_reverse.py ', file=sys.stderr) 9 | sys.exit(2) 10 | 11 | hostname = sys.argv[1] 12 | 13 | try: 14 | infolist = socket.getaddrinfo( 15 | hostname, 0, 0, socket.SOCK_STREAM, 0, 16 | socket.AI_ADDRCONFIG | socket.AI_V4MAPPED | socket.AI_CANONNAME, 17 | ) 18 | except socket.gaierror as e: 19 | print('Forward name service failure:', e.args[1]) 20 | sys.exit(1) 21 | 22 | info = infolist[0] # choose the first, if there are several addresses 23 | canonical = info[3] 24 | socketname = info[4] 25 | ip = socketname[0] 26 | 27 | if not canonical: 28 | print('WARNING! The IP address', ip, 'has no reverse name') 29 | sys.exit(1) 30 | 31 | print(hostname, 'has IP address', ip) 32 | print(ip, 'has the canonical hostname', canonical) 33 | 34 | # Lowercase for case-insensitive comparison, and chop off hostnames. 35 | 36 | forward = hostname.lower().split('.') 37 | reverse = canonical.lower().split('.') 38 | 39 | if forward == reverse: 40 | print('Wow, the names agree completely!') 41 | sys.exit(0) 42 | 43 | # Truncate the domain names, which now look like ['www', mit', 'edu'], 44 | # to the same length and compare. Failing that, be willing to try a 45 | # compare with the first element (the hostname?) lopped off if both of 46 | # they are the same length. 47 | 48 | length = min(len(forward), len(reverse)) 49 | if (forward[-length:] == reverse[-length:] 50 | or (len(forward) == len(reverse) 51 | and forward[-length+1:] == reverse[-length+1:] 52 | and len(forward[-2]) > 2)): # avoid thinking '.co.uk' means a match! 53 | print('The forward and reverse names have a lot in common') 54 | else: 55 | print('WARNING! The reverse name belongs to a different organization') 56 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/04/www_ping.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 4 - www_ping.py 3 | # Find the WWW service of an arbitrary host using getaddrinfo(). 4 | 5 | import socket, sys 6 | 7 | if len(sys.argv) != 2: 8 | print('usage: www_ping.py ', file=sys.stderr) 9 | sys.exit(2) 10 | 11 | hostname_or_ip = sys.argv[1] 12 | 13 | try: 14 | infolist = socket.getaddrinfo( 15 | hostname_or_ip, 'www', 0, socket.SOCK_STREAM, 0, 16 | socket.AI_ADDRCONFIG | socket.AI_V4MAPPED | socket.AI_CANONNAME, 17 | ) 18 | except socket.gaierror as e: 19 | print('Name service failure:', e.args[1]) 20 | sys.exit(1) 21 | 22 | info = infolist[0] # per standard recommendation, try the first one 23 | socket_args = info[0:3] 24 | address = info[4] 25 | s = socket.socket(*socket_args) 26 | try: 27 | s.connect(address) 28 | except socket.error as e: 29 | print('Network failure:', e.args[1]) 30 | else: 31 | print('Success: host', info[3], 'is listening on port 80') 32 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/05/blocks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 5 - blocks.py 3 | # Sending data one block at a time. 4 | 5 | import socket, struct, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | 8 | HOST = sys.argv.pop() if len(sys.argv) == 3 else '127.0.0.1' 9 | PORT = 1060 10 | format = struct.Struct('!I') # for messages up to 2**32 - 1 in length 11 | 12 | def recvall(sock, length): 13 | data = b'' 14 | while len(data) < length: 15 | more = sock.recv(length - len(data)) 16 | if not more: 17 | raise EOFError('socket closed %d bytes into a %d-byte message' 18 | % (len(data), length)) 19 | data += more 20 | return data 21 | 22 | def get(sock): 23 | lendata = recvall(sock, format.size) 24 | (length,) = format.unpack(lendata) 25 | return recvall(sock, length) 26 | 27 | def put(sock, message): 28 | sock.send(format.pack(len(message)) + message) 29 | 30 | if sys.argv[1:] == ['server']: 31 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 32 | s.bind((HOST, PORT)) 33 | s.listen(1) 34 | print('Listening at', s.getsockname()) 35 | sc, sockname = s.accept() 36 | print('Accepted connection from', sockname) 37 | sc.shutdown(socket.SHUT_WR) 38 | while True: 39 | message = get(sc) 40 | if not message: 41 | break 42 | print('Message says:', repr(message)) 43 | sc.close() 44 | s.close() 45 | 46 | elif sys.argv[1:] == ['client']: 47 | s.connect((HOST, PORT)) 48 | s.shutdown(socket.SHUT_RD) 49 | put(s, b'Beautiful is better than ugly.') 50 | put(s, b'Explicit is better than implicit.') 51 | put(s, b'Simple is better than complex.') 52 | put(s, b'') 53 | s.close() 54 | 55 | else: 56 | print('usage: streamer.py server|client [host]', file=sys.stderr) 57 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/05/streamer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 5 - streamer.py 3 | # Client that sends data then closes the socket, not expecting a reply. 4 | 5 | import socket, sys 6 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | 8 | HOST = sys.argv.pop() if len(sys.argv) == 3 else '127.0.0.1' 9 | PORT = 1060 10 | 11 | if sys.argv[1:] == ['server']: 12 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 13 | s.bind((HOST, PORT)) 14 | s.listen(1) 15 | print('Listening at', s.getsockname()) 16 | sc, sockname = s.accept() 17 | print('Accepted connection from', sockname) 18 | sc.shutdown(socket.SHUT_WR) 19 | message = b'' 20 | while True: 21 | more = sc.recv(8192) # arbitrary value of 8k 22 | if not more: # socket has closed when recv() returns '' 23 | break 24 | message += more 25 | print('Done receiving the message; it says:') 26 | print(message.decode('ascii')) 27 | sc.close() 28 | s.close() 29 | 30 | elif sys.argv[1:] == ['client']: 31 | s.connect((HOST, PORT)) 32 | s.shutdown(socket.SHUT_RD) 33 | s.sendall(b'Beautiful is better than ugly.\n') 34 | s.sendall(b'Explicit is better than implicit.\n') 35 | s.sendall(b'Simple is better than complex.\n') 36 | s.close() 37 | 38 | else: 39 | print('usage: streamer.py server|client [host]', file=sys.stderr) 40 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/06/sslclient.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 6 - sslclient.py 3 | # Using SSL to protect a socket in Python 2.6 or later 4 | 5 | import os, socket, ssl, sys 6 | 7 | try: 8 | script_name, hostname = sys.argv 9 | except ValueError: 10 | print('usage: sslclient.py ', file=sys.stderr) 11 | sys.exit(2) 12 | 13 | # First we connect, as usual, with a socket. 14 | 15 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 16 | sock.connect((hostname, 443)) 17 | 18 | # Next, we turn the socket over to the SSL library! 19 | 20 | ca_certs_path = os.path.join(os.path.dirname(script_name), 'certfiles.crt') 21 | sslsock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_SSLv3, 22 | cert_reqs=ssl.CERT_REQUIRED, ca_certs=ca_certs_path) 23 | 24 | # Does the certificate that the server proffered *really* match the 25 | # hostname to which we are trying to connect? We need to check. 26 | 27 | try: 28 | ssl.match_hostname(sslsock.getpeercert(), hostname) 29 | except ssl.CertificateError as ce: 30 | print('Certificate error:', str(ce)) 31 | sys.exit(1) 32 | 33 | # From here on, our `sslsock` works like a normal socket. We can, for 34 | # example, make an impromptu HTTP call. 35 | 36 | sslsock.sendall(b'GET / HTTP/1.0\r\n\r\n') 37 | result = sslsock.makefile().read() # quick way to read until EOF 38 | sslsock.close() 39 | print('The document https://%s/ is %d bytes long' % (hostname, len(result))) 40 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/Bench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for SERVER in server_*.py 4 | do 5 | echo '===========' $SERVER '===========' 6 | python $SERVER '' & 7 | ssh kenaniah <<'EOF' 8 | cd ~/apress 9 | source v/bin/activate 10 | cd fopnp/source/07 11 | LAUNCELOT_SERVER=192.168.5.130 fl-run-bench launcelot_tests.py TestLauncelot.test_dialog > OUT 2>&1 12 | EOF 13 | kill %1 14 | wait %1 2>/dev/null 15 | kill $(lsof | grep 'TCP.*1060' | awk '{print$2}') 16 | scp kenaniah:apress/fopnp/source/07/bench.xml ~/apress/bench 17 | (cd ~/apress/bench; fl-build-report --html bench.xml; rm -rf $SERVER; mv test_* $SERVER) 18 | done 19 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/Test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for SERVER in server_*.py 4 | do 5 | echo '===========' $SERVER '===========' 6 | python $SERVER localhost & 7 | sleep 1 8 | python client.py localhost 1060 9 | kill %1 10 | wait %1 2>/dev/null || true 11 | kill $(lsof | grep 'TCP.*1060' | awk '{print$2}') 12 | done 13 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/TestLancelot.conf: -------------------------------------------------------------------------------- 1 | # TestLauncelot.conf 2 | [main] 3 | title=Load Test For Chapter 7 4 | description=From the Foundations of Python Network Programming 5 | url=http://localhost:1060/ 6 | 7 | [ftest] 8 | log_path = ftest.log 9 | result_path = ftest.xml 10 | sleep_time_min = 0 11 | sleep_time_max = 0 12 | 13 | [bench] 14 | log_to = file 15 | log_path = bench.log 16 | result_path = bench.xml 17 | cycles = 1:2:3:5:7:10:13:16:20 18 | duration = 8 19 | startup_delay = 0.1 20 | sleep_time = 0.01 21 | cycle_time = 10 22 | sleep_time_min = 0 23 | sleep_time_max = 0 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - client.py 3 | # Simple Lancelot client that asks three questions then disconnects. 4 | 5 | import socket, sys, lancelot 6 | 7 | def client(hostname, port): 8 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 9 | s.connect((hostname, port)) 10 | s.sendall(lancelot.qa[0][0]) 11 | answer1 = lancelot.recv_until(s, b'.') # answers end with '.' 12 | s.sendall(lancelot.qa[1][0]) 13 | answer2 = lancelot.recv_until(s, b'.') 14 | s.sendall(lancelot.qa[2][0]) 15 | answer3 = lancelot.recv_until(s, b'.') 16 | s.close() 17 | print(answer1) 18 | print(answer2) 19 | print(answer3) 20 | 21 | if __name__ == '__main__': 22 | if not 2 <= len(sys.argv) <= 3: 23 | print('usage: client.py hostname [port]', file=sys.stderr) 24 | sys.exit(2) 25 | port = int(sys.argv[2]) if len(sys.argv) > 2 else lancelot.PORT 26 | client(sys.argv[1], port) 27 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/lancelot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - lancelot.py 3 | # Constants and routines for supporting a certain network conversation. 4 | 5 | import socket, sys 6 | 7 | PORT = 1060 8 | qa = ((b'What is your name?', b'My name is Sir Lancelot of Camelot.'), 9 | (b'What is your quest?', b'To seek the Holy Grail.'), 10 | (b'What is your favorite color?', b'Blue.')) 11 | qadict = dict(qa) 12 | 13 | def recv_until(sock, suffix): 14 | message = b'' 15 | while not message.endswith(suffix): 16 | data = sock.recv(4096) 17 | if not data: 18 | raise EOFError('socket closed before we saw %r' % suffix) 19 | message += data 20 | return message 21 | 22 | def setup(): 23 | if len(sys.argv) != 2: 24 | print('usage: %s interface' % sys.argv[0], file=sys.stderr) 25 | exit(2) 26 | interface = sys.argv[1] 27 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 28 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 29 | sock.bind((interface, PORT)) 30 | sock.listen(128) 31 | print('Ready and listening at %r port %d' % (interface, PORT)) 32 | return sock 33 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/lancelot_tests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - lancelot_tests.py 3 | # Test suite that can be run against the Lancelot servers. 4 | 5 | from funkload.FunkLoadTestCase import FunkLoadTestCase 6 | import socket, os, unittest, lancelot 7 | 8 | SERVER_HOST = os.environ.get('LAUNCELOT_SERVER', 'localhost') 9 | 10 | class TestLancelot(FunkLoadTestCase): 11 | def test_dialog(self): 12 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 13 | sock.connect((SERVER_HOST, lancelot.PORT)) 14 | for i in range(10): 15 | question, answer = lancelot.qa[i % len(launcelot.qa)] 16 | sock.sendall(question) 17 | reply = lancelot.recv_until(sock, '.') 18 | self.assertEqual(reply, answer) 19 | sock.close() 20 | 21 | if __name__ == '__main__': 22 | unittest.main() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/my_trace.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - my_trace.py 3 | # Command-line tool for tracing a single function in a program. 4 | 5 | import linecache, sys, time 6 | 7 | def make_tracer(funcname): 8 | def mytrace(frame, event, arg): 9 | if frame.f_code.co_name == funcname: 10 | if event == 'line': 11 | _events.append((time.time(), frame.f_code.co_filename, 12 | frame.f_lineno)) 13 | return mytrace 14 | return mytrace 15 | 16 | if __name__ == '__main__': 17 | _events = [] 18 | if len(sys.argv) < 3: 19 | print('usage: my_trace.py funcname other_script.py ...', file=sys.stderr) 20 | sys.exit(2) 21 | sys.settrace(make_tracer(sys.argv[1])) 22 | del sys.argv[0:2] # show the script only its own name and arguments 23 | try: 24 | exec(compile(open(sys.argv[0]).read(), sys.argv[0], 'exec')) 25 | finally: 26 | for t, filename, lineno in _events: 27 | s = linecache.getline(filename, lineno) 28 | sys.stdout.write('%9.6f %s' % (t % 60.0, s)) 29 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/server_SocketServer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_SocketServer.py 3 | # Answering Lancelot requests with a SocketServer. 4 | 5 | from socketserver import ThreadingMixIn, TCPServer, BaseRequestHandler 6 | import lancelot, server_simple, socket 7 | 8 | class MyHandler(BaseRequestHandler): 9 | def handle(self): 10 | server_simple.handle_client(self.request) 11 | 12 | class MyServer(ThreadingMixIn, TCPServer): 13 | allow_reuse_address = 1 14 | # address_family = socket.AF_INET6 # if you need IPv6 15 | 16 | server = MyServer(('', lancelot.PORT), MyHandler) 17 | server.serve_forever() 18 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/server_async.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_async.py 3 | # Using the ancient "asyncore" framework to write a server. 4 | 5 | import asyncore, asynchat, lancelot 6 | 7 | class LancelotRequestHandler(asynchat.async_chat): 8 | 9 | def __init__(self, sock): 10 | asynchat.async_chat.__init__(self, sock) 11 | self.set_terminator(b'?') 12 | self.data = b'' 13 | 14 | def collect_incoming_data(self, more_data): 15 | self.data += more_data 16 | 17 | def found_terminator(self): 18 | answer = dict(lancelot.qa)[self.data + b'?'] 19 | self.push(answer) 20 | self.initiate_send() 21 | self.data = b'' 22 | 23 | class LancelotServer(asyncore.dispatcher): 24 | def handle_accept(self): 25 | sock, address = self.accept() 26 | LancelotRequestHandler(sock) 27 | 28 | sock = lancelot.setup() 29 | ls = LancelotServer(sock) 30 | ls.accepting = True # since we already called listen() 31 | asyncore.loop() 32 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/server_multi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_multi.py 3 | # Using multiple threads or processes to serve several clients in parallel. 4 | 5 | import sys, time, lancelot 6 | from multiprocessing import Process 7 | from server_simple import server_loop 8 | from threading import Thread 9 | 10 | WORKER_CLASSES = {'thread': Thread, 'process': Process} 11 | WORKER_MAX = 10 12 | 13 | def start_worker(Worker, listen_sock): 14 | worker = Worker(target=server_loop, args=(listen_sock,)) 15 | worker.daemon = True # exit when the main process does 16 | worker.start() 17 | return worker 18 | 19 | if __name__ == '__main__': 20 | if len(sys.argv) != 3 or sys.argv[2] not in WORKER_CLASSES: 21 | print('usage: server_multi.py interface thread|process', file=sys.stderr) 22 | sys.exit(2) 23 | Worker = WORKER_CLASSES[sys.argv.pop()] # setup() wants len(argv)==2 24 | 25 | # Every worker will accept() forever on the same listening socket. 26 | 27 | listen_sock = lancelot.setup() 28 | workers = [] 29 | for i in range(WORKER_MAX): 30 | workers.append(start_worker(Worker, listen_sock)) 31 | 32 | # Check every two seconds for dead workers, and replace them. 33 | 34 | while True: 35 | time.sleep(2) 36 | for worker in workers: 37 | if not worker.is_alive(): 38 | print(worker.name, "died; starting replacement worker") 39 | workers.remove(worker) 40 | workers.append(start_worker(Worker, listen_sock)) 41 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/server_poll.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_poll.py 3 | # An event-driven approach to serving several clients with poll(). 4 | 5 | import lancelot 6 | import select 7 | 8 | listen_sock = lancelot.setup() 9 | sockets = { listen_sock.fileno(): listen_sock } 10 | requests = {} 11 | responses = {} 12 | 13 | poll = select.poll() 14 | poll.register(listen_sock, select.POLLIN) 15 | 16 | while True: 17 | for fd, event in poll.poll(): 18 | sock = sockets[fd] 19 | 20 | # Removed closed sockets from our list. 21 | if event & (select.POLLHUP | select.POLLERR | select.POLLNVAL): 22 | poll.unregister(fd) 23 | del sockets[fd] 24 | requests.pop(sock, None) 25 | responses.pop(sock, None) 26 | 27 | # Accept connections from new sockets. 28 | elif sock is listen_sock: 29 | newsock, sockname = sock.accept() 30 | newsock.setblocking(False) 31 | fd = newsock.fileno() 32 | sockets[fd] = newsock 33 | poll.register(fd, select.POLLIN) 34 | requests[newsock] = b'' 35 | 36 | # Collect incoming data until it forms a question. 37 | elif event & select.POLLIN: 38 | data = sock.recv(4096) 39 | if not data: # end-of-file 40 | sock.close() # makes POLLNVAL happen next time 41 | continue 42 | requests[sock] += data 43 | if b'?' in requests[sock]: 44 | question = requests.pop(sock) 45 | answer = dict(lancelot.qa)[question] 46 | poll.modify(sock, select.POLLOUT) 47 | responses[sock] = answer 48 | 49 | # Send out pieces of each reply until they are all sent. 50 | elif event & select.POLLOUT: 51 | response = responses.pop(sock) 52 | n = sock.send(response) 53 | if n < len(response): 54 | responses[sock] = response[n:] 55 | else: 56 | poll.modify(sock, select.POLLIN) 57 | requests[sock] = b'' 58 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/server_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_simple.py 3 | # Simple server that only serves one client at a time; others have to wait. 4 | 5 | import lancelot 6 | 7 | def handle_client(client_sock): 8 | try: 9 | while True: 10 | question = lancelot.recv_until(client_sock, b'?') 11 | answer = lancelot.qadict[question] 12 | client_sock.sendall(answer) 13 | except EOFError: 14 | client_sock.close() 15 | 16 | def server_loop(listen_sock): 17 | while True: 18 | client_sock, sockname = listen_sock.accept() 19 | handle_client(client_sock) 20 | 21 | if __name__ == '__main__': 22 | listen_sock = lancelot.setup() 23 | server_loop(listen_sock) 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/07/server_twisted.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 7 - server_twisted.py 3 | # Using Twisted to serve Lancelot users. 4 | 5 | from twisted.internet.protocol import Protocol, ServerFactory 6 | from twisted.internet import reactor 7 | import lancelot 8 | 9 | class Lancelot(Protocol): 10 | def connectionMade(self): 11 | self.question = '' 12 | 13 | def dataReceived(self, data): 14 | self.question += data 15 | if self.question.endswith('?'): 16 | self.transport.write(dict(lancelot.qa)[self.question]) 17 | self.question = '' 18 | 19 | factory = ServerFactory() 20 | factory.protocol = Lancelot 21 | reactor.listenTCP(1060, factory) 22 | reactor.run() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/08/hashing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 8 - hashing.py 3 | # Hashes are a great way to divide work. 4 | 5 | import hashlib 6 | 7 | def alpha_shard(word): 8 | """Do a poor job of assigning data to servers by using first letters.""" 9 | if word[0] in 'abcdef': 10 | return 'server0' 11 | elif word[0] in 'ghijklm': 12 | return 'server1' 13 | elif word[0] in 'nopqrs': 14 | return 'server2' 15 | else: 16 | return 'server3' 17 | 18 | def hash_shard(word): 19 | """Do a great job of assigning data to servers using a hash value.""" 20 | return 'server%d' % (hash(word) % 4) 21 | 22 | def md5_shard(word): 23 | """Do a great job of assigning data to servers using a hash value.""" 24 | data = word.encode('utf-8') 25 | return 'server%d' % (hashlib.md5(data).digest()[-1] % 4) 26 | 27 | words = open('/usr/share/dict/words').read().split() 28 | 29 | for function in alpha_shard, hash_shard, md5_shard: 30 | d = {'server0': 0, 'server1': 0, 'server2': 0, 'server3': 0} 31 | for word in words: 32 | d[function(word.lower())] += 1 33 | print(function.__name__[:-6], d) 34 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/08/queuecrazy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 8 - queuecrazy.py 3 | # Small application that uses several different message queues 4 | 5 | import random, threading, time, zmq 6 | zcontext = zmq.Context() 7 | 8 | def fountain(url): 9 | """Produces a steady stream of words.""" 10 | zsock = zcontext.socket(zmq.PUSH) 11 | zsock.bind(url) 12 | words = [ w for w in dir(__builtins__) if w.islower() ] 13 | while True: 14 | zsock.send(random.choice(words)) 15 | time.sleep(0.4) 16 | 17 | def responder(url, function): 18 | """Performs a string operation on each word received.""" 19 | zsock = zcontext.socket(zmq.REP) 20 | zsock.bind(url) 21 | while True: 22 | word = zsock.recv() 23 | zsock.send(function(word)) # send the modified word back 24 | 25 | def processor(n, fountain_url, responder_urls): 26 | """Read words as they are produced; get them processed; print them.""" 27 | zpullsock = zcontext.socket(zmq.PULL) 28 | zpullsock.connect(fountain_url) 29 | 30 | zreqsock = zcontext.socket(zmq.REQ) 31 | for url in responder_urls: 32 | zreqsock.connect(url) 33 | 34 | while True: 35 | word = zpullsock.recv() 36 | zreqsock.send(word) 37 | print(n, zreqsock.recv()) 38 | 39 | def start_thread(function, *args): 40 | thread = threading.Thread(target=function, args=args) 41 | thread.daemon = True # so you can easily Control-C the whole program 42 | thread.start() 43 | 44 | start_thread(fountain, 'tcp://127.0.0.1:6700') 45 | start_thread(responder, 'tcp://127.0.0.1:6701', str.upper) 46 | start_thread(responder, 'tcp://127.0.0.1:6702', str.lower) 47 | for n in range(3): 48 | start_thread(processor, n + 1, 'tcp://127.0.0.1:6700', 49 | ['tcp://127.0.0.1:6701', 'tcp://127.0.0.1:6702']) 50 | time.sleep(30) 51 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/08/squares.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 8 - squares.py 3 | # Using memcached to cache expensive results. 4 | 5 | import memcache, random, time, timeit 6 | mc = memcache.Client(['127.0.0.1:11211']) 7 | 8 | def compute_square(n): 9 | value = mc.get('sq:%d' % n) 10 | if value is None: 11 | time.sleep(0.001) # pretend that computing a square is expensive 12 | value = n * n 13 | mc.set('sq:%d' % n, value) 14 | return value 15 | 16 | def make_request(): 17 | compute_square(random.randint(0, 5000)) 18 | 19 | print('Ten successive runs:', end=' ') 20 | for i in range(1, 11): 21 | print('%.2fs' % timeit.timeit(make_request, number=2000), end=' ') 22 | print() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/09/get_rfc2616.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 9 - verbose_handler.py 3 | # Example use of the verbose HTTP request handler. 4 | 5 | import urllib, urllib.request, urllib.error, urllib.parse 6 | from verbose_http import VerboseHTTPHandler 7 | opener = urllib.request.build_opener(VerboseHTTPHandler) 8 | opener.open('http://www.ietf.org/rfc/rfc2616.txt') 9 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/09/verbose_http.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 9 - verbose_handler.py 3 | # HTTP request handler for urllib2 that prints requests and responses. 4 | 5 | import io, http.client, urllib.request, urllib.error, urllib.parse 6 | 7 | class VerboseHTTPResponse(http.client.HTTPResponse): 8 | def _read_status(self): 9 | s = self.fp.read() 10 | print('-' * 20, 'Response', '-' * 20) 11 | print(s.split(b'\r\n\r\n')[0].decode('ascii')) 12 | self.fp = io.BytesIO(s) 13 | return http.client.HTTPResponse._read_status(self) 14 | 15 | class VerboseHTTPConnection(http.client.HTTPConnection): 16 | response_class = VerboseHTTPResponse 17 | def send(self, s): 18 | print('-' * 50) 19 | print(s.strip().decode('ascii')) 20 | http.client.HTTPConnection.send(self, s) 21 | 22 | class VerboseHTTPHandler(urllib.request.HTTPHandler): 23 | def http_open(self, req): 24 | return self.do_open(VerboseHTTPConnection, req) 25 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/10/excerpt.html: -------------------------------------------------------------------------------- 1 | 2 | 7-Day Forecast for Latitude 33.45°N and Longitude 112.07°W (Elev. 1132 ft) 3 | ... 4 |
5 | 6 | 10 | 11 | 12 |
7 | Phoenix, Phoenix Sky Harbor International Airport
8 | Last Update on 29 Oct 7:51 MST

9 |
13 | 14 | 15 | 19 |
16 | 17 | A Few Clouds
18 |
71°F
(22°C)
20 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
Humidity:30 %
Wind Speed:SE 5 MPH
26 |
Barometer:30.05 in (1015.90 mb)
Dewpoint:38°F (3°C)
Visibility:10.00 Miles
More Local Wx: 3 Day History:
40 | ... 41 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/10/fetch_mechanize.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 10 - fetch_mechanize.py 3 | # Submitting a form and retrieving a page with mechanize 4 | 5 | import mechanize 6 | br = mechanize.Browser() 7 | br.open('http://www.weather.gov/') 8 | br.select_form(predicate=lambda form: 'zipcity' in form.action) 9 | br['inputstring'] = 'Phoenix, AZ' 10 | response = br.submit() 11 | content = response.read() 12 | open('phoenix.html', 'w').write(content) 13 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/10/fetch_urllib2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 10 - fetch_urllib2.py 3 | # Submitting a form and retrieving a page with urllib2 4 | 5 | import urllib, urllib.request, urllib.error, urllib.parse 6 | data = urllib.parse.urlencode({'inputstring': 'Phoenix, AZ'}).encode('ascii') 7 | info = urllib.request.urlopen('http://forecast.weather.gov/zipcity.php', data) 8 | content = info.read() 9 | open('phoenix.html', 'wb').write(content) 10 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/10/weather.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 10 - weather.py 3 | # Fetch the weather forecast from the National Weather Service. 4 | 5 | import sys, urllib, urllib.request, urllib.error, urllib.parse 6 | import lxml.etree 7 | from lxml.cssselect import CSSSelector 8 | # from BeautifulSoup import BeautifulSoup 9 | 10 | if len(sys.argv) < 2: 11 | print('usage: weather.py CITY, STATE', file=sys.stderr) 12 | exit(2) 13 | 14 | data = urllib.parse.urlencode({'inputstring': ' '.join(sys.argv[1:])}) 15 | data = data.encode('ascii') 16 | info = urllib.request.urlopen('http://forecast.weather.gov/zipcity.php', data) 17 | content = info.read() 18 | 19 | # Solution #1 20 | parser = lxml.etree.HTMLParser(encoding='utf-8') 21 | tree = lxml.etree.fromstring(content, parser) 22 | big = CSSSelector('td.big')(tree)[0] 23 | if big.find('font') is not None: 24 | big = big.find('font') 25 | print('Condition:', big.text.strip()) 26 | print('Temperature:', big.findall('br')[1].tail) 27 | tr = tree.xpath('.//td[b="Humidity"]')[0].getparent() 28 | print('Humidity:', tr.findall('td')[1].text) 29 | print() 30 | 31 | # Solution #2 32 | # soup = BeautifulSoup(content) # doctest: +SKIP 33 | # big = soup.find('td', 'big') 34 | # if big.font is not None: 35 | # big = big.font 36 | # print('Condition:', big.contents[0].string.strip()) 37 | # temp = big.contents[3].string or big.contents[4].string # can be either 38 | # print('Temperature:', temp.replace('°', ' ')) 39 | # tr = soup.find('b', text='Humidity').parent.parent.parent 40 | # print('Humidity:', tr('td')[1].string) 41 | # print() 42 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/11/bottle_app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 11 - bottle_app.py 3 | # A simple web application built using the Bottle micro-framework. 4 | 5 | import base64, bottle 6 | bottle.debug(True) 7 | app = bottle.Bottle() 8 | 9 | @app.route('/encode') 10 | @bottle.view('bottle_template.html') 11 | def encode(): 12 | mystring = bottle.request.GET.get('mystring').encode('utf-8') 13 | if mystring is None: 14 | bottle.abort(400, 'This form requires a "mystring" parameter') 15 | return dict(mystring=mystring, myb=base64.b64encode(mystring)) 16 | 17 | @app.route('/') 18 | @bottle.view('bottle_template.html') 19 | def index(): 20 | return dict(mystring=None) 21 | 22 | bottle.run(app=app, host='localhost', port=8080) 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/11/bottle_template.html: -------------------------------------------------------------------------------- 1 | %#!/usr/bin/env python 2 | %# Foundations of Python Network Programming - Chapter 11 - bottle_template.py 3 | %# The page template that goes with bottle_app.py. 4 | %# 5 | bottle_app.py 6 | 7 | %if mystring is None: 8 | Welcome! Enter a string: 9 |
10 | %else: 11 | {{mystring}} base64 encoded is: {{myb}}
12 | Return to the home page 13 | %end 14 | 15 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/11/wsgi_app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 11 - wsgi_app.py 3 | # A simple web application built directly against the low-level WSGI spec. 4 | 5 | import cgi, base64 6 | from wsgiref.simple_server import make_server 7 | 8 | def page(content, *args): 9 | yield b'wsgi_app.py' 10 | yield (content % args).encode('utf-8') 11 | yield b'' 12 | 13 | def simple_app(environ, start_response): 14 | html_headers = [('Content-Type', 'text/html; charset=UTF-8')] 15 | gohome = '
Return to the home page' 16 | q = cgi.parse_qs(environ['QUERY_STRING']) 17 | 18 | if environ['PATH_INFO'] == '/': 19 | 20 | if environ['REQUEST_METHOD'] != 'GET' or environ['QUERY_STRING']: 21 | start_response('400 Bad Request', [('Content-Type', 'text/plain')]) 22 | return [b'Error: the front page is not a form'] 23 | 24 | start_response('200 OK', html_headers) 25 | return page('Welcome! Enter a string:
' 26 | '
') 27 | 28 | elif environ['PATH_INFO'] == '/encode': 29 | 30 | if environ['REQUEST_METHOD'] != 'GET': 31 | start_response('400 Bad Request', [('Content-Type', 'text/plain')]) 32 | return [b'Error: this form does not support POST parameters'] 33 | 34 | if 'mystring' not in q or not q['mystring'][0]: 35 | start_response('400 Bad Request', [('Content-Type', 'text/plain')]) 36 | return [b'Error: this form requires a "mystring" parameter'] 37 | 38 | my = q['mystring'][0] 39 | my64 = base64.b64encode(my.encode('utf-8')).decode('ascii') 40 | start_response('200 OK', html_headers) 41 | return page('%s base64 encoded is: %s' + gohome, 42 | cgi.escape(repr(my)), cgi.escape(my64)) 43 | 44 | else: 45 | start_response('404 Not Found', [('Content-Type', 'text/plain')]) 46 | return [b'That URL is not valid'] 47 | 48 | print('Listening on localhost:8000') 49 | make_server('localhost', 8000, simple_app).serve_forever() 50 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/message.txt: -------------------------------------------------------------------------------- 1 | To: recipient@example.com 2 | From: Test Sender 3 | Subject: Test Message, Chapter 12 4 | Date: Mon, 02 Aug 2010 10:05:55 -0400 5 | Message-ID: <20100802140555.11734.89229@guinness.ten22> 6 | 7 | Hello, 8 | 9 | This is a test message from Chapter 12. I hope you enjoy it! 10 | 11 | -- Anonymous 12 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/mime_decode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_decode.py 3 | # This program requires Python 2.2.2 or above 4 | 5 | import sys, email 6 | counter = 0 7 | parts = [] 8 | 9 | def printmsg(msg, level = 0): 10 | global counter 11 | l = "| " * level 12 | if msg.is_multipart(): 13 | print(l + "Found multipart:") 14 | for item in msg.get_payload(): 15 | printmsg(item, level + 1) 16 | else: 17 | disp = ['%d. Decodable part' % (counter + 1)] 18 | if 'content-type' in msg: 19 | disp.append(msg['content-type']) 20 | if 'content-disposition' in msg: 21 | disp.append(msg['content-disposition']) 22 | print(l + ", ".join(disp)) 23 | counter += 1 24 | parts.append(msg) 25 | 26 | inputfd = open(sys.argv[1]) 27 | msg = email.message_from_file(inputfd) 28 | printmsg(msg) 29 | 30 | while 1: 31 | print("Select part number to decode or q to quit: ") 32 | part = sys.stdin.readline().strip() 33 | if part == 'q': 34 | sys.exit(0) 35 | try: 36 | part = int(part) 37 | msg = parts[part - 1] 38 | except: 39 | print("Invalid selection.") 40 | continue 41 | 42 | print("Select file to write to:") 43 | filename = sys.stdin.readline().strip() 44 | try: 45 | fd = open(filename, 'wb') 46 | except: 47 | print("Invalid filename.") 48 | continue 49 | 50 | fd.write(msg.get_payload(decode = 1)) 51 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/mime_gen_alt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_gen_alt.py 3 | 4 | from email.mime.base import MIMEBase 5 | from email.mime.multipart import MIMEMultipart 6 | from email.mime.text import MIMEText 7 | from email import utils, encoders 8 | 9 | def alternative(data, contenttype): 10 | maintype, subtype = contenttype.split('/') 11 | if maintype == 'text': 12 | retval = MIMEText(data, _subtype=subtype) 13 | else: 14 | retval = MIMEBase(maintype, subtype) 15 | retval.set_payload(data) 16 | encoders.encode_base64(retval) 17 | return retval 18 | 19 | messagetext = """Hello, 20 | 21 | This is a *great* test message from Chapter 12. I hope you enjoy it! 22 | 23 | -- Anonymous""" 24 | messagehtml = """Hello,

25 | This is a great test message from Chapter 12. I hope you enjoy 26 | it!

27 | -- Anonymous""" 28 | 29 | 30 | msg = MIMEMultipart('alternative') 31 | msg['To'] = 'recipient@example.com' 32 | msg['From'] = 'Test Sender ' 33 | msg['Subject'] = 'Test Message, Chapter 12' 34 | msg['Date'] = utils.formatdate(localtime = 1) 35 | msg['Message-ID'] = utils.make_msgid() 36 | 37 | msg.attach(alternative(messagetext, 'text/plain')) 38 | msg.attach(alternative(messagehtml, 'text/html')) 39 | print(msg.as_string()) 40 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/mime_gen_basic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_gen_basic.py 3 | 4 | from email.mime.base import MIMEBase 5 | from email.mime.multipart import MIMEMultipart 6 | from email.mime.text import MIMEText 7 | from email import utils, encoders 8 | import mimetypes, sys 9 | 10 | def attachment(filename): 11 | fd = open(filename, 'rb') 12 | mimetype, mimeencoding = mimetypes.guess_type(filename) 13 | if mimeencoding or (mimetype is None): 14 | mimetype = 'application/octet-stream' 15 | maintype, subtype = mimetype.split('/') 16 | if maintype == 'text': 17 | retval = MIMEText(fd.read(), _subtype=subtype) 18 | else: 19 | retval = MIMEBase(maintype, subtype) 20 | retval.set_payload(fd.read()) 21 | encoders.encode_base64(retval) 22 | retval.add_header('Content-Disposition', 'attachment', 23 | filename = filename) 24 | fd.close() 25 | return retval 26 | 27 | message = """Hello, 28 | 29 | This is a test message from Chapter 12. I hope you enjoy it! 30 | 31 | -- Anonymous""" 32 | 33 | msg = MIMEMultipart() 34 | msg['To'] = 'recipient@example.com' 35 | msg['From'] = 'Test Sender ' 36 | msg['Subject'] = 'Test Message, Chapter 12' 37 | msg['Date'] = utils.formatdate(localtime = 1) 38 | msg['Message-ID'] = utils.make_msgid() 39 | 40 | body = MIMEText(message, _subtype='plain') 41 | msg.attach(body) 42 | for filename in sys.argv[1:]: 43 | msg.attach(attachment(filename)) 44 | print(msg.as_string()) 45 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/mime_gen_both.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_gen_both.py 3 | 4 | from email.mime.text import MIMEText 5 | from email.mime.multipart import MIMEMultipart 6 | from email.mime.base import MIMEBase 7 | from email import utils, encoders 8 | import mimetypes, sys 9 | 10 | def genpart(data, contenttype): 11 | maintype, subtype = contenttype.split('/') 12 | if maintype == 'text': 13 | retval = MIMEText(data, _subtype=subtype) 14 | else: 15 | retval = MIMEBase(maintype, subtype) 16 | retval.set_payload(data) 17 | encoders.encode_base64(retval) 18 | return retval 19 | 20 | 21 | def attachment(filename): 22 | fd = open(filename, 'rb') 23 | mimetype, mimeencoding = mimetypes.guess_type(filename) 24 | if mimeencoding or (mimetype is None): 25 | mimetype = 'application/octet-stream' 26 | retval = genpart(fd.read(), mimetype) 27 | retval.add_header('Content-Disposition', 'attachment', 28 | filename = filename) 29 | fd.close() 30 | return retval 31 | 32 | messagetext = """Hello, 33 | 34 | This is a *great* test message from Chapter 12. I hope you enjoy it! 35 | 36 | -- Anonymous""" 37 | messagehtml = """Hello,

38 | This is a great test message from Chapter 12. I hope you enjoy 39 | it!

40 | -- Anonymous""" 41 | 42 | msg = MIMEMultipart() 43 | msg['To'] = 'recipient@example.com' 44 | msg['From'] = 'Test Sender ' 45 | msg['Subject'] = 'Test Message, Chapter 12' 46 | msg['Date'] = utils.formatdate(localtime = 1) 47 | msg['Message-ID'] = utils.make_msgid() 48 | 49 | body = MIMEMultipart('alternative') 50 | body.attach(genpart(messagetext, 'text/plain')) 51 | body.attach(genpart(messagehtml, 'text/html')) 52 | msg.attach(body) 53 | 54 | for filename in sys.argv[1:]: 55 | msg.attach(attachment(filename)) 56 | print(msg.as_string()) 57 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/mime_headers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_headers.py 3 | 4 | from email.mime.text import MIMEText 5 | from email.header import Header 6 | 7 | message = """Hello, 8 | 9 | This is a test message from Chapter 12. I hope you enjoy it! 10 | 11 | -- Anonymous""" 12 | 13 | msg = MIMEText(message) 14 | msg['To'] = 'recipient@example.com' 15 | fromhdr = Header() 16 | fromhdr.append('Michael Müller', 'iso-8859-1') # 'utf-8' is even more general 17 | fromhdr.append('') 18 | msg['From'] = fromhdr 19 | msg['Subject'] = 'Test Message, Chapter 12' 20 | 21 | print(msg.as_string()) 22 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/mime_parse_headers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_parse_headers.py 3 | 4 | import sys, email 5 | from email.header import decode_header 6 | 7 | msg = email.message_from_file(sys.stdin) 8 | for header, raw in list(msg.items()): 9 | parts = decode_header(raw) 10 | value = '' 11 | for data, charset in parts: 12 | if isinstance(data, str): 13 | value += data 14 | else: 15 | value += data.decode(charset or 'ascii') 16 | print('{0}: {1}'.format(header, value)) 17 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/mime_structure.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - mime_structure.py 3 | # This program requires Python 2.2.2 or above 4 | 5 | import sys, email 6 | 7 | def printmsg(msg, level = 0): 8 | prefix = "| " * level 9 | prefix2 = prefix + "|" 10 | print(prefix + "+ Message Headers:") 11 | for header, value in list(msg.items()): 12 | print(prefix2, header + ":", value) 13 | if msg.is_multipart(): 14 | for item in msg.get_payload(): 15 | printmsg(item, level + 1) 16 | 17 | msg = email.message_from_file(sys.stdin) 18 | printmsg(msg) 19 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/test.txt: -------------------------------------------------------------------------------- 1 | This is a test 2 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/test.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/foundations-of-python-network-programming/f9e2f1f9fd424da3880c94258134ab3e9fa54969/foundations-of-python-network-programming/python3/12/test.txt.gz -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/trad_gen_newhdrs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - trad_gen_newhdrs.py 3 | # Traditional Message Generation with Date and Message-ID 4 | # This program requires Python 2.5 or above 5 | 6 | import email.utils 7 | from email.message import Message 8 | 9 | message = """Hello, 10 | 11 | This is a test message from Chapter 12. I hope you enjoy it! 12 | 13 | -- Anonymous""" 14 | 15 | msg = Message() 16 | msg['To'] = 'recipient@example.com' 17 | msg['From'] = 'Test Sender ' 18 | msg['Subject'] = 'Test Message, Chapter 12' 19 | msg['Date'] = email.utils.formatdate(localtime = 1) 20 | msg['Message-ID'] = email.utils.make_msgid() 21 | msg.set_payload(message) 22 | 23 | print(msg.as_string()) 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/trad_gen_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - trad_gen_simple.py 3 | # Traditional Message Generation, Simple 4 | # This program requires Python 2.5 or above 5 | 6 | from email.message import Message 7 | text = """Hello, 8 | 9 | This is a test message from Chapter 12. I hope you enjoy it! 10 | 11 | -- Anonymous""" 12 | 13 | msg = Message() 14 | msg['To'] = 'recipient@example.com' 15 | msg['From'] = 'Test Sender ' 16 | msg['Subject'] = 'Test Message, Chapter 12' 17 | msg.set_payload(text) 18 | 19 | print(msg.as_string()) 20 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/12/trad_parse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 12 - trad_parse.py 3 | # Traditional Message Parsing 4 | # This program requires Python 2.5 or above 5 | 6 | import email 7 | 8 | banner = '-' * 48 9 | popular_headers = ('From', 'To', 'Subject', 'Date') 10 | msg = email.message_from_file(open('message.txt')) 11 | headers = sorted(msg.keys()) 12 | 13 | print(banner) 14 | for header in headers: 15 | if header not in popular_headers: 16 | print(header + ':', msg[header]) 17 | print(banner) 18 | for header in headers: 19 | if header in popular_headers: 20 | print(header + ':', msg[header]) 21 | 22 | print(banner) 23 | if msg.is_multipart(): 24 | print("This program cannot handle MIME multipart messages.") 25 | else: 26 | print(msg.get_payload()) 27 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/13/debug.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SMTP transmission with debugging - Chapter 13 - debug.py 3 | 4 | import sys, smtplib, socket 5 | 6 | if len(sys.argv) < 4: 7 | print("usage: %s server fromaddr toaddr [toaddr...]" % sys.argv[0]) 8 | sys.exit(2) 9 | 10 | server, fromaddr, toaddrs = sys.argv[1], sys.argv[2], sys.argv[3:] 11 | 12 | message = """To: %s 13 | From: %s 14 | Subject: Test Message from simple.py 15 | 16 | Hello, 17 | 18 | This is a test message sent to you from the debug.py program 19 | in Foundations of Python Network Programming. 20 | """ % (', '.join(toaddrs), fromaddr) 21 | 22 | try: 23 | s = smtplib.SMTP(server) 24 | s.set_debuglevel(1) 25 | s.sendmail(fromaddr, toaddrs, message) 26 | except (socket.gaierror, socket.error, socket.herror, 27 | smtplib.SMTPException) as e: 28 | print(" *** Your message may not have been sent!") 29 | print(e) 30 | sys.exit(1) 31 | else: 32 | print("Message successfully sent to %d recipient(s)" % len(toaddrs)) 33 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/13/ehlo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SMTP transmission with manual EHLO - Chapter 13 - ehlo.py 3 | 4 | import sys, smtplib, socket 5 | 6 | if len(sys.argv) < 4: 7 | print("usage: %s server fromaddr toaddr [toaddr...]" % sys.argv[0]) 8 | sys.exit(2) 9 | 10 | server, fromaddr, toaddrs = sys.argv[1], sys.argv[2], sys.argv[3:] 11 | 12 | message = """To: %s 13 | From: %s 14 | Subject: Test Message from simple.py 15 | 16 | Hello, 17 | 18 | This is a test message sent to you from the ehlo.py program 19 | in Foundations of Python Network Programming. 20 | """ % (', '.join(toaddrs), fromaddr) 21 | 22 | try: 23 | s = smtplib.SMTP(server) 24 | code = s.ehlo()[0] 25 | uses_esmtp = (200 <= code <= 299) 26 | if not uses_esmtp: 27 | code = s.helo()[0] 28 | if not (200 <= code <= 299): 29 | print("Remote server refused HELO; code:", code) 30 | sys.exit(1) 31 | 32 | if uses_esmtp and s.has_extn('size'): 33 | print("Maximum message size is", s.esmtp_features['size']) 34 | if len(message) > int(s.esmtp_features['size']): 35 | print("Message too large; aborting.") 36 | sys.exit(1) 37 | 38 | s.sendmail(fromaddr, toaddrs, message) 39 | 40 | except (socket.gaierror, socket.error, socket.herror, 41 | smtplib.SMTPException) as e: 42 | print(" *** Your message may not have been sent!") 43 | print(e) 44 | sys.exit(1) 45 | else: 46 | print("Message successfully sent to %d recipient(s)" % len(toaddrs)) 47 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/13/login.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SMTP transmission with authentication - Chapter 13 - login.py 3 | 4 | import sys, smtplib, socket 5 | from getpass import getpass 6 | 7 | if len(sys.argv) < 4: 8 | print("Syntax: %s server fromaddr toaddr [toaddr...]" % sys.argv[0]) 9 | sys.exit(2) 10 | 11 | server, fromaddr, toaddrs = sys.argv[1], sys.argv[2], sys.argv[3:] 12 | 13 | message = """To: %s 14 | From: %s 15 | Subject: Test Message from simple.py 16 | 17 | Hello, 18 | 19 | This is a test message sent to you from the login.py program 20 | in Foundations of Python Network Programming. 21 | """ % (', '.join(toaddrs), fromaddr) 22 | 23 | print("Enter username: ") 24 | username = sys.stdin.readline().strip() 25 | password = getpass("Enter password: ") 26 | 27 | try: 28 | s = smtplib.SMTP(server) 29 | try: 30 | s.login(username, password) 31 | except smtplib.SMTPException as e: 32 | print("Authentication failed:", e) 33 | sys.exit(1) 34 | s.sendmail(fromaddr, toaddrs, message) 35 | except (socket.gaierror, socket.error, socket.herror, 36 | smtplib.SMTPException) as e: 37 | print(" *** Your message may not have been sent!") 38 | print(e) 39 | sys.exit(1) 40 | else: 41 | print("Message successfully sent to %d recipient(s)" % len(toaddrs)) 42 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/13/simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Basic SMTP transmission - Chapter 13 - simple.py 3 | 4 | import sys, smtplib 5 | 6 | if len(sys.argv) < 4: 7 | print("usage: %s server fromaddr toaddr [toaddr...]" % sys.argv[0]) 8 | sys.exit(2) 9 | 10 | server, fromaddr, toaddrs = sys.argv[1], sys.argv[2], sys.argv[3:] 11 | 12 | message = """To: %s 13 | From: %s 14 | Subject: Test Message from simple.py 15 | 16 | Hello, 17 | 18 | This is a test message sent to you from the simple.py program 19 | in Foundations of Python Network Programming. 20 | """ % (', '.join(toaddrs), fromaddr) 21 | 22 | s = smtplib.SMTP(server) 23 | s.sendmail(fromaddr, toaddrs, message) 24 | 25 | print("Message successfully sent to %d recipient(s)" % len(toaddrs)) 26 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/13/tls.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SMTP transmission with TLS - Chapter 13 - tls.py 3 | 4 | import sys, smtplib, socket 5 | 6 | if len(sys.argv) < 4: 7 | print("Syntax: %s server fromaddr toaddr [toaddr...]" % sys.argv[0]) 8 | sys.exit(2) 9 | 10 | server, fromaddr, toaddrs = sys.argv[1], sys.argv[2], sys.argv[3:] 11 | 12 | message = """To: %s 13 | From: %s 14 | Subject: Test Message from simple.py 15 | 16 | Hello, 17 | 18 | This is a test message sent to you from the tls.py program 19 | in Foundations of Python Network Programming. 20 | """ % (', '.join(toaddrs), fromaddr) 21 | 22 | try: 23 | s = smtplib.SMTP(server) 24 | code = s.ehlo()[0] 25 | uses_esmtp = (200 <= code <= 299) 26 | if not uses_esmtp: 27 | code = s.helo()[0] 28 | if not (200 <= code <= 299): 29 | print("Remove server refused HELO; code:", code) 30 | sys.exit(1) 31 | 32 | if uses_esmtp and s.has_extn('starttls'): 33 | print("Negotiating TLS....") 34 | s.starttls() 35 | code = s.ehlo()[0] 36 | if not (200 <= code <= 299): 37 | print("Couldn't EHLO after STARTTLS") 38 | sys.exit(5) 39 | print("Using TLS connection.") 40 | else: 41 | print("Server does not support TLS; using normal connection.") 42 | s.sendmail(fromaddr, toaddrs, message) 43 | 44 | except (socket.gaierror, socket.error, socket.herror, 45 | smtplib.SMTPException) as e: 46 | print(" *** Your message may not have been sent!") 47 | print(e) 48 | sys.exit(1) 49 | else: 50 | print("Message successfully sent to %d recipient(s)" % len(toaddrs)) 51 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/14/download-and-delete.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # POP mailbox downloader with deletion - Chapter 14 3 | # download-and-delete.py 4 | 5 | import email, getpass, poplib, sys 6 | 7 | if len(sys.argv) != 3: 8 | print('usage: %s hostname user' % sys.argv[0]) 9 | exit(2) 10 | 11 | hostname, user = sys.argv[1:] 12 | passwd = getpass.getpass() 13 | 14 | p = poplib.POP3_SSL(hostname) 15 | try: 16 | p.user(user) 17 | p.pass_(passwd) 18 | except poplib.error_proto as e: 19 | print("Login failed:", e) 20 | else: 21 | response, listings, octets = p.list() 22 | for listing in listings: 23 | number, size = listing.decode('ascii').split() 24 | print('Message', number, '(size is', size, 'bytes):') 25 | print() 26 | response, lines, octets = p.top(number, 0) 27 | document = '\n'.join( line.decode('ascii') for line in lines ) 28 | message = email.message_from_string(document) 29 | for header in 'From', 'To', 'Subject', 'Date': 30 | if header in message: 31 | print(header + ':', message[header]) 32 | print() 33 | print('Read this message [ny]?') 34 | answer = input() 35 | if answer.lower().startswith('y'): 36 | response, lines, octets = p.retr(number) 37 | document = '\n'.join( line.decode('ascii') for line in lines ) 38 | message = email.message_from_string(document) 39 | print('-' * 72) 40 | for part in message.walk(): 41 | if part.get_content_type() == 'text/plain': 42 | print(part.get_payload()) 43 | print('-' * 72) 44 | print() 45 | print('Delete this message [ny]?') 46 | answer = input() 47 | if answer.lower().startswith('y'): 48 | p.dele(number) 49 | print('Deleted.') 50 | finally: 51 | p.quit() 52 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/14/mailbox.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # POP mailbox scanning - Chapter 14 - mailbox.py 3 | 4 | import getpass, poplib, sys 5 | 6 | if len(sys.argv) != 3: 7 | print('usage: %s hostname user' % sys.argv[0]) 8 | exit(2) 9 | 10 | hostname, user = sys.argv[1:] 11 | passwd = getpass.getpass() 12 | 13 | p = poplib.POP3_SSL(hostname) 14 | try: 15 | p.user(user) 16 | p.pass_(passwd) 17 | except poplib.error_proto as e: 18 | print("Login failed:", e) 19 | else: 20 | response, listings, octet_count = p.list() 21 | for listing in listings: 22 | number, size = listing.decode('ascii').split() 23 | print("Message %s has %s bytes" % (number, size)) 24 | finally: 25 | p.quit() 26 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/14/popconn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # POP connection and authentication - Chapter 14 - popconn.py 3 | 4 | import getpass, poplib, sys 5 | 6 | if len(sys.argv) != 3: 7 | print('usage: %s hostname user' % sys.argv[0]) 8 | exit(2) 9 | 10 | hostname, user = sys.argv[1:] 11 | passwd = getpass.getpass() 12 | 13 | p = poplib.POP3_SSL(hostname) # or "POP3" if SSL is not supported 14 | try: 15 | p.user(user) 16 | p.pass_(passwd) 17 | except poplib.error_proto as e: 18 | print("Login failed:", e) 19 | else: 20 | status = p.stat() 21 | print("You have %d messages totaling %d bytes" % status) 22 | finally: 23 | p.quit() 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/15/folder_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 15 - folder_info.py 3 | # Opening an IMAP connection with IMAPClient and listing folder information. 4 | 5 | import getpass, sys 6 | from imapclient import IMAPClient 7 | 8 | try: 9 | hostname, username = sys.argv[1:] 10 | except ValueError: 11 | print('usage: %s hostname username' % sys.argv[0]) 12 | sys.exit(2) 13 | 14 | c = IMAPClient(hostname, ssl=True) 15 | try: 16 | c.login(username, getpass.getpass()) 17 | except c.Error as e: 18 | print('Could not log in:', e) 19 | sys.exit(1) 20 | else: 21 | select_dict = c.select_folder('INBOX', readonly=True) 22 | for k, v in list(select_dict.items()): 23 | print('%s: %r' % (k, v)) 24 | c.logout() 25 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/15/mailbox_summary.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 15 - mailbox_summary.py 3 | # Opening an IMAP connection with IMAPClient and retrieving mailbox messages. 4 | 5 | import email, getpass, sys 6 | from imapclient import IMAPClient 7 | 8 | try: 9 | hostname, username, foldername = sys.argv[1:] 10 | except ValueError: 11 | print('usage: %s hostname username folder' % sys.argv[0]) 12 | sys.exit(2) 13 | 14 | c = IMAPClient(hostname, ssl=True) 15 | try: 16 | c.login(username, getpass.getpass()) 17 | except c.Error as e: 18 | print('Could not log in:', e) 19 | sys.exit(1) 20 | 21 | c.select_folder(foldername, readonly=True) 22 | msgdict = c.fetch('1:*', ['BODY.PEEK[]']) 23 | for message_id, message in list(msgdict.items()): 24 | e = email.message_from_string(message['BODY[]']) 25 | print(message_id, e['From']) 26 | payload = e.get_payload() 27 | if isinstance(payload, list): 28 | part_content_types = [ part.get_content_type() for part in payload ] 29 | print(' Parts:', ' '.join(part_content_types)) 30 | else: 31 | print(' ', ' '.join(payload[:60].split()), '...') 32 | 33 | c.logout() 34 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/15/open_imap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 15 - open_imap.py 3 | # Opening an IMAP connection with the powerful IMAPClient 4 | 5 | import getpass, sys 6 | from imapclient import IMAPClient 7 | 8 | try: 9 | hostname, username = sys.argv[1:] 10 | except ValueError: 11 | print('usage: %s hostname username' % sys.argv[0]) 12 | sys.exit(2) 13 | 14 | c = IMAPClient(hostname, ssl=True) 15 | try: 16 | c.login(username, getpass.getpass()) 17 | except c.Error as e: 18 | print('Could not log in:', e) 19 | sys.exit(1) 20 | 21 | print('Capabilities:', c.capabilities()) 22 | print('Listing mailboxes:') 23 | data = c.list_folders() 24 | for flags, delimiter, folder_name in data: 25 | print(' %-30s%s %s' % (' '.join(flags), delimiter, folder_name)) 26 | c.logout() 27 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/15/open_imap.txt: -------------------------------------------------------------------------------- 1 | Capabilities: ('IMAP4REV1', 'UNSELECT', 'IDLE', 'NAMESPACE', 'QUOTA', 'XLIST', 'CHILDREN', 'XYZZY', 'SASL-IR', 'AUTH=XOAUTH') 2 | Listing mailboxes: 3 | \HasNoChildren / INBOX 4 | \HasNoChildren / Personal 5 | \HasNoChildren / Receipts 6 | \HasNoChildren / Travel 7 | \HasNoChildren / Work 8 | \Noselect \HasChildren / [Gmail] 9 | \HasChildren \HasNoChildren / [Gmail]/All Mail 10 | \HasNoChildren / [Gmail]/Drafts 11 | \HasChildren \HasNoChildren / [Gmail]/Sent Mail 12 | \HasNoChildren / [Gmail]/Spam 13 | \HasNoChildren / [Gmail]/Starred 14 | \HasChildren \HasNoChildren / [Gmail]/Trash 15 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/15/open_imaplib.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 15 - open_imaplib.py 3 | # Opening an IMAP connection with the pitiful Python Standard Library 4 | 5 | import getpass, imaplib, sys 6 | 7 | try: 8 | hostname, username = sys.argv[1:] 9 | except ValueError: 10 | print('usage: %s hostname username' % sys.argv[0]) 11 | sys.exit(2) 12 | 13 | m = imaplib.IMAP4_SSL(hostname) 14 | m.login(username, getpass.getpass()) 15 | print('Capabilities:', m.capabilities) 16 | print('Listing mailboxes ') 17 | status, data = m.list() 18 | print('Status:', repr(status)) 19 | print('Data:') 20 | for datum in data: 21 | print(repr(datum)) 22 | m.logout() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/15/open_imaplib.txt: -------------------------------------------------------------------------------- 1 | Capabilities: ('IMAP4REV1', 'UNSELECT', 'IDLE', 'NAMESPACE', 'QUOTA', 2 | 'XLIST', 'CHILDREN', 'XYZZY', 'SASL-IR', 'AUTH=XOAUTH') 3 | Listing mailboxes 4 | Status: 'OK' 5 | Data: 6 | '(\\HasNoChildren) "/" "INBOX"' 7 | '(\\HasNoChildren) "/" "Personal"' 8 | '(\\HasNoChildren) "/" "Receipts"' 9 | '(\\HasNoChildren) "/" "Travel"' 10 | '(\\HasNoChildren) "/" "Work"' 11 | '(\\Noselect \\HasChildren) "/" "[Gmail]"' 12 | '(\\HasChildren \\HasNoChildren) "/" "[Gmail]/All Mail"' 13 | '(\\HasNoChildren) "/" "[Gmail]/Drafts"' 14 | '(\\HasChildren \\HasNoChildren) "/" "[Gmail]/Sent Mail"' 15 | '(\\HasNoChildren) "/" "[Gmail]/Spam"' 16 | '(\\HasNoChildren) "/" "[Gmail]/Starred"' 17 | '(\\HasChildren \\HasNoChildren) "/" "[Gmail]/Trash"' 18 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/16/fabfile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - fabfile.py 3 | # A sample Fabric script 4 | 5 | # Even though this chapter will not cover Fabric, you might want to try 6 | # using Fabric to automate your SSH commands instead of re-inventing the 7 | # wheel. Here is a script that checks for Python on remote machines. 8 | # Fabric finds this "fabfile.py" automatically if you are in the same 9 | # directory. Try running both verbosely, and with most messages off: 10 | # 11 | # $ fab versions:host=server.example.com 12 | # $ fab --hide=everything versions:host=server.example.com 13 | 14 | from fabric.api import * 15 | 16 | def versions(): 17 | with cd('/usr/bin'): 18 | with settings(hide('warnings'), warn_only=True): 19 | for version in '2.4', '2.5', '2.6', '2.7', '3.0', '3.1': 20 | result = run('python%s -c "None"' % version) 21 | if not result.failed: 22 | print("Host", env.host, "has Python", version) 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/16/sftp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - sftp.py 3 | # Fetching files with SFTP 4 | 5 | import functools 6 | import paramiko 7 | 8 | class AllowAnythingPolicy(paramiko.MissingHostKeyPolicy): 9 | def missing_host_key(self, client, hostname, key): 10 | return 11 | 12 | client = paramiko.SSHClient() 13 | client.set_missing_host_key_policy(AllowAnythingPolicy()) 14 | client.connect('127.0.0.1', username='test') # password='') 15 | 16 | def my_callback(filename, bytes_so_far, bytes_total): 17 | print('Transfer of %r is at %d/%d bytes (%.1f%%)' % ( 18 | filename, bytes_so_far, bytes_total, 100. * bytes_so_far / bytes_total)) 19 | 20 | sftp = client.open_sftp() 21 | sftp.chdir('/var/log') 22 | for filename in sorted(sftp.listdir()): 23 | if filename.startswith('messages.'): 24 | callback_for_filename = functools.partial(my_callback, filename) 25 | sftp.get(filename, filename, callback=callback_for_filename) 26 | 27 | client.close() 28 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/16/shell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - shell.py 3 | # A simple shell, so you can try running commands in the absence of 4 | # any special characters (except for whitespace, used for splitting). 5 | 6 | import subprocess 7 | 8 | while True: 9 | args = input('] ').split() 10 | if not args: 11 | pass 12 | elif args == ['exit']: 13 | break 14 | elif args[0] == 'show': 15 | print("Arguments:", args[1:]) 16 | else: 17 | subprocess.call(args) 18 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/16/ssh_commands.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - ssh_commands.py 3 | # Running separate commands instead of using a shell 4 | 5 | import paramiko 6 | 7 | class AllowAnythingPolicy(paramiko.MissingHostKeyPolicy): 8 | def missing_host_key(self, client, hostname, key): 9 | return 10 | 11 | client = paramiko.SSHClient() 12 | client.set_missing_host_key_policy(AllowAnythingPolicy()) 13 | client.connect('127.0.0.1', username='test') # password='') 14 | 15 | for command in 'echo "Hello, world!"', 'uname', 'uptime': 16 | stdin, stdout, stderr = client.exec_command(command) 17 | stdin.close() 18 | print(repr(stdout.read())) 19 | stdout.close() 20 | stderr.close() 21 | 22 | client.close() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/16/ssh_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - ssh_simple.py 3 | # Using SSH like Telnet: connecting and running two commands 4 | 5 | import paramiko 6 | 7 | class AllowAnythingPolicy(paramiko.MissingHostKeyPolicy): 8 | def missing_host_key(self, client, hostname, key): 9 | return 10 | 11 | client = paramiko.SSHClient() 12 | client.set_missing_host_key_policy(AllowAnythingPolicy()) 13 | client.connect('127.0.0.1', username='test') # password='') 14 | 15 | channel = client.invoke_shell() 16 | stdin = channel.makefile('wb') 17 | stdout = channel.makefile('rb') 18 | 19 | stdin.write('echo Hello, world\rexit\r') 20 | print(stdout.read()) 21 | 22 | client.close() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/16/ssh_simple.txt: -------------------------------------------------------------------------------- 1 | Linux guinness 2.6.32-24-generic #42-Ubuntu SMP Fri Aug 20 14:24:04 UTC 2 | 2010 i686 GNU/Linux 3 | Ubuntu 10.04.1 LTS 4 | 5 | Welcome to Ubuntu! 6 | * Documentation: https://help.ubuntu.com/ 7 | 8 | Last login: Mon Sep 6 01:02:46 2010 from localhost 9 | echo Hello, world 10 | exit 11 | test@guinness:~$ echo Hello, world 12 | Hello, world 13 | test@guinness:~$ exit 14 | logout 15 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/16/ssh_threads.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - ssh_threads.py 3 | # Running two remote commands simultaneously in different channels 4 | 5 | import threading 6 | import paramiko 7 | 8 | class AllowAnythingPolicy(paramiko.MissingHostKeyPolicy): 9 | def missing_host_key(self, client, hostname, key): 10 | return 11 | 12 | client = paramiko.SSHClient() 13 | client.set_missing_host_key_policy(AllowAnythingPolicy()) 14 | client.connect('127.0.0.1', username='test') # password='') 15 | 16 | def read_until_EOF(fileobj): 17 | s = fileobj.readline() 18 | while s: 19 | print(s.strip()) 20 | s = fileobj.readline() 21 | 22 | out1 = client.exec_command('echo One;sleep 2;echo Two;sleep 1;echo Three')[1] 23 | out2 = client.exec_command('echo A;sleep 1;echo B;sleep 2;echo C')[1] 24 | thread1 = threading.Thread(target=read_until_EOF, args=(out1,)) 25 | thread2 = threading.Thread(target=read_until_EOF, args=(out2,)) 26 | thread1.start() 27 | thread2.start() 28 | thread1.join() 29 | thread2.join() 30 | 31 | client.close() 32 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/16/telnet_codes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - telnet_codes.py 3 | # How your code might look if you intercept Telnet options yourself 4 | 5 | from telnetlib import Telnet, IAC, DO, DONT, WILL, WONT, SB, SE, TTYPE 6 | 7 | def process_option(tsocket, command, option): 8 | if command == DO and option == TTYPE: 9 | tsocket.sendall(IAC + WILL + TTYPE) 10 | print('Sending terminal type "mypython"') 11 | tsocket.sendall(IAC + SB + TTYPE + b'\0' + b'mypython' + IAC + SE) 12 | elif command in (DO, DONT): 13 | print('Will not', ord(option)) 14 | tsocket.sendall(IAC + WONT + option) 15 | elif command in (WILL, WONT): 16 | print('Do not', ord(option)) 17 | tsocket.sendall(IAC + DONT + option) 18 | 19 | t = Telnet('localhost') 20 | # t.set_debuglevel(1) # uncomment this for debugging messages 21 | 22 | t.set_option_negotiation_callback(process_option) 23 | t.read_until(b'login:', 5) 24 | t.write(b'brandon\n') 25 | t.read_until(b'assword:', 5) # so P can be capitalized or not 26 | t.write(b'mypass\n') 27 | n, match, previous_text = t.expect([br'Login incorrect', br'\$'], 10) 28 | if n == 0: 29 | print("Username and password failed - giving up") 30 | else: 31 | t.write(b'exec echo My terminal type is $TERM\n') 32 | print(t.read_all().decode('ascii')) 33 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/16/telnet_login.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 16 - telnet_login.py 3 | # Connect to localhost, watch for a login prompt, and try logging in 4 | 5 | import telnetlib 6 | 7 | t = telnetlib.Telnet('localhost') 8 | # t.set_debuglevel(1) # uncomment this for debugging messages 9 | 10 | t.read_until(b'login:') 11 | t.write(b'brandon\n') 12 | t.read_until(b'assword:') # let "P" be capitalized or not 13 | t.write(b'mypass\n') 14 | n, match, previous_text = t.expect([br'Login incorrect', br'\$'], 10) 15 | if n == 0: 16 | print(b'Username and password failed - giving up') 17 | else: 18 | t.write(b'exec uptime\n') 19 | print(t.read_all().decode('ascii')) # read until connection closes 20 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/17/advbinarydl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Advanced binary download - Chapter 17 - advbinarydl.py 3 | 4 | import os, sys 5 | from ftplib import FTP 6 | 7 | if os.path.exists('linux-1.0.tar.gz'): 8 | raise IOError('refusing to overwrite your linux-1.0.tar.gz file') 9 | 10 | f = FTP('ftp.kernel.org') 11 | f.login() 12 | 13 | f.cwd('/pub/linux/kernel/v1.0') 14 | f.voidcmd("TYPE I") 15 | 16 | datasock, size = f.ntransfercmd("RETR linux-1.0.tar.gz") 17 | bytes_so_far = 0 18 | fd = open('linux-1.0.tar.gz', 'wb') 19 | 20 | while 1: 21 | buf = datasock.recv(2048) 22 | if not buf: 23 | break 24 | fd.write(buf) 25 | bytes_so_far += len(buf) 26 | print("\rReceived", bytes_so_far, end=' ') 27 | if size: 28 | print("of %d total bytes (%.1f%%)" % ( 29 | size, 100 * bytes_so_far / float(size)), end=' ') 30 | else: 31 | print("bytes", end=' ') 32 | sys.stdout.flush() 33 | 34 | print() 35 | fd.close() 36 | datasock.close() 37 | f.voidresp() 38 | f.quit() 39 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/17/advbinaryul.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Advanced binary upload - Chapter 17 - advbinaryul.py 3 | 4 | from ftplib import FTP 5 | import sys, getpass, os.path 6 | 7 | BLOCKSIZE = 8192 # chunk size to read and transmit: 8 kB 8 | 9 | if len(sys.argv) != 5: 10 | print("usage: %s " % ( 11 | sys.argv[0])) 12 | exit(2) 13 | 14 | host, username, localfile, remotedir = sys.argv[1:] 15 | password = getpass.getpass("Enter password for %s on %s: " % \ 16 | (username, host)) 17 | f = FTP(host) 18 | f.login(username, password) 19 | 20 | f.cwd(remotedir) 21 | f.voidcmd("TYPE I") 22 | 23 | fd = open(localfile, 'rb') 24 | datasock, esize = f.ntransfercmd('STOR %s' % os.path.basename(localfile)) 25 | size = os.stat(localfile)[6] 26 | bytes_so_far = 0 27 | 28 | while 1: 29 | buf = fd.read(BLOCKSIZE) 30 | if not buf: 31 | break 32 | datasock.sendall(buf) 33 | bytes_so_far += len(buf) 34 | print("\rSent", bytes_so_far, "of", size, "bytes", \ 35 | "(%.1f%%)\r" % (100 * bytes_so_far / float(size))) 36 | sys.stdout.flush() 37 | 38 | print() 39 | datasock.close() 40 | fd.close() 41 | f.voidresp() 42 | f.quit() 43 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/17/asciidl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # ASCII download - Chapter 17 - asciidl.py 3 | # Downloads README from remote and writes it to disk. 4 | 5 | import os 6 | from ftplib import FTP 7 | 8 | if os.path.exists('README'): 9 | raise IOError('refusing to overwrite your README file') 10 | 11 | def writeline(data): 12 | fd.write(data) 13 | fd.write(os.linesep) 14 | 15 | f = FTP('ftp.kernel.org') 16 | f.login() 17 | f.cwd('/pub/linux/kernel') 18 | 19 | fd = open('README', 'w') 20 | f.retrlines('RETR README', writeline) 21 | fd.close() 22 | 23 | f.quit() 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/17/binarydl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Binary upload - Chapter 17 - binarydl.py 3 | 4 | import os 5 | from ftplib import FTP 6 | 7 | if os.path.exists('patch8.gz'): 8 | raise IOError('refusing to overwrite your patch8.gz file') 9 | 10 | f = FTP('ftp.kernel.org') 11 | f.login() 12 | f.cwd('/pub/linux/kernel/v1.0') 13 | 14 | fd = open('patch8.gz', 'wb') 15 | f.retrbinary('RETR patch8.gz', fd.write) 16 | fd.close() 17 | 18 | f.quit() 19 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/17/binaryul.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Binary download - Chapter 17 - binaryul.py 3 | 4 | from ftplib import FTP 5 | import sys, getpass, os.path 6 | 7 | if len(sys.argv) != 5: 8 | print("usage: %s " % ( 9 | sys.argv[0])) 10 | exit(2) 11 | 12 | host, username, localfile, remotedir = sys.argv[1:] 13 | password = getpass.getpass( 14 | "Enter password for %s on %s: " % (username, host)) 15 | 16 | f = FTP(host) 17 | f.login(username, password) 18 | f.cwd(remotedir) 19 | 20 | fd = open(localfile, 'rb') 21 | f.storbinary('STOR %s' % os.path.basename(localfile), fd) 22 | fd.close() 23 | 24 | f.quit() 25 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/17/connect.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Basic connection - Chapter 17 - connect.py 3 | 4 | from ftplib import FTP 5 | 6 | f = FTP('ftp.ibiblio.org') 7 | print("Welcome:", f.getwelcome()) 8 | f.login() 9 | 10 | print("Current working directory:", f.pwd()) 11 | f.quit() 12 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/17/dir.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # dir() example - Chapter 17 - dir.py 3 | 4 | from ftplib import FTP 5 | 6 | f = FTP('ftp.ibiblio.org') 7 | f.login() 8 | f.cwd('/pub/academic/astronomy/') 9 | entries = [] 10 | f.dir(entries.append) 11 | print("%d entries:" % len(entries)) 12 | for entry in entries: 13 | print(entry) 14 | f.quit() 15 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/17/nlst.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # NLST example - Chapter 17 - nlst.py 3 | 4 | from ftplib import FTP 5 | 6 | f = FTP('ftp.ibiblio.org') 7 | f.login() 8 | f.cwd('/pub/academic/astronomy/') 9 | entries = f.nlst() 10 | entries.sort() 11 | print(len(entries), "entries:") 12 | for entry in entries: 13 | print(entry) 14 | f.quit() 15 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/17/recursedl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Recursive downloader - Chapter 17 - recursedl.py 3 | 4 | import os, sys 5 | from ftplib import FTP, error_perm 6 | 7 | def walk_dir(f, dirpath): 8 | original_dir = f.pwd() 9 | try: 10 | f.cwd(dirpath) 11 | except error_perm: 12 | return # ignore non-directores and ones we cannot enter 13 | print(dirpath) 14 | names = f.nlst() 15 | for name in names: 16 | walk_dir(f, dirpath + '/' + name) 17 | f.cwd(original_dir) # return to cwd of our caller 18 | 19 | f = FTP('ftp.kernel.org') 20 | f.login() 21 | walk_dir(f, '/pub/linux/kernel/Historic/old-versions') 22 | f.quit() 23 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/18/jsonrpc_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - jsonrpc_client.py 3 | # JSON-RPC client 4 | 5 | from lovely.jsonrpc import proxy 6 | proxy = proxy.ServerProxy('http://localhost:7002') 7 | print(proxy.lengths((1,2,3), 27, {'Sirius': -1.46, 'Rigel': 0.12})) 8 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/18/jsonrpc_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - jsonrpc_server.py 3 | # JSON-RPC server 4 | 5 | from wsgiref.simple_server import make_server 6 | import lovely.jsonrpc.dispatcher, lovely.jsonrpc.wsgi 7 | 8 | def lengths(*args): 9 | results = [] 10 | for arg in args: 11 | try: 12 | arglen = len(arg) 13 | except TypeError: 14 | arglen = None 15 | results.append((arglen, arg)) 16 | return results 17 | 18 | dispatcher = lovely.jsonrpc.dispatcher.JSONRPCDispatcher() 19 | dispatcher.register_method(lengths) 20 | app = lovely.jsonrpc.wsgi.WSGIJSONRPCApplication({'': dispatcher}) 21 | server = make_server('localhost', 7002, app) 22 | print("Starting server") 23 | while True: 24 | server.handle_request() 25 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/18/rpyc_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - rpyc_client.py 3 | # RPyC client 4 | 5 | import rpyc 6 | 7 | def noisy(string): 8 | print('Noisy:', repr(string)) 9 | 10 | proxy = rpyc.connect('localhost', 18861, config={'allow_public_attrs': True}) 11 | fileobj = open('testfile.txt') 12 | linecount = proxy.root.line_counter(fileobj, noisy) 13 | print('The number of lines in the file was', linecount) 14 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/18/rpyc_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - rpyc_server.py 3 | # RPyC server 4 | 5 | import rpyc 6 | 7 | class MyService(rpyc.Service): 8 | def exposed_line_counter(self, fileobj, function): 9 | for linenum, line in enumerate(fileobj.readlines()): 10 | function(line) 11 | return linenum + 1 12 | 13 | from rpyc.utils.server import ThreadedServer 14 | t = ThreadedServer(MyService, port = 18861) 15 | t.start() 16 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/18/testfile.txt: -------------------------------------------------------------------------------- 1 | Simple 2 | is 3 | better 4 | than 5 | complex. 6 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/18/xmlrpc_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Foundations of Python Network Programming - Chapter 18 - xmlrpc_client.py 4 | # XML-RPC client 5 | 6 | import xmlrpc.client 7 | proxy = xmlrpc.client.ServerProxy('http://127.0.0.1:7001') 8 | print(proxy.addtogether('x', 'ÿ', 'z')) 9 | print(proxy.addtogether(20, 30, 4, 1)) 10 | print(proxy.quadratic(2, -4, 0)) 11 | print(proxy.quadratic(1, 2, 1)) 12 | print(proxy.remote_repr((1, 2.0, 'three'))) 13 | print(proxy.remote_repr([1, 2.0, 'three'])) 14 | print(proxy.remote_repr({'name': 'Arthur', 'data': {'age': 42, 'sex': 'M'}})) 15 | print(proxy.quadratic(1, 0, 1)) 16 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/18/xmlrpc_introspect.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - xmlrpc_introspect.py 3 | # XML-RPC client 4 | 5 | import xmlrpc.client 6 | proxy = xmlrpc.client.ServerProxy('http://127.0.0.1:7001') 7 | 8 | print('Here are the functions supported by this server:') 9 | for method_name in proxy.system.listMethods(): 10 | 11 | if method_name.startswith('system.'): 12 | continue 13 | 14 | signatures = proxy.system.methodSignature(method_name) 15 | if isinstance(signatures, list) and signatures: 16 | for signature in signatures: 17 | print('%s(%s)' % (method_name, signature)) 18 | else: 19 | print('%s(...)' % (method_name,)) 20 | 21 | method_help = proxy.system.methodHelp(method_name) 22 | if method_help: 23 | print(' ', method_help) 24 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/18/xmlrpc_multicall.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - xmlrpc_multicall.py 3 | # XML-RPC client performing a multicall 4 | 5 | import xmlrpc.client 6 | proxy = xmlrpc.client.ServerProxy('http://127.0.0.1:7001') 7 | multicall = xmlrpc.client.MultiCall(proxy) 8 | multicall.addtogether('a', 'b', 'c') 9 | multicall.quadratic(2, -4, 0) 10 | multicall.remote_repr([1, 2.0, 'three']) 11 | for answer in multicall(): 12 | print(answer) 13 | -------------------------------------------------------------------------------- /foundations-of-python-network-programming/python3/18/xmlrpc_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Foundations of Python Network Programming - Chapter 18 - xmlrpc_server.py 3 | # XML-RPC server 4 | 5 | import operator, math 6 | from xmlrpc.server import SimpleXMLRPCServer 7 | from functools import reduce 8 | 9 | def addtogether(*things): 10 | """Add together everything in the list `things`.""" 11 | return reduce(operator.add, things) 12 | 13 | def quadratic(a, b, c): 14 | """Determine `x` values satisfying: `a` * x*x + `b` * x + c == 0""" 15 | b24ac = math.sqrt(b*b - 4.0*a*c) 16 | return list(set([ (-b-b24ac) / 2.0*a, 17 | (-b+b24ac) / 2.0*a ])) 18 | 19 | def remote_repr(arg): 20 | """Return the `repr()` rendering of the supplied `arg`.""" 21 | return arg 22 | 23 | server = SimpleXMLRPCServer(('127.0.0.1', 7001)) 24 | server.register_introspection_functions() 25 | server.register_multicall_functions() 26 | server.register_function(addtogether) 27 | server.register_function(quadratic) 28 | server.register_function(remote_repr) 29 | print("Server ready") 30 | server.serve_forever() 31 | --------------------------------------------------------------------------------