0

I'm new to Python. I'm trying to write a program which is supposed to listen on a specific localhost port I've chosen and do some HTTP communications. I had initially been using a browser, but the browser isn't displaying the HTML response. So I wanted to test it using netcat, and that's where things got weird, because even though my browser can connect to the program fine and send it data (which the program receives), netcat says connection refused. What could cause this issue?

Python is set to bind to port 60504 so I tried nc -v 127.0.0.1 60504 from wsl. I expect that to connect to the socket, at which point I can send my own HTTP requests and see what is being sent back. However, I get the message nc: connect to 127.0.0.1 port 60504 (tcp) failed: Connection refused

import tkinter.messagebox as messagebox
import re
import configparser
import logging

import socket

import openai


HOST = "127.0.0.1"
PORT = 60504

CONFIG_PATH = "config"
config = configparser.ConfigParser()
config.read_file(open(CONFIG_PATH))

MODEL = config.get("AskVinci", "MODEL")
API_KEY = config.get("AskVinci", "OPENAPI_KEY")
MAX_TOKENS = int(config.get("AskVinci", "MAX_TOKENS"))
TEMPERATURE = float(config.get("AskVinci", "TEMPERATURE"))


def expandasciiescapes(text: str) -> str:
    """
    Replace all ASCII escapes in a URI with their corresponding characters.

    This function expects a properly formatted URI. Any occurence of the
    character '%' must be followed by a valid two-digit uppercase hex number.
    """
    i = 0
    while i < len(text):
        if text[i] == '%':
            str1 = text[:i:]
            str2 = "%(char)c" % {'char': int(text[i + 1:i + 3:], 16)}
            str3 = text[i + 3::]
            text = str1 + str2 + str3
        i += 1

    return text


with socket.socket() as localsock:
    logging.info("socket assigned")
    try:
        localsock.bind((HOST, PORT))
        logging.info("bound to {}:{}, listening...".format(HOST, PORT))
    except socket.error as e:
        messagebox.showerror(
            "AskVinci", "AskVinci: Could not bind to {}\n{}".format(PORT, str(e)))

    localsock.listen()

    # accept loop
    while True:
        clntconn, clntaddr = localsock.accept()
        with clntconn:
            logging.info("accepted connection from {}".format(clntaddr))
            # need to allow for requests > 4096 though! Also handle no input
            query = str(clntconn.recv(4096))
            if not query:
                continue
            query = query.split(" ")
            if len(query) < 2:
                continue
            query = query[1][1::]

            query = expandasciiescapes(query)
            if query == "favicon.ico":
                clntconn.send(bytes("HTTP/1.0 404 Not Found", "utf-8"))
                continue
            print("received query: \"{}\"".format(query)) # TODO: remove

            openai.api_key = API_KEY
            response = openai.Completion.create(
                model=MODEL,
                prompt=query,
                suffix="\n\n - DaVinci",
                max_tokens=MAX_TOKENS,
                temperature=TEMPERATURE
            )
            logging.debug("OpenAI response: " + str(response))
            textline = re.search(r"\"text[ -~]+\n", str(response))
            try:
                textline = textline.group(0) # TODO: slice this
            except IndexError as e:
                messagebox.showerror(
                    "AskVinci", "Askvinci: bad response format.\n{}".format(e))

            print(textline) # TODO: remove

            message = ("HTTP/1.0 200 OK\r\n"
                       "<html>\r\n"
                       "<body>\r\n"
                       + "<h1> Query: \"{}\"</h1>\r\n".format(query) +
                       "<h2>DaVinciSez:</h2>\r\n"
                       + "<p>{}</p>\r\n".format(textline) +
                       "</body>\r\n"
                       "</html>\r\n")

            clntconn.sendall(bytes(message, "utf-8"))
            clntconn.close()
            logging.info(str(clntaddr) + " closed.")
Rubén
  • 34,714
  • 9
  • 70
  • 166
  • Make sure you don't have a firewall blocking the port. – Barmar Jan 19 '23 at 23:52
  • @Barmar I already tried turning off windows defender and it didn't help. I also tried making an inbound port rule but I'm not familiar with firewalls so idk whether I did that correctly. But if it were a firewall issue, wouldn't it block the browser too? – Noam Bechhofer Jan 20 '23 at 00:38
  • Can you remove all the irrelevant code and make a [mre] that other people can try? – Barmar Jan 20 '23 at 00:39
  • Since you are using 127.0.0.1 - are the server and the `nc` client run in the same environment, i.e. both inside wsl? Given that it worked with your browser my guess is that the server and browser are running outside wsl - but 127.0.0.1 in wsl is not 127.0.0.1 outside wsl - see also https://superuser.com/questions/1594420/cant-access-127-0-0-180-outside-of-wsl2-ubuntu-20-04 – Steffen Ullrich Jan 20 '23 at 07:09
  • Apart from that the HTTP response you send is not proper HTTP. That's why the browser will not display it. But that's another question. – Steffen Ullrich Jan 20 '23 at 07:12
  • @SteffenUllrich Thank you! Incidentally, what's the issue with my HTML? – Noam Bechhofer Jan 20 '23 at 20:44
  • @NoamBechhofer: Absolutely wrong: Missing proper separation of HTTP header and body. Mostly wrong: Missing Content-Type information. No Content-Length given. – Steffen Ullrich Jan 20 '23 at 20:49

0 Answers0