2016-10-29 2 views
0

Я запускаю Ubuntu 16.04, и я пытаюсь написать скрипт python, который делает запрос GET указанному файлу изображения с учетом URL-адреса. В качестве примера, в коде ниже:Использование скрипта python для отправки запроса GET на сервер с netcat

host является www.google.com

port является 80

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 на терминале, но я явно получаю текст HTML www.google.com на сервере.

Я думал, что мне может потребоваться, чтобы он дождался запроса HTTP до тех пор, пока не будет открыто STDIN netcat, но я не знаю, как это сделать. Или, может быть, это просто завершение запроса, потому что он как-то отправляет \n? Я действительно не знаю.

EDIT: Кажется, он фактически не отправляет запрос на www.google.com. Я сохранил ответ сервера как файл .html, и он выглядит как облачный веб-сайт.

EDIT2: После дополнительных исследований кажется, что проблема заключается в том, что, поскольку netcat является интерактивным, и поэтому это «взаимоблокировки» или что-то в этом роде. Я пытался использовать proc.communicate(), но так как мне нужно отправить несколько строк, это не позволяет видеть, так как communicate позволяет только записывать начальный ввод в STDIN, а затем он отправляет EOF или что-то в этом роде. Это привело меня к попытке использовать proc.stdin.write, но это, по-видимому, также, как известно, вызывает тупик с чем-то связанным с тем, что команды Popen используют subprocess.PIPE для STDIN, STDOUT и STDERR. Он также требует, чтобы вход был закодирован как объект bytes-like, который я сделал, но когда я отправляю \r\n\r\n в конце, чтобы попытаться закрыть соединение, он ничего не делает, а STDOUT просто содержит b'', который я понимаю как пустой строка в виде bytes

+0

есть ли причина, почему вы используете 'netcat' сделать запрос GET? Там гораздо больше простых способов сделать это. –

+0

Это часть задания для сетевого класса, и мы должны использовать только «netcat». Нет библиотек или чего-либо, что может скрывать, что происходит в фоновом режиме. –

+0

Попробуйте выполнить GET напротив сайта, кроме google.com. Google может возражать против того, чтобы ваш робот-скрипт получал свои данные, не используя свой API. – boardrider

ответ

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()