Search code examples
curltcp

How can I send a request to port 17 using curl?


TCP port 17 is used for quote-of-the-day. For a bit of fun I've stood up a what is effectively a qotd server using a simple bit of python:

import socket
import random

quotes = [
    "Never do today what you can do tomorrow",
    "Nobody lies on the internet",
    "The cake is a lie"
]

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("0.0.0.0", 17)) # Bind to port 17
server.listen(5)

while True:
    sock, addr = server.accept()
    quote = random.choice(quotes)
    sock.send(f"{quote}\n")
    sock.close()

which was provided at https://gist.github.com/alphaolomi/51f27912abe699dd5db95cfbc21d1a2d#file-main-py.

I now want to send a request to it using curl. I tried: curl 127.0.0.1:17 which failed with error:

curl: (56) Recv failure: Connection reset by peer

and my qotd "server" immediately errored with:

Traceback (most recent call last):
File "/private/tmp/test-mysqlclient-in-devcontainer/tst/main.py", line 17, in sock.send(f"{quote}\n")
TypeError: a bytes-like object is required, not 'str'

screenshot of python app failing

How can I use curl to send a valid request so I get a quote back?


Solution

  • printf "" | curl telnet://127.0.0.1:17
    

    works :) (not sure why curl isn't detecting the socket closing without sending feof on stdin, but it isn't... thus the printf)

    raw tcp connections isn't really a job suited for curl tho, it's a job suited for netcat:

    nc 127.0.0.1 17
    

    also work

    Traceback (most recent call last): File "/private/tmp/test-mysqlclient-in-devcontainer/tst/main.py", line 17, in sock.send(f"{quote}\n") TypeError: a bytes-like object is required, not 'str'

    my best guess is that the code is written for Python2, and in Python2 it is legal to send strings through socket.send, and you are trying to run the code on python3 - a python3 compatible replacement would be

    sock.send(quote.encode("utf-8"))