传递数据时python套接字http库post请求不起作用

2024-06-20 15:07:14 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,正如我的标题所说,Im制作了一个带有基本get和post请求的小http库。 我已经完成了get请求,但是我的post请求有点奇怪。 任何时候我把数据传递给post,它都不会得到响应。 当我不传递body属性(最后一个)时,它似乎工作得很好。 我试着用我自己的图书馆。在

谁能看出我做错了什么吗?我觉得我错过了一个头球,但我不知道是哪个。在

import socket
from urllib.parse import urlparse
import json

TCRLF = "\r\n\r\n"
CRLF = "\r\n"



def post(url, headers=None, data=""):

    connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    request = build_request("POST", url, headers, data)
    print("request: " + request)
    print("url:" + url)
    print("headers :" + str(headers))

    url = urlparse(url)

    connection.connect((url.hostname, url.port or 80))
    connection.sendall(request.encode("UTF-8"))
    response = connection.recv(4096).decode("UTF-8")
    print("response: " +  response)
    #
    # (response_header, response_body) = response.split(TCRLF)
    # response_body = json.loads(response_body)
    #
    # print(response_header)
    # print(response_body)

    return None

def build_request(req_type, url, headers=None, body=""):

    url = urlparse(url)

    hostname = url.hostname
    path = url.path or "/"
    query = url.query
    port = url.port or 80

    print("hostname" + hostname)
    print("path : " + path)
    print("query :" + query)
    print("port :" + str(port))
    print("body:" + str(body))

    uri = "{}?{}".format(path, query) if query else path

    formatted_headers = "".join(
        "{}:{}\r\n".format(k, v) for k, v in headers.items())


    print("formatted: "+ formatted_headers)

    requestGet = "GET " + uri + " HTTP/1.0" + CRLF + "Host:" + hostname + CRLF + formatted_headers + TCRLF

    ##TODO body failing when passing object
    requestPost = "POST " + uri + " HTTP/1.0" + CRLF + "Host: " + hostname + CRLF + "Content-Length: " + str(
        len(body)) + CRLF + formatted_headers + TCRLF + body + TCRLF

    print("Request" + requestPost)

    if req_type=="POST":
        return requestPost
    else:
        return requestGet


def main():
    post("http://httpbin.org/post", {"Content-Type": "application/json" }, "{'Assignment': 1}")

if __name__ == '__main__':
    main()

Tags: pathurlportresponserequestbodysocketquery
1条回答
网友
1楼 · 发布于 2024-06-20 15:07:14

我不知道你从哪里得到的HTTP知识。但是根据HTTP标准,GET和POST请求都不是正确的请求。对于GET,您在末尾添加了一个额外的\r\n(即GET / HTTP/1.0\r\nHost: example.com\r\n\r\n\r\n-最后一个\r\n太多),对于POST,您也这样做,并且在请求主体之后添加一些无效数据(TCRLF)。在

在请求头之后添加的这个额外的\r\n是根据您给出的Content-length计算的,这意味着服务器读取的HTTP主体比您预期的主体短两个字节。加上在正文后面发送的TRCLF,实际发送的HTTP正文比Content-Length头中给出的值长6个字节。在

请参考HTTP标准了解HTTP应该是什么样的-这就是标准的目的。不要试图通过查看互联网上的流量或代码示例来正确理解HTTP的工作原理。特别是简单的代码示例通常是错误的或不完整的,并且可能在某些服务器或某些用例中工作,但通常不适用。在

Anytime I pass data to the post, it doesn't get a response.

我不能重复说根本没有回复的说法。在获取未修改的代码时,我实际上从服务器得到了一个响应,其中包括响应主体的servers视图:

...    
"data": "\r\n{'Assignment': ", 
...

这是您想要的正文前缀是错误的\r\n,并缩短了两个字节以匹配所声明的Content-length。当修改代码以执行正确的请求时,我得到了预期的结果:

^{pr2}$

相关问题 更多 >