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>
Related
I'm sending data in a TCP client in python and the tutorial I'm following is telling me to send this:
"GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"
I've tried looking up information about the formatting here and I'm confused about what the GET is actually requesting or what data would be sent back by this request, and also what is the purpose of the carriage returns and newlines?
If want to write low-level HTTP GET in Python then you can create a TCP Socket and write the GET command optionally with header parameters then read the response.
The HTTP request starts with a Request-line (e.g. GET / HTTP/1.1 with a terminating CRLF or "\r\n"). The request line is followed by zero or more headers each ending with a CRLF. A final CRLF sequence marks the end of the request line and header part of the HTTP request followed by an optional message body. The request structure is defined in section 5 of the HTTP 1.1 spec
import socket
# host and port map to URL http://localhost:8000/
host = "localhost"
port = 8000
try:
sock = socket.socket()
sock.connect((host, port))
sock.sendall("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n".encode())
# keep reading from socket until no more data in response
while True:
response = sock.recv(8096)
if len(response) == 0:
break
print(response)
except Exception as ex:
print("I/O Error:", ex)
The first line of the HTTP response is the status line including status code terminated with \r\n and followed by response headers.
HTTP/1.1 200 OK\r\n
Content-type: text/plain\r\n
Content-length: 14\r\n
\r\n
This is a test
You need to parse the status line and headers to determine how to decode the message body of the HTTP response.
Details of the HTTP response are in section 6 of the HTTP 1.1 Spec.
Alternatively, the requests module implements the HTTP spec in a simple API.
Example to make a HTTP GET using requests API.
import requests
url = 'http://localhost:8000/'
response = requests.get(url)
print("Status code:", response.status_code)
print("Content:", response.text)
So, i am trying to create a simple server on python and trying to access a html file in the same directory through it, but as the output i keep on getting ready to serve...
output
EDIT:
Put an HTML file (e.g., HelloWorld.html) in the same directory that the server is in. Run the server program. Determine the IP address of the host that is running the server (e.g., 128.238.251.26). From another host, open a browser and provide the corresponding URL. For example:
http://128.238.251.26:6789/HelloWorld.html
‘HelloWorld.html’ is the name of the file you placed in the server directory. Note also the use of the port number after the colon. You need to replace this port number with whatever port you have used in the server code. In the above example, we have used the port number 6789. The browser should then display the contents of HelloWorld.html. If you omit ":6789", the browser will assume port 80 and you will get the web page from the server only if your server is listening at port 80.
Then try to get a file that is not present at the server. You should get a “404 Not Found” message.
#import socket module
from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM)
#Prepare a sever socket
serverSocket.bind(('', 12006))
serverSocket.listen(1)
while True:
print 'Ready to serve...'
#Establish the connection
connectionSocket, addr = serverSocket.accept()
try:
message = connectionSocket.recv(1024)
filename = message.split()[1]
f = open(filename[1:])
outputdata = f.read()
f.close()
#Send one HTTP header line into socket
connectionSocket.send('HTTP/1.0 200 OK\r\n\r\n')
#Send the content of the requested file to the client
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i])
connectionSocket.close()
except IOError:
#Send response message for file not found
connectionSocket.send('404 Not Found')
#Close client socket
connectionSocket.close()
serverSocket.close()
Your output is a standart output, that used through print function. you should to make a request to your server and you'll get the correct output
If your server on your local machine, you should use localhost address; if not, you should use your server ip. Also you should to specify a port. 12006 in your case. localhost:12006 as an example
Also socket.send method requires a byte-like object. not string
If it's only a string literal, you should to add a b character before the first quotation mark
Example:
connectionSocket.send(b'HTTP/1.0 200 OK\r\n\r\n')
If it is a string object, you should to encode it:
connectionSocket.send(outputdata[i].encode())
Check out the documentation
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$
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()
When I run below python script and try to do a GET request for a .html file via safari, I get the content in raw format i.e. along with the HTML tags. How do I retrieve html pages and also if I do a GET for images it says the file is damaged.
from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM) #create a socket
serverPort = 7000
serverSocket.bind(('',serverPort))
serverSocket.listen(1)
while True:
print 'Ready to serve . . .'
connectionSocket, addr = serverSocket.accept() #create socket for client
try:
message =connectionSocket.recv(1024) #receive message from client
print message
filename = message.split()[1]
f = open(filename[1:])
outputdata =f.read()
#Send HTTP header line into socket
connectionSocket.send('\nHTTP/1.x 200 OK\n')
#Send contents of the requested file to the client
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i])
connectionSocket.close()
print 'File Received'
except IOError:
connectionSocket.send('\n404 File Not Found\n')
connectionSocket.close()
serverSocket.close()
You need to tell the client that you are sending HTML back. Before sending the data add:
connectionSocket.send("Content-type: text/html\r\n")
Also, you may be seeing the HTTP response header you're sending back as well, right? If so, that's because you have a leading \n which terminates the headers and makes the rest of the body that gets sent back, so change that line to
connectionSocket.send('HTTP/1.x 200 OK\r\n')
and make sure you put a blank line when you are done with all the headers, and also that end of line in HTTP should be \r\n not just \n though I wouldn't be surprised if browsers handled it with just \n