使用python脚本将GET请求发送到带有netcat的服务器

时间:2016-10-29 06:54:58

标签: python get netcat

我正在运行Ubuntu 16.04并且我正在尝试编写一个python脚本,该脚本在给定url的情况下向指定的图像文件发出GET请求。例如,在下面的代码中:

hostwww.google.com

port80

u.path/images/srpr/logo3w.png

proc = Popen(["netcat {} {}".format(host, port)], shell= True)
proc = Popen(["GET {} HTTP/1.1".format(u.path)], shell= True)
proc = Popen(["Host: {}".format(host)], shell= True)
proc = Popen(["Connection: close"], shell= True)
proc = Popen(["\n"], shell= True)

我的问题是我可以在终端中正常执行这些操作,但是当我尝试运行脚本时,它似乎会在GET之前将www.google.com请求发送到u.path }}。我知道这样做有两个原因。首先,就在服务器响应进来之前,我得到以下结果:

/bin/sh: 1: Host:: not found /bin/sh: 1: Connection:: not found

其次,我知道图像数据的服务器响应是在终端上被解释为奇怪的Unicode符号的一堆丑陋的东西,但我显然在服务器响应中获得了www.google.com HTML文本。 / p>

我想我可能需要让它等待HTTP请求,直到netcat STDIN打开,但我不知道如何。或者它可能只是完成请求,因为它以某种方式发送\n?我真的不知道。

编辑:好像它实际上没有将请求发送给www.google.com。我将服务器响应保存为.html文件,它看起来像一个云端网站

EDIT2:经过更多的研究,似乎问题是因为netcat是交互式的,所以它“死锁”或类似的东西。我尝试使用proc.communicate(),但由于我需要发送多行,因此不允许它看到communicate只允许将初始输入写入STDIN,然后发送{{ 1}}或沿着这些方向的东西。这导致我尝试使用EOF,但这显然也会导致与proc.stdin.write命令使用Popen subprocess.PIPE STDIN相关的问题导致死锁,{{1} }和STDOUT。它还要求输入被编码为STDERR对象,我已经完成但是当我在末尾发送bytes-like以尝试关闭连接时它不会执行任何操作而{{1只包含\r\n\r\n,我理解为STDOUT

形式的空字符串

1 个答案:

答案 0 :(得分:0)

对于有类似问题的人,我找到了解决方案:

#begin the interactive shell of netcat
proc = Popen(['netcat -q -1 {} {}'.format(host, port)], shell=True, stdout=PIPE, stdin=PIPE, stderr=PIPE)

#set file status flags on stdout to non-blocking reads
fcntl.fcntl(proc.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)

#each time we write a diffrent line to the interactive shell
#we need to flush the buffer just to be safe
#credit to http://nigelarmstrong.me/2015/04/python-subprocess/
proc.stdin.write(str.encode('GET %s HTTP/1.1\n' %(path+filename)))
proc.stdin.flush()
proc.stdin.write(str.encode('Host: {}\n'.format(host)))
proc.stdin.flush()
proc.stdin.write(str.encode('Connection: close\n'))
proc.stdin.flush()
proc.stdin.write(str.encode('\r\n\r\n'))
proc.stdin.flush()

#give the server time to respond
proc.wait()

#store the server response (which is bytes-like)
#attempting to decode it results in error since we're recieving data as a mix of text/image
serv_response = proc.stdout.read()