class WebServer(BasicNode): """A host in the network which is serving a website (specified by the web_server_to_proxy_hostname parameter) on TCP port 80. Like Host, it also replies to echo and ARP requests. It serves the specified website by acting as a proxy for that website.""" def __init__(self, topo, name, path_to_serve): BasicNode.__init__(self, topo, name) self.http_server = HTTPServer(TCPServer.ANY_PORT, path_to_serve) self.intf = None self.pkt = None @staticmethod def get_type_str(): return 'Web Server' def handle_non_icmp_ip_packet_to_self(self, intf, pkt): """If pkt is to an HTTP_PORT, then the packet is handed off to the HTTP server. Otherwise, the default superclass implementation is called.""" reactor.callLater(2, self.send_packets) if pkt.is_valid_tcp(): if is_http_port(pkt.tcp_dst_port): self.handle_http_request(intf, pkt) return BasicNode.handle_non_icmp_ip_packet_to_self(self, intf, pkt) def handle_http_request(self, intf, pkt): """Forward the rceived packet from an HTTP client to the web server.""" self.intf = intf self.pkt = pkt tcp_conn = self.http_server.handle_tcp(pkt) self.send_packets() def send_packets(self): """Send any waiting packets""" if self.intf and self.pkt: for (_, tcp_conn) in self.http_server.connections.iteritems(): if tcp_conn and not tcp_conn.dead: tcp_pts = tcp_conn.get_packets_to_send() for tcp, data in tcp_pts: eth = self.pkt.get_reversed_eth() ip = self.pkt.get_reversed_ip(new_ttl=64, new_tlen=self.pkt.ip_hlen+len(tcp)+len(data)) pkt_out = eth + ip + Packet.cksum_tcp_hdr(ip, tcp, data) + data logging.debug('%s sending packet from HTTP server: %s' % (self, pktstr(pkt_out))) self.intf.link.send_to_other(self.intf, pkt_out) def __str__(self): ps = ' serving:%s' % self.http_server.get_path_being_served() return BasicNode.__str__(self) + ps
class WebServer(BasicNode): """A host in the network which is serving a website (specified by the web_server_to_proxy_hostname parameter) on TCP port 80. Like Host, it also replies to echo and ARP requests. It serves the specified website by acting as a proxy for that website.""" def __init__(self, topo, name, path_to_serve): BasicNode.__init__(self, topo, name) self.http_server = HTTPServer(TCPServer.ANY_PORT, path_to_serve) @staticmethod def get_type_str(): return 'Web Server' def handle_non_icmp_ip_packet_to_self(self, intf, pkt): """If pkt is to an HTTP_PORT, then the packet is handed off to the HTTP server. Otherwise, the default superclass implementation is called.""" if pkt.is_valid_tcp(): if is_http_port(pkt.tcp_dst_port): self.handle_http_request(intf, pkt) return BasicNode.handle_non_icmp_ip_packet_to_self(self, intf, pkt) def handle_http_request(self, intf, pkt): """Forward the received packet from an HTTP client to the web server.""" tcp_conn = self.http_server.handle_tcp(pkt) if tcp_conn: tcp_pts = tcp_conn.get_packets_to_send() if tcp_pts: for tcp, data in tcp_pts: eth = pkt.get_reversed_eth() ip = pkt.get_reversed_ip(new_ttl=64, new_tlen=pkt.ip_hlen+len(tcp)+len(data)) pkt_out = eth + ip + Packet.cksum_tcp_hdr(ip, tcp, data) + data logging.debug('%s sending packet from HTTP server: %s' % (self, pktstr(pkt_out))) intf.link.send_to_other(intf, pkt_out) def __str__(self): ps = ' serving:%s' % self.http_server.get_path_being_served() return BasicNode.__str__(self) + ps