Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

TelnetServer recv error: Forcing an RST request to the telnet server can cause a crash

オープン 初心者向け
#2,073 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 4 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
68/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
静か
技術スタック
python
領域
networking

調査の方向性

prompt_toolkit/contrib/telnet/server.py の handle_incoming_data から始めます。traceback には、クライアントが RST を送信した後に conn.recv(1024) が ConnectionResetError を発生させていることが示されています。受信接続のエラーがどのように処理されているかを追跡し、提供されている socket client で報告を再現してください。クライアントによる突然のリセットによって、event-loop で未処理の例外が発生しなくなれば完了です。

索引モデルが issue の本文から書いたものです。

説明

TelnetServer and the local terminal start simultaneously.

#!/usr/bin/env python3

import asyncio
import logging
import errno

from prompt_toolkit import PromptSession
from prompt_toolkit.patch_stdout import patch_stdout
from prompt_toolkit.contrib.telnet.server import TelnetServer

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(message)s"
)

logger = logging.getLogger(__name__)


def install_asyncio_exception_filter(loop):
    old_handler = loop.get_exception_handler()

    def exception_handler(loop, context):
        exc = context.get("exception")
        print(1231231)

        if isinstance(exc, ConnectionResetError):
            return

        if isinstance(exc, OSError):
            if getattr(exc, "errno", None) in (
                errno.ECONNRESET,
                errno.EPIPE,
            ):
                return

        if old_handler:
            old_handler(loop, context)
        else:
            loop.default_exception_handler(context)

    loop.set_exception_handler(exception_handler)


async def interact(connection):
    peer = connection.addr
    print("666 Client connected:"+ str(peer))
    logger.info("Client connected: %s", peer)

    try:
        session = PromptSession()

        await connection.send(
            "\r\n"
            "====================================\r\n"
            " prompt_toolkit Telnet Demo\r\n"
            "====================================\r\n"
            "Type 'exit' to quit.\r\n\r\n"
        )

        while True:
            try:
                with patch_stdout():
                    text = await session.prompt_async(
                        "telnet> "
                    )

            except (EOFError, KeyboardInterrupt):
                break

            if text.lower() in ("exit", "quit"):
                break

            await connection.send(
                f"You typed: {text}\r\n"
            )
        '''
        except ConnectionResetError:
            logger.info("Client reset connection: %s", peer)

        except OSError as e:
            if e.errno in (
                errno.ECONNRESET,
                errno.EPIPE,
            ):
                logger.info(
                    "Client disconnected unexpectedly: %s",
                    peer,
                )
            else:
                raise
        '''

    except Exception:
        logger.exception(
            "Unhandled exception from %s",
            peer,
        )

    finally:
        logger.info("Client disconnected: %s", peer)


#!/usr/bin/env python3
from prompt_toolkit import PromptSession
from prompt_toolkit.patch_stdout import patch_stdout
from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.styles import Style
import asyncio

style = Style.from_dict({
    "prompt": "ansicyan bold",
    "command": "ansigreen",
    "error": "ansired bold",
})

async def main():
    loop = asyncio.get_running_loop()
    install_asyncio_exception_filter(loop)

    server = TelnetServer(
        host="0.0.0.0",
        port=8023,
        interact=interact,
    )

    asyncio.create_task( server.run() )

    print("Listening on 0.0.0.0:8023")




    session = PromptSession()

    print("Welcome to the demo interactive session!")
    print("Type 'exit' or 'quit' to leave.\n")

    while True:
        try:
            with patch_stdout():
                text = await session.prompt_async(HTML('<prompt>MyPrompt> </prompt>'), style=style)

        except (EOFError, KeyboardInterrupt):
            print("\n[Session terminated]")
            break

        text = text.strip()
        if not text:
            continue

        if text.lower() in ("exit", "quit"):
            print("[Goodbye]")
            break

        print(HTML(f"<command>You typed:</command> {text}"), style=style)


if __name__ == "__main__":
    asyncio.run(main())

Exploit/Client request:

import socket
import time

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", 8023))

s.send(b"hello")
time.sleep(1)


s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
             (1, 0))   # linger=0 -> RST

s.close()

Crash:

MyPrompt> 
MyPrompt> 2026-06-02 01:18:59,623 INFO New connection '127.0.0.1' 60252
2026-06-02 01:18:59,624 INFO Initializing telnet connection
2026-06-02 01:18:59,624 INFO Starting interaction '127.0.0.1' 60252
Press ENTER to continue...2026-06-02 01:19:00,642 INFO Connection closed by client. '127.0.0.1' 60252

Unhandled exception in event loop:
  File "/home/debian/.pyenv/versions/3.12.7/lib/python3.12/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "/home/debian/.pyenv/versions/3.12.7/lib/python3.12/site-packages/prompt_toolkit/contrib/telnet/server.py", line 185, in handle_incoming_data
    data = self.conn.recv(1024)
           ^^^^^^^^^^^^^^^^^^^^

Exception [Errno 104] Connection reset by peer
Press ENTER to continue...

主要言語
Python
スター
10.6k
フォーク
819
PR マージ指標
30日以内にマージされた PR はありません

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

prompt-toolkit/python-prompt-toolkit のほかの issue

prompt-toolkit/python-prompt-toolkit の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。