import socket,struct
def enc(p):
    r=b''
    for k,v in p.items():
        for b in (k.encode(),v.encode()):
            if len(b)<128: r+=struct.pack('B',len(b))
            else: r+=struct.pack('!I',len(b)|0x80000000)
        r+=k.encode()+v.encode()
    return r
def test(mode, tag):
    p={'GATEWAY_INTERFACE':'CGI/1.1','REQUEST_METHOD':'GET','SCRIPT_FILENAME':'/tmp/t1.php','SCRIPT_NAME':'/x.php','REQUEST_URI':'/x.php','QUERY_STRING':'','SERVER_PROTOCOL':'HTTP/1.1','REMOTE_ADDR':'127.0.0.1','SERVER_NAME':'localhost','SERVER_PORT':'80','SERVER_ADDR':'127.0.0.1','REDIRECT_STATUS':'200','DOCUMENT_ROOT':'/','HTTP_HOST':'localhost'}
    if mode=='short':
        begin=struct.pack('!BBHH',1,1,1,3)+struct.pack('!HB',1,0)
    else:
        begin=struct.pack('!BBHH',1,1,1,8)+struct.pack('!HB',1,0)+b'\x00'*5
    pd=enc(p)
    out=begin+struct.pack('!BBHH',1,4,1,len(pd))+pd+struct.pack('!BBHH',1,4,1,0)+struct.pack('!BBHH',1,5,1,0)
    try:
        s=socket.create_connection(('127.0.0.1',9000),4)
        s.sendall(out)
        s.settimeout(5)
        data=b''
        try:
            while True:
                c=s.recv(65536)
                if not c: break
                data+=c
        except socket.timeout:
            data+=b'<TIMEOUT>'
        print(tag,'OK',repr(data[:300]))
        s.close()
    except Exception as e:
        print(tag,'EXC',repr(e))
test('short','SHORT_BEGIN(3B)')
test('long','LONG_BEGIN(8B)')
