When you send requests via socket you need to ensure to carefully follow the protocol in which the server is expecting. It seems that in this case the server expects valid HTTP/1.1 messages, and so you must strictly follow the protocol. In this case, a simple GET call would need to look something like so:
GET / HTTP/1.1
Host: example.com
Connection: close
Accept: */*
However, note that each line must be escaped properly with what is defined in RFC7230, section 3, Message Format as CRLF, which is simply \r\n, and one extra one at the end of your message. Therefore, the above message would actually look like so:
GET / HTTP/1.1\r\nHost: example.com\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n
If you are wanting to send raw messages like the above, I recommend checking out two possible modules that can make your life a little bit easier:
- httpsuite: (disclaimer: I am the author) allows easy manipulation of
HTTP/1.1 requests for socket purposes.
- h11: Similar to the above, but I have personally not used it (found it after writing my module above).
You can make your life a little bit easier by abstracting away from socket, and instead using something like requests, which will allow you to more easily send a GET requests:
import requests
requests.get("http://example.com")
If you are interacting with different protocols (like SFTP, SSH, etc.) I would recommend finding modules that abstract away from the raw socket requests, and use them in conjunction. Messing with raw HTTP requests (and/or other protocol) requires a certain level of "confidence" in regards to how the server is bound to reply, and usually these modules will abstract a lot of the backend heavy work (e.g. in the case of HTTP/1.1 200-299 and 300-399 response codes).