python 2.7 400 Bad Request Error - python-2.7

I am doing an exercise for an online course and keep getting an error thrown at me. Theres another 404 error in the output as well actually. I believe there are really only 2 spots where this could go haywire, line 11 and 13 but it looks correct to me. If I replace the variables with fixed addresses (not user generated) it works fine. Thanks for your help.
import socket
site= raw_input("Enter url:")
print ""
print "site is",site
print ""
hostel = site.split("/")
print "Hostel is", hostel
print ""
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect((hostel[2], 80))
mysock.send('GET site HTTP/1.0\n\n')
while True:
data = mysock.recv(1024)
data = data.strip()
if len(data) < 1:
break
print data
mysock.close()

You're not using your site variable here, but literally requesting "site":
mysock.send('GET site HTTP/1.0\n\n')
Try:
mysock.send('GET ' + site + ' HTTP/1.0\n\n')

You should use the variable 'site' instead of the word site try:
message_send = "GET / HTTP/1.1\r\nHost: %s\r\n\r\n".format(site)
mysock.send(message_send)

Related

Getting 404 error for every page with python socket

I started to learn python. I was trying this piece of code from the book.
import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
mysock.connect(('www.py4inf.com', 80))
mysock.send('GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n')
except Exception as e:
print(e)
try:
while True:
data = mysock.recv(512)
if ( len(data) < 1 ) :
break
print data
except Exception as e:
print(e)
mysock.close()
It doesn't matter which web page I am trying to connect, I am getting 404 error.
I got the following when I run the code.
HTTP/1.1 404 Not Found
Server: nginx
Date: Tue, 23 May 2017 17:54:54 GMT
Content-Type: text/html
Content-Length: 162
Connection: close
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
mysock.send('GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n')
You are trying to send a HTTP request but there are multiple things wrong with it. Some of these cause problems while others just get ignored by this specific server:
The line end should be \r\n not \n
The path in the GET request should not be an absolute URL but relative to the server, i.e. /code/romeo.txt. Absolute is acceptable with HTTP/1.1 but you use HTTP/1.0.
The server uses virtual hosting, i.e. multiple host names on the same IP address. Therefore you must specify which host to access using a Host header.
The last item is actually the most important one in this case but the other points should be fixed too. Thus the correct request would look like this
mysock.send('GET /code/romeo.txt HTTP/1.0\r\nHost: www.py4inf.com\r\n\r\n')
For more information please study the HTTP standard, i.e. RFC 1945 for the simpler HTTP/1.0 and RFC 2616 for HTTP/1.1 which is more complex but more used in practice.
Try changing this linemysock.send('GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n') use this instead mysock.connect(('www.py4inf.com', 80))
mysock.send('GET /code/romeo.txt HTTP/1.0\nHost:www.py4inf.com\n\n'.encode())
the connection should look like this :
import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('www.py4inf.com', 80))
mysock.send('GET /code/romeo.txt HTTP/1.0\nHost:www.py4inf.com\n\n'.encode())
while True:
data = mysock.recv(512)
if (len(data) < 1):
break
print(data.decode(),end='')
mysock.close()
Here i made the change for you hope this will help :
Ps: also on line 19 Print (data) or you will get SyntaxError
import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
mysock.connect(('www.py4inf.com', 80))
#mysock.send('GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n')
mysock.send('GET /code/romeo.txt HTTP/1.0\nHost:www.py4inf.com\n\n'.encode())
except Exception as e:
print(e)
try:
while True:
data = mysock.recv(512)
if ( len(data) < 1 ) :
break
print (data)
except Exception as e:
print(e)
mysock.close()

Print 3000 first characters from the file online using sockets

So I am doing this ungraded assignment from an online course (so please do not hesitate to post solutions to this nemesis of mine).
Assignment open the file from the webpage using import socket,prompt the user for the url, print 3000 first characters including header, but count all of the characters in the file.
So first I have done this:
import socket
import re
url = raw_input('Enter - ')
try:
hostname = re.findall('http://(.+?)/', url)
hostname = hostname[0]
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect((hostname, 80))
mysock.send('GET ' + url + ' HTTP/1.0\n\n')
count = 0
text = str()
while True:
data = mysock.recv(512)
if ( len(data) < 1 ) :
break
count += len(data)
if count <= 3000:
print data
mysock.close()
except:
print 'Please enter a valid URL'
print count
But every time I adjust the buffer in the mysock.recv() the output changes and I get random spaces inside the text.
Then I've done this which eliminated the funky random splits in lines but the output still differs depending on the buffer inside.
import socket
import re
url = raw_input('Enter - ')
try:
hostname = re.findall('http://(.+?)/', url)
hostname = hostname[0]
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect((hostname, 80))
mysock.send('GET ' + url + ' HTTP/1.0\n\n')
count = 0
text = str()
while True:
data = mysock.recv(512)
if ( len(data) < 1 ) :
break
count += len(data)
if count <= 3000:
data.rstrip()
text = text + data
mysock.close()
except:
print 'Please enter a valid URL'
print text
print count
So I've been at it for several hours now and still can't get the exact same output regardless of the size of the buffer without funky line splitting spaces in there.
the file that I use: http://www.py4inf.com/code/romeo-full.txt
I'm studying on same book and i'm on same exercise. Question is 3 years old but don't give af, maybe is helpful for someone.
On first you can't print data in that way. You need something like this:
while True:
data = mysock.recv(512)
if len(data) < 1:
break
print(data.decode(),end='')
Also, it's perfectly normal that you haven't same results if you change the buffer 512 because count variable depends on it. Anyway the author asked just to stop after showing 3000 chars.
My full code (will works only with HTTP, HTTPS not handled):
import socket
import sys
import validators
import urllib.parse
url = input('Insert url to fetch: ')
# Test valid url
try:
valid = validators.url(url)
if valid != True:
raise ValueError
except ValueError:
print('url incorrect')
sys.exit()
# Test socket connection
try:
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('\nSocket successfully created')
except socket.error as err:
print('Socket creation failed with error %s' %(err))
# Extract hostname of url
parsed_url = urllib.parse.urlparse(url)
print('Resolving ->', parsed_url.netloc)
# Test if we can resolve the host
try:
host_ip = socket.gethostbyname(parsed_url.netloc)
except socket.gaierror:
print('Unable to resolve', parsed_url.netloc)
sys.exit()
# Connect to host
mysock.connect((parsed_url.netloc, 80))
# Crafting our command to send
cmd = ('GET ' + url + ' HTTP/1.0\r\n\r\n').encode()
# Sending our command
mysock.send(cmd)
count = 0
# Receive data
while True:
data = mysock.recv(500)
count += len(data)
if len(data) < 1:
break
if count > 3000:
break
print(data.decode(),end='')
mysock.close()
Could be the solution, maybe

print text file from web server to python program print errors

I'm trying to print a text a text file from a webserver in a python program but I am receiving errors. Any help would be greatly appreciated, here is my code:
import RPi.GPIO as GPIO
import urllib2
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(5,GPIO.OUT)
true = 1
while(true):
try:
response = urllib2.urlopen('http://148.251.158.132/k.txt')
status = response.read()
except urllib2.HTTPError, e:
print e.code
except urllib2.URLError, e:
print e.args
print status
if status=='bulbion':
GPIO.output(5,True)
elif status=='bulbioff':
GPIO.output(5,False)
By your comments, it appears your error: "SyntaxError: Missing parentheses in call to print", is caused by excluding parentheses/brackets in your print statements. People usually experience these errors after they update their python version, as the old print statements never required parentheses. The other error: "SyntaxError: unindent does not match any outer indentation level", is because your print statement on line 16 is one space behind all of your other statements on that indentation level, you can fix this problem by moving the print statement one space forward.
Changing your code to this should fix the problems:
import RPi.GPIO as GPIO
import urllib2
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(5,GPIO.OUT)
true = 1
while(true):
try:
response = urllib2.urlopen('http://148.251.158.132/k.txt')
status = response.read()
except urllib2.HTTPError, e:
print (e.code)
except urllib2.URLError, e:
print (e.args)
print (status)
if status=='bulbion':
GPIO.output(5,True)
elif status=='bulbioff':
GPIO.output(5,False)
Hope this helps!

Python 2.7 posting, and getting result from web site

I appreciate the help in advance. I am trying to write a python script that posts an IP address to a site referenced below, and get the results printed out in the terminal or file, and then read the file immediately after.
Here is my script:
#!/usr/bin/env python
import requests
IP = raw_input("Enter IP address here: ")
Alert_URL = 'http://www.blacklistalert.org'
def submit_form():
"""Submit a form"""
payload = IP
# make a get request
resp = requests.get(Alert_URL)
print "Response to GET request: %s" % resp.content
# send POST request
resp = requests.post(Alert_URL, payload)
print "Headers from a POST request response: %s" % resp.headers
# print "HTML Response: %s" %resp.read()
if __name__ == '__main__':
submit_form()
The site has section to input IP addresses on the web page, and inspecting the site I found lines to input as follows:
<form method=POST onsubmit="document.forms[0].submit.disabled='true';">
IP or Domain <input onclick="this.value='';" name=q value=11.11.154.23>
I would like to post an IP address that I want to check to the site using the input section above somehow. For instance using raw_input to post into the 'value=' section, and get the result.
Thanks for the help.
You need to parse the PHPSESSID and post:
import requests
from bs4 import BeautifulSoup
ip = raw_input("Enter IP address here: ")
data = {"q": ip} # ip goes here
url = "http://www.blacklistalert.org/"
with requests.Session() as s:
# get the page first to parse
soup = BeautifulSoup(s.get(url).content)
# extract and add the PHPSESSID
PHPSESSID = soup.select_one("input[name=PHPSESSID]")["value"]
data["PHPSESSID"] = PHPSESSID
# finally post
res = s.post(url, data=data)
print(res)
print(res.content)

Paramiko SSH - Multiple Authentication Credentials with Python

I have the following code:
import paramiko
import time
import re
import sys
import random
import fileinput
ip_address = raw_input("Enter a valid WAP IP: ")
#Open SSHv2 connection to devices
def open_ssh_conn(ip):
try:
#Logging into device
session = paramiko.SSHClient()
#AutoAddPolicy
session.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Passing the necessary
session.connect(ip, username = 'myUsername', password = 'myPassword')
#Start an interactive shell session on the switch
connection = session.invoke_shell()
#Commands
connection.send("enable\n")
time.sleep(1)
connection.send("show version\n")
time.sleep(1)
#Checking command output for IOS syntax errors
output = connection.recv(65535)
#Checking command output for IOS Syntax errors
if re.search(r"% Invalid input detected at", output):
print "* There was at least one IOS syntax error on device %s" % ip
else:
print "\nDONE for device %s" % ip
#Test for reading command output
print output + "\n"
#Closing the connection
session.close()
except paramiko.AuthenticationException:
print "* Invalid username or password. \n* Please check
the username/password file or the device configuration!"
print "* Closing program...\n"
#Calling the SSH function
open_ssh_conn(ip_address)
How can I test multiple credential without getting kick out of the program when an exception is caught?
for example, try this new credentials:
session.connect(ip, username = 'myNewUsername', password = 'myNewPassword')
I figured it out! I created a nested list with the credentials:
list = [['username1', 'password1'], ['username2', 'password2'], \
['username3', 'password3']]
Then, created a for loop and put my code inside:
for elem in list:
my code...
# this is the connect line:
session.connect(ip, username = elem[0], password = elem[1])
That did it!!!!