0brine
0brine

Reputation: 486

Python TCP socket send String

When sending get in putty the server response with HTTP/1.1 400 Bad Request
this is perfectly fine as i am only checking if the server is up and running.

Now i am trying to automate the process in python, but s.send("get".encode()) seems to do nothing, how do I use s.send()?

the s.recv(1024).decode("utf-8") works fine tho

I am also using the same program to check other ports as well.

import socket

host = "webmail"
port = 80

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

s.send("get".encode())
print(s.recv(1024).decode("utf-8"))

Upvotes: 0

Views: 2024

Answers (2)

felipe
felipe

Reputation: 8025

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).

Upvotes: 1

0brine
0brine

Reputation: 486

President James K. Polk:

@0brine: This answer shows a minimal correct string to send, however, each "newline" needs to be a carriage-return linefeed pair, e.g. b'\r\n'. Thus s.sendall(b'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\nAccept: /\r\n') should suffice. –

Upvotes: 0

Related Questions