Python for Everyone - 12- HTTP C code not working

Hello, I´m following Dr. Chuck in part 12 to make a web server.
I had updated the URL to the current address of the text file his code is referencing, but when I run it in VS Code I receive this error message:

  File "c:\Users\Admin\Desktop\PY4E\ex_02_05\week_5.py", line 3, in <module>
    mysock.connect(('https:/www.py4e.com', 80))
socket.gaierror: [Errno 11001] getaddrinfo failed

When I run it on Replit.com, I receive this error message:

Traceback (most recent call last):
  File "main.py", line 3, in <module>
    mysock.connect(('https:/www.py4e.com', 80))
socket.gaierror: [Errno -2] Name or service not known

Am I doing something wrong with the port number? Should it be 443?

Where am I going wrong?

Thanks for any help you can provide.
Nick

https://docs.python.org/3/library/socket.html

You can lose the https:/

“A pair (host, port) is used for the AF_INET address family, where host is a string representing either a hostname in internet domain notation like 'daring.cwi.nl' or an IPv4 address like '100.50.200.5', and port is an integer.”

I redid the code. I am receiving a 400 error message, which means that i made a mistake. This is the error message:

HTTP/1.1 400 Bad Request
Server: cloudflare
Date: Mon, 05 Jun 2023 07:04:27 GMT
Content-Type: text/html
Content-Length: 155
Connection: close
CF-RAY: -

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>cloudflare</center>
</body>
</html>

Traceback (most recent call last):
  File "c:\Users\Admin\Desktop\PY4E\ex_02_05\week_5.py", line 8, in <module>
    data = mysock.recv(512)
OSError: [WinError 10038] An operation was attempted on something that is not a socket
import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('www.py4e.com', 80))
cmd = 'GET www.py4e.com/code3/romeo-full.txt HHTP/1.0\n\n'.encode()
mysock.send(cmd)

while True:
    data = mysock.recv(512)
    if (len(data) < 1):
        break
    print(data.decode())
    mysock.close()

It indicates an error on line 8, which is where I specify how many characters to receive. It says the socket is incorrect. What have I done wrong with setting up the socket?

import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('www.py4e.com', 80))
cmd = 'GET www.py4e.com/code3/romeo-full.txt HHTP/1.0\n\n'.encode()
mysock.send(cmd)

while True:
    data = mysock.recv(512)
    if (len(data) < 1):
        break
    print(data.decode())
    mysock.close()

Hello again! You’re busy

You successfully connect and receive an error code from the server, which is good.

At the end of your while True loop you have mysock.close() which closes your socket. But your loop continues to run

Why is it good to receive an error?

Also, the error said that I attempted an operation on something that was not a socket.
I thought that by importing socket and performing a socket function that it was a socket. What was non-socket about my supposed socket?

It’s good because you successfully connected to the server, you know the connection works. It’s just your HTTP request that needs attention.

Look at the logic of your loop:

At the end of the loop you close the socket, then you try to receive data again at the top.

Regarding the GET request, look at the example GET here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET

GET /index.html

So as I understand what was written in the example correct (GET - HTTP | MDN ),

The HTTP GET method requests a representation of the specified resource. Requests using GET should only be used to request data (they shouldn’t include data).

Referencing a .txt file in my GET methos would be “payload” and not a “representation”.
I’m sure I understand how they are using “representation”. At first I thought it meant just a URL ending in .html. I wrote (py4e.com/code3.html)…but I got the same error message as above. I don’t know what “representation” means in relation to the website I’m using in the GET method. Can someone help?

You don’t include the hostname in your request. You’ve already connected to the host. Look at this example again:

GET /index.html

and your request:

GET www.py4e.com/code3/romeo-full.txt

I already used

import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('www.py4e.com', 80))
cmd = 'GET /code3/romeo-full.txt HHTP/1.0\n\n'.encode()
mysock.send(cmd)

while True:
    data = mysock.recv(512)
    if (len(data) < 1):
        break
    print(data.decode())

and

import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('www.py4e.com', 80))
cmd = 'GET /romeo-full.txt HHTP/1.0\n\n'.encode()
mysock.send(cmd)

while True:
    data = mysock.recv(512)
    if (len(data) < 1):
        break
    print(data.decode())

and both times returned the same error message.I don’t understand why I’m getting a 400 error message when they URL works fine.

Something might be wrong with that website. It works if you use these lines with a different hostname:

mysock.connect(('data.pr4e.org', 80))
cmd = 'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n'.encode()

I found this URL info here: https://github.com/csev/py4e/blob/master/code3/socket1.py maybe it’s been changed / updated.

Also just to make note of this: https://github.com/csev/py4e/blob/master/code3/socket2.py

"# This is using HTTP 1.0 - not all servers support the oldest protocol
# Try http://data.pr4e.org/romeo.txt if your server fails."

I´m still getting a 400 error. Here is my code below.

import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('data.pr4e.org', 80))
cmd = 'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\n'.encode()
mysock.send(cmd)

while True:
    data = mysock.recv(512)
    if (len(data) < 1):
        break
    print(data.decode())

I’m going to try another website to see if I can make it work, but I’d really like to figure out what I’m doing wrong with this one. If you can, can you help me out?

cmd = 'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n'.encode()

You were missing one \r in this line

It worked.
I have a clarification question. So the use of ‘\r\n\r\n’ is to establish the line breaks in the .txt file. (Which would be referred to as a “payload”?)

No, it doesn’t affect the txt file that’s returned at all. I’m not sure but maybe it’s just to signal the end of the request string.

I would not get too hung up on the “payload” and “representation” terminology at this point. GET is a request for data and POST is to send data to the server, that is the distinction they are trying to make.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.