You didn't put commas after each variable:
Your code:
Edited code:
Also you should never use sys for arguments, use argparse or optparse instead. You also have a lot of readability issues. A better and more pythonic way to write this would be something like this:
As you can see the one I wrote reads more like python and can be simply and easily edited to make multiple connections if needed.
Your code:
Code:
req = req.format(
rfcnum=rfc_number
host=host
port=port
version=sys.version.info[0]
)
Edited code:
Code:
import sys, socket
try:
rfc_number = int(sys.argv[1])
except (IndexError, ValueError):
print('Must supply an RFC number as first argument')
sys.exit(2)
host = 'www.ietf.org'
port = 80
sock = socket.create_connection((host, port))
req = (
'GET/rfc/rfc{rfcnum}.txt HTTP/1.1\r\n'
'Host: {host}:{port}\r\n'
'User-Agent: Python {version}\r\n'
'Connection: close\r\n'
'\r\n'
)
req = req.format(
rfcnum=rfc_number,
host=host,
port=port,
version=sys.version.info[0]
)
sock.sendall(req.encode('ascii'))
rfc_raw = bytearray()
while True:
buf = sock.recv(4096)
if not len(buf):
break
rfc_raw += buf
rfc = rfc_raw.decode('utf-8')
print(rfc)
Also you should never use sys for arguments, use argparse or optparse instead. You also have a lot of readability issues. A better and more pythonic way to write this would be something like this:
Code:
import sys
import socket
import argparse
class Parser(argparse.ArgumentParser):
"""
class to store your arguments in
"""
def __init__(self):
super(Parser, self).__init__()
@staticmethod
def optparse():
"""
staticmethod so that python knows this is apart of the class but does not
generate data from the class itself
"""
parser = argparse.ArgumentParser()
parser.add_argument("-h", "--host", dest="hostToConnect", help="pass a host")
parser.add_argument("-p", "--port", type=int, dest="portToConnect", help="pass a port")
parser.add_argument("-r", "--rfc", type=int, dest="rfcNumber", help="pass an RFC number")
return parser.parse_args()
# constants for what is going to be used throughout the entire program
SOCK = socket.create_connection
BUFFER_SIZE = 4096
def create_packet(rfc_number, host, port, py_version=sys.version_info):
"""
create your packet in a function for readability
"""
packet = "GET /rfc/rfc{}.txt HTTP/1.1\r\n"
packet += "Host: {}:{}\r\n"
packet += "User-Agent: Python {}\r\n"
packet += "Connection: close\r\n"
packet += "\r\n"
return packet.format(
rfc_number, host, port, py_version
)
def create_request(rfc, host, port):
"""
create your request in a function and generate the packet from the function
that way if you want to do multiple hosts at once, it is simple and easy
"""
req = create_packet(rfc, host, port)
raw_rfc = bytearray()
socks = SOCK((host, port))
socks.sendall(req.encode("ascii"))
while True:
recv_buffer = socks.recv(BUFFER_SIZE)
if not len(recv_buffer):
break
raw_rfc += recv_buffer
rfc = raw_rfc.decode("utf-8")
return rfc
def main():
"""
main function of the program where you call everything
"""
opts = Parser().optparse()
if opts.hostToConnect is None:
print("must specify a host")
if opts.portToConnect is None:
print("must specify a port")
if opts.rfcNumber is None:
print("must specify an RFC number")
data = create_request(opts.rfcNumber, opts.hostToConnect, opts.portToConnect)
print(data)
# this tell python the entry point of your program
if __name__ == "__main__":
main()
As you can see the one I wrote reads more like python and can be simply and easily edited to make multiple connections if needed.