Python向Clangd发送JSONRPC请求时Content-Length报错排查
向Clangd发送JSON请求时持续收到"缺少Content-Length头"警告的问题
问题场景
我尝试用Python向桌面端Clangd发送JSON请求,终端内Clangd输出如下警告:
I[15:52:46.580] Warning: Missing Content-Length header, or zero-length message.
"Content-Length": 53{
"jsonrpc": "2.0",
"id": 1,
"method": "exit"
}
但我已添加对应头信息,初始Python代码如下:
import argparse import sys if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-p", "--process_num", type=int, help="Clangd process number", required=True) parser.add_argument("-d", "--dry_run", action="store_true", help="Dry run") args = parser.parse_args() filepath = f"/proc/{args.process_num}/fd/0" my_content = """\ "Content-Length": 53 { "jsonrpc": "2.0", "id": 1, "method": "exit" }""" if args.dry_run: print(my_content.encode("utf-8")) sys.exit(0) with open(filepath, 'wb') as f: f.write(my_content.encode("utf-8"))
请问我是否遗漏了某些格式要求?
更新后的尝试
根据建议修改代码后,仍收到相同警告,修改后的代码如下:
import argparse import sys import json if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-p", "--process_num", type=int, help="Clangd process number", required=True) parser.add_argument("-d", "--dry_run", action="store_true", help="Dry run") args = parser.parse_args() filepath = f"/proc/{args.process_num}/fd/0" my_object = {} my_object["jsonrpc"] = "2.0" my_object["id"] = 1 my_object["method"] = "exit" my_content = json.dumps(my_object).encode() my_header = "Content-Length: {}\r\n\r".format(len(my_content)).encode("ascii") if args.dry_run: print(my_header) print(my_content) sys.exit(0) with open(filepath, 'wb') as f: f.write(my_header) f.write(my_content)
问题分析与解决方向
- Header格式错误:JSON-RPC的头部要求
Content-Length是无引号的键,且头部与正文必须用\r\n\r\n分隔。初始代码给Content-Length加了双引号,违反格式;更新后的代码头部结尾是\r\n\r,少了一个\n,需修正为\r\n\r\n。 - /proc/fd写入的缓冲问题:直接写入
/proc/{pid}/fd/0(进程标准输入)可能存在缓冲,写入的内容未被Clangd立即读取。可在写入后调用f.flush()强制刷新缓冲区,或改用os.write直接操作文件描述符。 - Content-Length计算验证:确保
len(my_content)是JSON正文的字节长度,json.dumps后的编码字节数需准确,避免计算错误导致解析失败。 - 更可靠的输入方式:如果可控Clangd启动流程,建议用
subprocess.Popen创建子进程,通过管道stdin.write发送请求,比直接写入/proc文件描述符更稳定。
示例修正点:
# 修正头部格式 my_header = f"Content-Length: {len(my_content)}\r\n\r\n".encode("ascii") # 写入后刷新缓冲区 with open(filepath, 'wb') as f: f.write(my_header) f.write(my_content) f.flush()
内容的提问来源于stack exchange,提问作者xBACP
相关产品推荐
相关产品推荐

