"""HTTP Messages This modules contains classes for representing HTTP responses and requests. """ import re import regexes as r import weblogging as logging reasondict = { # Dictionary for code reasons # Format: code : "Reason" 200 : 'OK', 403 : 'Forbidden', 404 : 'Not Found', 500 : 'Internal Server Error' } class Message(object): """Class that stores an HTTP Message""" def __init__(self): """Initialize the Message""" self.version = "HTTP/1.1" self.body = "" self.headers = dict() def set_header(self, name, value): """Add a header and its value Args: name (str): name of header value (str): value of header """ self.headers[name] = str(value) def get_header(self, name): """Get the value of a header Args: name (str): name of header Returns: str: value of header, empty if header does not exist """ if name in self.headers: return self.headers[name] else: return "" def parse_headers(self, msg): for name, value in re.findall(r.MessageHeader, msg): self.set_header(name, value.strip()) logging.debug("%s: %s" % (name, value.strip())) def startline(self): return '' def __str__(self): """Convert the Message to a string Returns: str: representation the can be sent over socket """ msg = '' msg += '%s\r\n' % self.startline() msg += '\r\n'.join([k + ": " + v for k, v in self.headers.iteritems()]) msg += '\r\n\r\n' msg += self.body return msg def __eq__(self, other): return self.__dict__ == other.__dict__ class Request(Message): """Class that stores an HTTP request""" def __init__(self): """Initialize the Request""" super(Request, self).__init__() self.method = "" self.uri = "" def parse(self, msg): [reqline, rest] = msg.split('\r\n', 1) reqline = re.match(r.RequestLine, reqline + '\r\n') self.method, self.uri, self.version = reqline.groups() [headers, body] = rest.split('\r\n\r\n', 1) self.parse_headers(headers) self.body = body def startline(self): return "%s %s %s" % (self.method, self.uri, self.version) def __str__(self): """Convert the Request to a string Returns: str: representation the can be sent over socket """ return super(Request, self).__str__() class Response(Message): """Class that stores an HTTP Response""" def __init__(self): """Initialize the Response""" super(Response, self).__init__() def parse(self, msg): [respline, rest] = msg.split('\r\n', 1) respline = re.match(r.StatusLine, respline + '\r\n') self.version = respline.group(1) self.code = int(respline.group(2)) [headers, body] = rest.split('\r\n\r\n', 1) self.parse_headers(headers) self.body = body def startline(self): return "%s %d %s" % (self.version, self.code, reasondict[self.code]) def __str__(self): """Convert the Response to a string Returns: str: representation the can be sent over socket """ return super(Response, self).__str__()