This commit is contained in:
HIllya51 2024-01-11 00:21:58 +08:00
parent c990426f63
commit e9b7655e4d
3 changed files with 60 additions and 56 deletions

View File

@ -92,14 +92,14 @@ class Session(Sessionbase):
curl_easy_setopt(curl,CURLoption.CURLOPT_HEADERFUNCTION,winsharedutils.WriteMemoryCallback)
self._perform(curl)
self.rawdata=self._getmembyte(_content)
self._update_header_cookie(self._getmembyte(_headers).decode('utf8'))
resp=Response()
resp.content=self._getmembyte(_content)
resp.status_code=self._getStatusCode(curl)
self.status_code=self._getStatusCode(curl)
return self
def iter_content(self,chunk_size=1024):
yield self.content
resp.headers=self._update_header_cookie(self._getmembyte(_headers).decode('utf8'))
resp.cookies=self.cookies
return resp
Sessionimpl[0]=Session
if __name__=='__main__':
pass

View File

@ -46,21 +46,40 @@ class CaseInsensitiveDict(MutableMapping):
def __repr__(self):
return str(dict(self.items()))
class Response:
def __init__(self):
self.headers=CaseInsensitiveDict()
self.cookies={}
self.status_code=0
self.content=b'{}'
@property
def text(self):
try:
return self.content.decode(self.charset)
except:
raise Exception('unenable to decode with {}'.format(self.charset))
@property
def charset(self):
content_type=self.headers.get('Content-Type','')
m = re.search(r"charset=([\w-]+)", content_type)
charset = m.group(1) if m else "utf-8"
return charset
def json(self):
return json.loads(self.text)
def iter_content(self,chunk_size=1024):
yield self.content
class Sessionbase:
def __init__(self) -> None:
self.UA='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
self.last_error=0
self.status_code=0
self.rawdata=b'{}'
self.cookies={}
self.dfheaders=CaseInsensitiveDict({
self.headers=CaseInsensitiveDict({
"User-Agent": self.UA,
"Accept-Encoding": 'gzip, deflate, br',
"Accept": "*/*",
"Connection": "keep-alive",
})
self.headers=CaseInsensitiveDict()
def __enter__(self):
return self
def __exit__(self, *args):
@ -151,8 +170,9 @@ class Sessionbase:
_c.append('{}={}'.format(k,v))
return '; '.join(_c)
def _update_header_cookie(self,headerstr):
self.headers,cookies=self._parseheader2dict(headerstr)
headers,cookies=self._parseheader2dict(headerstr)
self.cookies.update(cookies)
return headers
def _parseheader2dict(self,headerstr):
#print(headerstr)
header=CaseInsensitiveDict()
@ -166,25 +186,6 @@ class Sessionbase:
else:
header[line[:idx]]=line[idx+2:]
return CaseInsensitiveDict(header),cookie
def decompress_impl(self,data,encode):
return data
@property
def content(self):
return self.decompress_impl(self.rawdata,self.headers.get('Content-Encoding',None))
@property
def text(self):
try:
return self.content.decode(self.charset)
except:
raise Exception('unenable to decode with {}'.format(self.charset))
@property
def charset(self):
content_type=self.headers.get('Content-Type','')
m = re.search(r"charset=([\w-]+)", content_type)
charset = m.group(1) if m else "utf-8"
return charset
def json(self):
return json.loads(self.text)
def request_impl(self,*args):
pass
@ -193,7 +194,7 @@ class Sessionbase:
auth=None, timeout=None, allow_redirects=True, hooks=None, stream=None, verify=False, cert=None, ):
headers=CaseInsensitiveDict(headers if headers else {})
headers.update(self.dfheaders)
headers.update(self.headers)
if auth and isinstance(auth,tuple) and len(auth)==2:
headers['Authorization']="Basic " + ( base64.b64encode(b":".join((auth[0].encode("latin1"), auth[1].encode("latin1")))).strip() ).decode()

View File

@ -7,6 +7,18 @@ try:
from brotli_dec import decompress
except:
pass
class winhttp_resp(Response):
def iter_content(self,chunk_size=1024):
downloadedSize=DWORD()
buff=create_string_buffer(chunk_size)
while True:
succ=WinHttpReadData(self.hreq,buff,chunk_size,pointer(downloadedSize))
if succ==0:raise WinhttpException(GetLastError())
if downloadedSize.value==0:
del self.hreq
del self.hconn
break
yield buff[:downloadedSize.value]
class Session(Sessionbase):
def __init__(self) -> None:
super().__init__()
@ -68,13 +80,15 @@ class Session(Sessionbase):
if succ==0:
raise WinhttpException(GetLastError())
self._update_header_cookie(self._getheaders(hRequest))
self.status_code=self._getStatusCode(hRequest)
headers=self._update_header_cookie(self._getheaders(hRequest))
resp=winhttp_resp()
resp.status_code=self._getStatusCode(hRequest)
resp.headers=headers
resp.cookies=self.cookies
if stream:
self.hconn=hConnect
self.hreq=hRequest
return self
resp.hconn=hConnect
resp.hreq=hRequest
return resp
availableSize=DWORD()
downloadedSize=DWORD()
downloadeddata=b''
@ -85,30 +99,19 @@ class Session(Sessionbase):
if availableSize.value==0:
break
buff=create_string_buffer(availableSize.value)
#这里可以做成流式的
succ=WinHttpReadData(hRequest,buff,availableSize,pointer(downloadedSize))
if succ==0:raise WinhttpException(GetLastError())
downloadeddata+=buff[:downloadedSize.value]
self.rawdata=downloadeddata
#print(self.text)
resp.content=self.decompress(downloadeddata,headers)
return self
def iter_content(self,chunk_size=1024):
downloadedSize=DWORD()
buff=create_string_buffer(chunk_size)
while True:
succ=WinHttpReadData(self.hreq,buff,chunk_size,pointer(downloadedSize))
if succ==0:raise WinhttpException(GetLastError())
if downloadedSize.value==0:
del self.hreq
del self.hconn
break
yield buff[:downloadedSize.value]
def decompress_impl(self,data,encode):
return resp
def decompress(self,data,headers):
#WINHTTP_OPTION_DECOMPRESSION
#支持gzip和deflateWINHTTP_DECOMPRESSION_FLAG_GZIP|WINHTTP_DECOMPRESSION_FLAG_DEFLATE
#但只支持win8.1+,不支持br
encode=headers.get('Content-Encoding',None)
try:
if encode =='gzip':
data=gzip.decompress(data)