diff --git a/LunaTranslator/LunaTranslator/network/libcurl/requests.py b/LunaTranslator/LunaTranslator/network/libcurl/requests.py index 12b10922..e21cdc67 100644 --- a/LunaTranslator/LunaTranslator/network/libcurl/requests.py +++ b/LunaTranslator/LunaTranslator/network/libcurl/requests.py @@ -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 \ No newline at end of file diff --git a/LunaTranslator/LunaTranslator/network/requests_common.py b/LunaTranslator/LunaTranslator/network/requests_common.py index 3b1e1c4b..e3ca959c 100644 --- a/LunaTranslator/LunaTranslator/network/requests_common.py +++ b/LunaTranslator/LunaTranslator/network/requests_common.py @@ -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() diff --git a/LunaTranslator/LunaTranslator/network/winhttp/requests.py b/LunaTranslator/LunaTranslator/network/winhttp/requests.py index b0a17419..053912a9 100644 --- a/LunaTranslator/LunaTranslator/network/winhttp/requests.py +++ b/LunaTranslator/LunaTranslator/network/winhttp/requests.py @@ -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和deflate,WINHTTP_DECOMPRESSION_FLAG_GZIP|WINHTTP_DECOMPRESSION_FLAG_DEFLATE #但只支持win8.1+,不支持br + encode=headers.get('Content-Encoding',None) try: if encode =='gzip': data=gzip.decompress(data)