因此,正如我的标题所述,我制作了一个带有基本get和post请求的小型http库。 我已经完成了get请求,但是我的发帖请求很奇怪。 每当我将数据传递到帖子时,都不会得到响应。 当我不传递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()
答案 0 :(得分:1)
body = '{"name":"mandar"}'
length = len(body)
#request = "GET / HTTP/1.1\r\nHost:%s\r\nUser-Agent: Mandar\r\n\r\n" % serverHost
p = HttpParser()
request = "POST / HTTP/1.1\r\nHost:{0}\r\nUser-Agent:Mandar\r\nContent-Type: application/json\r\nContent-Length: {1}\r\n\r\n{2}\r\n".format(serverHost, length, body)
答案 1 :(得分:0)
我不知道您从哪里获得HTTP知识。但是,根据HTTP标准,您的GET和POST请求都不是正确的请求。对于GET,您将在末尾添加一个额外的\r\n
(即GET / HTTP/1.0\r\nHost: example.com\r\n\r\n\r\n
-最后一个\r\n
太多),而对于POST,您将添加同样的内容,并添加一些无效数据({{ 1}})之后。
在将请求标头计入您提供的TCRLF
之后,您添加的这个额外\r\n
意味着服务器读取的HTTP正文比您想要的正文短了两个字节。与在正文之后发送的Content-length
一起,实际发送的HTTP正文比在TRCLF
标头中提供的值长6个字节。
请参阅HTTP标准以了解HTTP的外观-这就是标准的用途。不要仅仅通过查看在Internet上发现的流量或代码示例来尝试正确理解HTTP的工作方式。特别简单的代码示例通常是错误的或不完整的,并且可能在某些服务器或某些用例中可以使用,但通常不能使用。
每当我将数据传递到帖子时,都不会得到响应。
我无法重现根本没有返回任何答复的说法。当获取未经修改的代码时,我实际上从服务器获得响应,其中包括响应主体的服务器视图:
Content-Length
这是您要放置的正文,前面带有错误的...
"data": "\r\n{'Assignment': ",
...
,并缩短了两个字节以匹配声明的\r\n
。当修改您的代码以在正确的位置进行正确的请求而没有错误的Content-length
时,我得到了预期的结果:
\r\n