only getting blank response from http request - python

I am trying to send a HTTP request to a web-server, I'm really new to this - started yesterday so I'm probs being stupid but everytime I send a request I only get a blank response, here is my python code:
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('192.168.0.40', 80))
msg = 'GET /testPy.html HTTP/1.0'
client.send(msg.encode())
response = client.recv(4096)
print(response.decode())
Don't know if it is something with my python or if it is something i need to set up on the webserver, many thanks in advance
my console:
Emilians-MacBook-Pro:python emil$ python tcp.py
Emilians-MacBook-Pro:python emil$
there is around a 10s delay until the newline
when i do not decode the request it prints
Emilians-MacBook-Pro:python emil$ python tcp.py
b''
Emilians-MacBook-Pro:python emil$

Related

Simple TCP socket server, browser stalls on GET

I have the following code for a simple Server that handles GET requests from the browser over TCP.
while True:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('127.0.0.1', int(args.port)))
print(f'TCP Server listening on port {args.port}...')
s.listen()
connection, addr = s.accept()
print(f'Connected by {addr}')
while True:
data = connection.recv(args.buf)
if not data:
print('Connection closed')
break
message = data.decode()
response = handle_request(message)
connection.sendall(response)
connection.close()
This works somewhat, but not really. When the browser GETs a PNG or html file, that it has cached (if-modified-since), it works seamlessly. However, when it has to serve a new file, the browser (Safari) stalls until I shut down the server but then mysteriously shows the actual file the browser was trying to GET.
I wonder if this has something to do with my implementation of the connection, but I assume that it more likely has to do with my http headers.
This is what my simple headers and response to the browser look like:
header = f"HTTP/1.1 {status}\r\n" \
f"Host: {header_dict['host']}\r\n" \
f"Date: {datetime.today().strftime(time_format)}\r\n" \
f"Last-Modified: {mod_time}\r\n" \
f"Connection: Keep-Alive\r\n" \
f"\r\n".encode()
with open(filename, "rb") as f:
payload = f.read()
response = header + payload
Is there anything important missing from the header for Safari (or any other browser) to work with it? Thanks!
As KompjoeFriek commented, the browser needs to know how much data it is getting from the server. So the content-length header is necessary when handling a get request to serve some data. Without it, it waits until the connection is closed to show the data it has received. Adding a content-length header solved the problem.

How to read all data from Python socket.recv()?

I'm trying to send mails through smtp protocol in a very simple, basic code.
import socket
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 2525
clientSocket.connect(('localhost', port))
clientSocket.settimeout(5)
helo = 'HELO Me'
clientSocket.send(bytes(helo, 'utf-8'))
response = clientSocket.recv(1024).decode('utf-8')
print(f'Response: {response}')
# this response gets printed to the console
print('Succesfully connected via smtp')
mailFrom = 'MAIL FROM: myemail#gmail.com'
clientSocket.send(bytes(mailFrom, 'utf-8'))
response = clientSocket.recv(1024).decode('utf-8')
print(f'Response: {response}')
# here my program is blocked, and eventually gets a timeout
The problem is when I recieve the response, my, program stops running at the second response. I reckon my recv() function call is wrong, since if I change the first recv() buffersize to let's say 20, it works fine, so I guess there's still some data left in the socket. But how do I read it?

Cant download HTTP files through a python request

I have been working on this program which basically sends an HTML request to the specified server, but each time I run it to send a GET request it responds with a 404 not found page of that site. Can anybody please guide what am I doing wrong out here? I tried copying the Firefox HTML request file and sending that still no use.
import socket
server,port = 'google.com',80
ip = socket.gethostbyname(server)
print (ip)
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((server,port))
request = 'GET /HTTP/1.1\nHost: '+str(ip)+'\n\n'
print(request)
sock.sendall(request.encode())
while True:
data = ' '
data = sock.recv(4096)
if data == ' ':
break
print(data.decode())
And also what are the applications of socket module apart from creating remote servers?
I think your problem is your request. First, you need a space after that first /. Second, for the host, it should be www.google.com, not an IP address.
request = 'GET / HTTP/1.1 \nHost: www.google.com\n\n'
Also, you should change that first line to www.google.com, since it will redirect you there anyway:
server,port = 'www.google.com',80

Raw HTTP client not returning any data

import socket
host = 'www.google.com'
port = 80
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try :
client.connect((host, port))
except socket.error:
print ("Err")
package = '00101'
package.encode('utf-8')
client.sendall(package.encode(encoding = 'utf-8'))
response = client.recv(4096)
print (response.decode('UTF-8')
I kept getting b'' as my return, so I'm trying to decode it. The error I receive is unexpected EOF while parsing. Should I not include the decoding() function in my printing? I've tried printing only response, the .decode() function did not decode. What should I try?
You need to send a valid HTTP request. For example:
package = b'''GET /HTTP/1.1
Host: www.google.com
'''
client.sendall(package)
Which correctly returns a redirect on my machine. Note the empty line at the end of package, which ends the request.
When you send b'00101' and start reading, the google server has not yet processed your request and returns nothing. By sending a trailing newline (package = b'00101\n') it will start processing your request, and you will get:
...
<p>Your client has issued a malformed or illegal request. <ins>That’s all we know.</ins>

A simple HTTP server I built in Python works for Chrome but not in Firefox

So I built a very simple HTTP server in Python. It's purpose is to send a file when it gets a request.
This works in chrome but in Firefox it keeps downloading without making any progress. I also noticed that in Chrome, the name of the downloaded file is download.png where as the actual name of the file is s.png. Could someone tell me what is wrong with this code? Also I tried printing a message and sending html code too in firefox, it just keeps on showing the message "waiting on localhost" and does nothing.
import socket
serversocket = socket.socket()
serversocket.bind(("127.0.0.1", 80))
serversocket.listen(800)
msg = open("s.png", "r").read()
msg = "HTTP/1.0 200 OK\r\nServer: ls\r\nContent-Type: image/png\r\nContent-Disposition: attachement\r\nfilename: s.png\r\n\r\n" + msg + "\r\n\r\n"
while 1:
(clientsocket, address) = serversocket.accept()
clientsocket.send(msg)
Do not insert newline between Content-Disposition and the name of the file.
Using : between filename and the name of the file is also wrong.
I think you shouldn't add useless newlines after the image data.
Using binary mode is good for reading binary files.
You should close the connection after sending the message. Otherwise, the client cannot tell where the end of file is because you didn't send Content-Length header.
It seems good for Firefox to read the request before sending the response.
Try this (tested with Python 3.4.2 and Python 2.7.11):
import socket
serversocket = socket.socket()
serversocket.bind(("127.0.0.1", 80))
serversocket.listen(800)
msg = open("s.png", "rb").read()
msg = "HTTP/1.0 200 OK\r\nServer: ls\r\nContent-Type: image/png\r\nContent-Disposition: attachement; filename=s.png\r\n\r\n".encode('UTF-8') + msg
while True:
(clientsocket, address) = serversocket.accept()
recvdata = ''.encode('UTF-8')
while True:
recvdata += clientsocket.recv(4096)
if "\r\n\r\n".encode('UTF-8') in recvdata:
break
clientsocket.send(msg)
clientsocket.close()

Categories

Resources