1

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?

jamiet
  • 10,501
  • 14
  • 80
  • 159
  • 1
    The error you see has nothing to do with curl but with trying to use Python 2 semantic for `sendto` with Python 3: [TypeError: a bytes-like object is required, not 'str'](https://stackoverflow.com/questions/33003498/typeerror-a-bytes-like-object-is-required-not-str) – Steffen Ullrich Aug 04 '23 at 04:34
  • 1
    Apart from that: curl is for HTTP protocol, which is not the protocol spoken here. You cannot use curl for this, since this is not a HTTP server.. You will simply get `Received HTTP/0.9 when not allowed` back (once the `sendto` error got fixed). It's basically like asking how to make some client speaking only English to communicate with a server which speaks only French. – Steffen Ullrich Aug 04 '23 at 04:36
  • 1
    i think it's supposed to be `sock.send(quote.encode("utf-8"))` (or some such) – hanshenrik Aug 04 '23 at 12:49

2 Answers2

1
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"))
hanshenrik
  • 19,904
  • 4
  • 43
  • 89
  • As does the UTF8 encoding. https://gist.github.com/alphaolomi/51f27912abe699dd5db95cfbc21d1a2d?permalink_comment_id=4655847#gistcomment-4655847 – jamiet Aug 09 '23 at 08:10
0

PHP cURL is primarily designed for making HTTP requests,

However, it can also be used to make requests to other protocols, such as FTP, FTPS, SCP, SFTP, LDAP, and more. but it doesn't support the Quote of the Day (QOTD) protocol, out of the box. The QOTD protocol is a simple protocol that runs on port 17 and provides a quote of the day from a server.

However, you can use PHP's sockets to establish a connection to the QOTD server and retrieve the quote.

<?php

// Define the QOTD server's address and port
$serverAddress = '127.0.0.1';
$serverPort = 17;

// Establish a connection to the QOTD server
$socket = stream_socket_client("tcp://$serverAddress:$serverPort", $errno, $errstr, 30);

// Check if the connection was successful
if (!$socket) {
    echo "Error: $errno - $errstr";
} else {
    // Read the quote from the server
    $quote = fgets($socket);

    // Close the connection
    fclose($socket);

    // Output the quote
    echo "Quote of the Day: $quote";
}

Alpha Olomi
  • 115
  • 9