requrst 1.0.0__tar.gz → 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: requrst
3
- Version: 1.0.0
3
+ Version: 2.0.0
4
4
  Summary: 纯Python Socket手写HTTP/HTTPS客户端,零第三方依赖,第二方自研请求库
5
5
  Home-page:
6
6
  Author:
@@ -0,0 +1,14 @@
1
+ from .core import (
2
+ get, post, Session, Response, RequestContext,
3
+ register_before_request, extract_html_text, send_email,
4
+ DEFAULT_VERIFY, DEFAULT_TIMEOUT, DEFAULT_RETRY,
5
+ DEFAULT_MAX_REDIRECTS, DEFAULT_HEADERS
6
+ )
7
+
8
+ __version__ = "2.0.0"
9
+ __all__ = [
10
+ "get", "post", "Session", "Response", "RequestContext",
11
+ "register_before_request", "extract_html_text", "send_email",
12
+ "DEFAULT_VERIFY", "DEFAULT_TIMEOUT", "DEFAULT_RETRY",
13
+ "DEFAULT_MAX_REDIRECTS", "DEFAULT_HEADERS"
14
+ ]
@@ -14,18 +14,6 @@ DEFAULT_RETRY = 1
14
14
  DEFAULT_MAX_REDIRECTS = 3
15
15
  DEFAULT_VERIFY = True
16
16
 
17
- def recv_all(sock, buf_size=4096):
18
- data = b""
19
- while True:
20
- try:
21
- chunk = sock.recv(buf_size)
22
- if not chunk:
23
- break
24
- data += chunk
25
- except (socket.timeout, ConnectionResetError):
26
- break
27
- return data
28
-
29
17
  def recv_smtp_line(sock):
30
18
  resp = b""
31
19
  while True:
@@ -136,67 +124,46 @@ def _socket_request(host, path, port, scheme, method, headers, body=b"", timeout
136
124
  req_data = "\r\n".join(req_lines).encode("utf-8") + body
137
125
  sock.sendall(req_data)
138
126
 
139
- # 读取响应头
140
- resp_data = b""
141
- while True:
142
- chunk = sock.recv(4096)
143
- if not chunk:
144
- break
145
- resp_data += chunk
146
- if b"\r\n\r\n" in resp_data:
147
- break
148
-
149
- header_end = resp_data.find(b"\r\n\r\n")
150
- if header_end == -1:
151
- return Response(0, {}, b"Invalid HTTP response")
152
-
153
- header_part = resp_data[:header_end].decode("utf-8", errors="ignore")
154
- body_part = resp_data[header_end + 4:]
155
-
156
- first_line = header_part.splitlines()[0]
157
- parts = first_line.split()
127
+ sock_file = sock.makefile("rb")
128
+ status_line = sock_file.readline().decode("utf-8").strip()
129
+ parts = status_line.split()
158
130
  status_code = int(parts[1]) if len(parts) > 1 else 0
159
131
 
160
- resp_headers = {}
161
- for line in header_part.splitlines()[1:]:
132
+ headers_dict = {}
133
+ while True:
134
+ line = sock_file.readline().decode("utf-8").strip()
135
+ if not line:
136
+ break
162
137
  if ": " in line:
163
138
  k, v = line.split(": ", 1)
164
- resp_headers[k.strip()] = v.strip()
165
-
166
- # 根据 Content-Length 或 chunked 继续读取剩余正文
167
- content_length = resp_headers.get("Content-Length")
168
- transfer_encoding = resp_headers.get("Transfer-Encoding", "").lower()
139
+ headers_dict[k] = v
169
140
 
141
+ transfer_encoding = headers_dict.get("Transfer-Encoding", "").lower()
170
142
  if transfer_encoding == "chunked":
171
- sock.settimeout(timeout)
143
+ chunked_data = b""
172
144
  while True:
173
- try:
174
- chunk = sock.recv(4096)
175
- if not chunk:
176
- break
177
- body_part += chunk
178
- if b"0\r\n\r\n" in body_part:
179
- break
180
- except socket.timeout:
145
+ line = sock_file.readline().decode("utf-8").strip()
146
+ if not line:
181
147
  break
182
- body_part = _parse_chunked_body(body_part)
183
- elif content_length:
184
- content_length = int(content_length)
185
- received = len(body_part)
186
- while received < content_length:
187
- try:
188
- chunk = sock.recv(min(4096, content_length - received))
189
- if not chunk:
190
- break
191
- body_part += chunk
192
- received += len(chunk)
193
- except socket.timeout:
148
+ chunk_size = int(line, 16)
149
+ if chunk_size == 0:
150
+ sock_file.readline()
194
151
  break
195
-
152
+ chunk = sock_file.read(chunk_size)
153
+ chunked_data += chunk
154
+ sock_file.readline()
155
+ body_part = chunked_data
156
+ else:
157
+ content_length = headers_dict.get("Content-Length")
158
+ if content_length:
159
+ body_part = sock_file.read(int(content_length))
160
+ else:
161
+ body_part = sock_file.read()
162
+ sock_file.close()
196
163
  sock.close()
197
164
 
198
165
  if status_code in (301, 302, 303, 307, 308) and max_redirects > 0:
199
- location = resp_headers.get("Location", "")
166
+ location = headers_dict.get("Location", "")
200
167
  if location:
201
168
  parsed = urlparse(location)
202
169
  if not parsed.netloc:
@@ -205,7 +172,7 @@ def _socket_request(host, path, port, scheme, method, headers, body=b"", timeout
205
172
  return _request(location, new_method, headers, body if new_method != "GET" else b"",
206
173
  timeout, verify, retry, max_redirects - 1)
207
174
 
208
- return Response(status_code, resp_headers, body_part)
175
+ return Response(status_code, headers_dict, body_part)
209
176
 
210
177
  except (socket.timeout, ConnectionError, ssl.SSLError) as e:
211
178
  if sock:
@@ -311,6 +278,7 @@ def extract_html_text(html: str) -> str:
311
278
  text = re.sub(r"\s+", " ", text).strip()
312
279
  return text
313
280
 
281
+
314
282
  def send_email(smtp_server, smtp_port, sender_email, sender_pwd, to_email, subject, content):
315
283
  try:
316
284
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: requrst
3
- Version: 1.0.0
3
+ Version: 2.0.0
4
4
  Summary: 纯Python Socket手写HTTP/HTTPS客户端,零第三方依赖,第二方自研请求库
5
5
  Home-page:
6
6
  Author:
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="requrst",
5
- version="1.0.0",
5
+ version="2.0.0",
6
6
  author="",
7
7
  author_email="",
8
8
  description="纯Python Socket手写HTTP/HTTPS客户端,零第三方依赖,第二方自研请求库",
@@ -1,8 +0,0 @@
1
- from .core import (
2
- get, post, Session, Response, RequestContext,
3
- register_before_request, extract_html_text, send_email,
4
- DEFAULT_VERIFY, DEFAULT_TIMEOUT, DEFAULT_RETRY,
5
- DEFAULT_MAX_REDIRECTS, DEFAULT_HEADERS
6
- )
7
-
8
- __version__ = "1.0.0"
File without changes
File without changes
File without changes