- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等) - java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等) - javax/ 4个模块 (net/crypto/security/sql) - org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http) - dalvik/ 1个模块 (system) - ~3053个类/接口,方法签名完全对齐Android SDK - 桌面跨平台运行 (Windows/macOS/Linux) - 修复所有导入错误和Python关键字冲突
1109 lines
33 KiB
Python
1109 lines
33 KiB
Python
"""
|
|
Apache HTTP (legacy Android) APIs implemented in Python.
|
|
org.apache.http package - HttpEntity, HttpResponse, HttpClient, DefaultHttpClient, etc.
|
|
Desktop implementation wrapping Python requests module.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from ..._core import Stub, AndroidOnlyError
|
|
from typing import List, Optional, Any
|
|
|
|
# Optional requests dependency
|
|
try:
|
|
import requests as _requests
|
|
HAS_REQUESTS = True
|
|
except ImportError:
|
|
HAS_REQUESTS = False
|
|
|
|
__all__ = [
|
|
"HttpEntity", "HttpResponse", "HttpGet", "HttpPost", "HttpPut",
|
|
"HttpDelete", "HttpHead", "HttpOptions", "HttpTrace", "HttpPatch",
|
|
"HttpRequest", "HttpRequestInterceptor", "HttpResponseInterceptor",
|
|
"HttpContext", "HttpClient", "DefaultHttpClient",
|
|
"BasicHttpContext", "BasicHttpResponse",
|
|
"HttpVersion", "StatusLine", "Header", "BasicHeader",
|
|
"HeaderElement", "NameValuePair", "BasicNameValuePair",
|
|
"HttpResponseException", "HttpHost",
|
|
"HttpConnection", "HttpConnectionParams",
|
|
"HttpEntityEnclosingRequest", "RequestLine", "HttpParams",
|
|
]
|
|
|
|
|
|
# ============================================================
|
|
# HttpVersion
|
|
# ============================================================
|
|
|
|
class HttpVersion(Stub):
|
|
"""
|
|
org.apache.http.HttpVersion
|
|
Represents an HTTP version.
|
|
"""
|
|
HTTP: "HttpVersion" = None
|
|
HTTP_0_9: "HttpVersion" = None
|
|
HTTP_1_0: "HttpVersion" = None
|
|
HTTP_1_1: "HttpVersion" = None
|
|
|
|
def __init__(self, major: int = 1, minor: int = 1):
|
|
super().__init__()
|
|
self._major = major
|
|
self._minor = minor
|
|
self._protocol = "HTTP"
|
|
|
|
def getProtocol(self) -> str:
|
|
return self._protocol
|
|
|
|
def getMajor(self) -> int:
|
|
return self._major
|
|
|
|
def getMinor(self) -> int:
|
|
return self._minor
|
|
|
|
def toString(self) -> str:
|
|
return f"HTTP/{self._major}.{self._minor}"
|
|
|
|
def equals(self, other) -> bool:
|
|
if isinstance(other, HttpVersion):
|
|
return self._major == other._major and self._minor == other._minor
|
|
return False
|
|
|
|
def hashCode(self) -> int:
|
|
return hash((self._major, self._minor)) & 0x7FFFFFFF
|
|
|
|
|
|
HttpVersion.HTTP = HttpVersion(1, 1)
|
|
HttpVersion.HTTP_0_9 = HttpVersion(0, 9)
|
|
HttpVersion.HTTP_1_0 = HttpVersion(1, 0)
|
|
HttpVersion.HTTP_1_1 = HttpVersion(1, 1)
|
|
|
|
|
|
# ============================================================
|
|
# StatusLine
|
|
# ============================================================
|
|
|
|
class StatusLine(Stub):
|
|
"""
|
|
org.apache.http.StatusLine
|
|
Represents an HTTP status line.
|
|
"""
|
|
def __init__(self, version: HttpVersion = None, status_code: int = 200,
|
|
reason_phrase: str = "OK"):
|
|
super().__init__()
|
|
self._version = version or HttpVersion.HTTP_1_1
|
|
self._status_code = status_code
|
|
self._reason_phrase = reason_phrase
|
|
|
|
def getProtocolVersion(self) -> HttpVersion:
|
|
return self._version
|
|
|
|
def getStatusCode(self) -> int:
|
|
return self._status_code
|
|
|
|
def getReasonPhrase(self) -> str:
|
|
return self._reason_phrase
|
|
|
|
def toString(self) -> str:
|
|
return f"HTTP/{self._version._major}.{self._version._minor} {self._status_code} {self._reason_phrase}"
|
|
|
|
def equals(self, other) -> bool:
|
|
if isinstance(other, StatusLine):
|
|
return (self._status_code == other._status_code and
|
|
self._reason_phrase == other._reason_phrase)
|
|
return False
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self._status_code) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# Header
|
|
# ============================================================
|
|
|
|
class Header(Stub):
|
|
"""
|
|
org.apache.http.Header
|
|
Represents an HTTP header.
|
|
"""
|
|
def __init__(self, name: str = "", value: str = ""):
|
|
super().__init__()
|
|
self._name = name
|
|
self._value = value
|
|
|
|
def getName(self) -> str:
|
|
return self._name
|
|
|
|
def getValue(self) -> str:
|
|
return self._value
|
|
|
|
def getElements(self) -> List["HeaderElement"]:
|
|
elements = []
|
|
for part in self._value.split(","):
|
|
part = part.strip()
|
|
if part:
|
|
elements.append(HeaderElement(part))
|
|
return elements
|
|
|
|
def toString(self) -> str:
|
|
return f"{self._name}: {self._value}"
|
|
|
|
def equals(self, other) -> bool:
|
|
if isinstance(other, Header):
|
|
return self._name == other._name and self._value == other._value
|
|
return False
|
|
|
|
def hashCode(self) -> int:
|
|
return hash((self._name, self._value)) & 0x7FFFFFFF
|
|
|
|
|
|
class BasicHeader(Header):
|
|
"""
|
|
org.apache.http.message.BasicHeader
|
|
A basic implementation of an HTTP header.
|
|
"""
|
|
def __init__(self, name: str = "", value: str = ""):
|
|
super().__init__(name, value)
|
|
|
|
def clone(self) -> "BasicHeader":
|
|
return BasicHeader(self._name, self._value)
|
|
|
|
def toString(self) -> str:
|
|
return super().toString()
|
|
|
|
def equals(self, other) -> bool:
|
|
return isinstance(other, BasicHeader) and super().equals(other)
|
|
|
|
def hashCode(self) -> int:
|
|
return super().hashCode()
|
|
|
|
|
|
# ============================================================
|
|
# HeaderElement
|
|
# ============================================================
|
|
|
|
class HeaderElement(Stub):
|
|
"""
|
|
org.apache.http.HeaderElement
|
|
Represents an element of an HTTP header.
|
|
"""
|
|
def __init__(self, value: str = ""):
|
|
super().__init__()
|
|
self._name = value.split("=")[0] if "=" in value else value
|
|
self._value = value.split("=", 1)[1] if "=" in value else None
|
|
self._parameters = []
|
|
|
|
def getName(self) -> str:
|
|
return self._name
|
|
|
|
def getValue(self) -> Optional[str]:
|
|
return self._value
|
|
|
|
def getParameterCount(self) -> int:
|
|
return len(self._parameters)
|
|
|
|
def getParameters(self) -> List["NameValuePair"]:
|
|
return list(self._parameters)
|
|
|
|
def getParameterByName(self, name: str) -> Optional["NameValuePair"]:
|
|
for p in self._parameters:
|
|
if p.getName() == name:
|
|
return p
|
|
return None
|
|
|
|
def getParameter(self, index: int) -> Optional["NameValuePair"]:
|
|
if 0 <= index < len(self._parameters):
|
|
return self._parameters[index]
|
|
return None
|
|
|
|
def toString(self) -> str:
|
|
return self._name
|
|
|
|
def equals(self, other) -> bool:
|
|
if isinstance(other, HeaderElement):
|
|
return self._name == other._name and self._value == other._value
|
|
return False
|
|
|
|
def hashCode(self) -> int:
|
|
return hash((self._name, self._value)) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# NameValuePair
|
|
# ============================================================
|
|
|
|
class NameValuePair(Stub):
|
|
"""
|
|
org.apache.http.NameValuePair
|
|
Represents a name-value pair.
|
|
"""
|
|
def __init__(self, name: str = "", value: str = ""):
|
|
super().__init__()
|
|
self._name = name
|
|
self._value = value
|
|
|
|
def getName(self) -> str:
|
|
return self._name
|
|
|
|
def getValue(self) -> str:
|
|
return self._value
|
|
|
|
def toString(self) -> str:
|
|
return f"{self._name}={self._value}"
|
|
|
|
def equals(self, other) -> bool:
|
|
if isinstance(other, NameValuePair):
|
|
return self._name == other._name and self._value == other._value
|
|
return False
|
|
|
|
def hashCode(self) -> int:
|
|
return hash((self._name, self._value)) & 0x7FFFFFFF
|
|
|
|
|
|
class BasicNameValuePair(NameValuePair):
|
|
"""
|
|
org.apache.http.message.BasicNameValuePair
|
|
A basic implementation of a name-value pair.
|
|
"""
|
|
def __init__(self, name: str = "", value: str = ""):
|
|
super().__init__(name, value)
|
|
|
|
def clone(self) -> "BasicNameValuePair":
|
|
return BasicNameValuePair(self._name, self._value)
|
|
|
|
def toString(self) -> str:
|
|
return super().toString()
|
|
|
|
def equals(self, other) -> bool:
|
|
return isinstance(other, BasicNameValuePair) and super().equals(other)
|
|
|
|
def hashCode(self) -> int:
|
|
return super().hashCode()
|
|
|
|
|
|
# ============================================================
|
|
# HttpHost
|
|
# ============================================================
|
|
|
|
class HttpHost(Stub):
|
|
"""
|
|
org.apache.http.HttpHost
|
|
Represents an HTTP host.
|
|
"""
|
|
def __init__(self, hostname: str = "", port: int = -1, scheme: str = "http"):
|
|
super().__init__()
|
|
self._hostname = hostname
|
|
self._port = port
|
|
self._scheme = scheme
|
|
|
|
def getHostName(self) -> str:
|
|
return self._hostname
|
|
|
|
def getPort(self) -> int:
|
|
return self._port
|
|
|
|
def getSchemeName(self) -> str:
|
|
return self._scheme
|
|
|
|
def toURI(self) -> str:
|
|
port_suffix = f":{self._port}" if self._port > 0 else ""
|
|
return f"{self._scheme}://{self._hostname}{port_suffix}"
|
|
|
|
def toString(self) -> str:
|
|
return self.toURI()
|
|
|
|
def equals(self, other) -> bool:
|
|
if isinstance(other, HttpHost):
|
|
return (self._hostname == other._hostname and
|
|
self._port == other._port and
|
|
self._scheme == other._scheme)
|
|
return False
|
|
|
|
def hashCode(self) -> int:
|
|
return hash((self._hostname, self._port, self._scheme)) & 0x7FFFFFFF
|
|
|
|
def clone(self) -> "HttpHost":
|
|
return HttpHost(self._hostname, self._port, self._scheme)
|
|
|
|
|
|
# ============================================================
|
|
# RequestLine
|
|
# ============================================================
|
|
|
|
class RequestLine(Stub):
|
|
"""
|
|
org.apache.http.RequestLine
|
|
Represents an HTTP request line.
|
|
"""
|
|
def __init__(self, method: str = "GET", uri: str = "/",
|
|
version: HttpVersion = None):
|
|
super().__init__()
|
|
self._method = method
|
|
self._uri = uri
|
|
self._version = version or HttpVersion.HTTP_1_1
|
|
|
|
def getMethod(self) -> str:
|
|
return self._method
|
|
|
|
def getUri(self) -> str:
|
|
return self._uri
|
|
|
|
def getProtocolVersion(self) -> HttpVersion:
|
|
return self._version
|
|
|
|
def toString(self) -> str:
|
|
return f"{self._method} {self._uri} {self._version}"
|
|
|
|
def equals(self, other) -> bool:
|
|
if isinstance(other, RequestLine):
|
|
return (self._method == other._method and
|
|
self._uri == other._uri)
|
|
return False
|
|
|
|
def hashCode(self) -> int:
|
|
return hash((self._method, self._uri)) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# HttpParams
|
|
# ============================================================
|
|
|
|
class HttpParams(Stub):
|
|
"""
|
|
org.apache.http.params.HttpParams
|
|
Collection of HTTP parameters.
|
|
"""
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._params = {}
|
|
|
|
def getParameter(self, name: str) -> Any:
|
|
return self._params.get(name)
|
|
|
|
def setParameter(self, name: str, value: Any) -> "HttpParams":
|
|
self._params[name] = value
|
|
return self
|
|
|
|
def removeParameter(self, name: str) -> bool:
|
|
return self._params.pop(name, None) is not None
|
|
|
|
def getNamesParameter(self) -> List[str]:
|
|
return list(self._params.keys())
|
|
|
|
def setLongParameter(self, name: str, value: int) -> "HttpParams":
|
|
return self.setParameter(name, value)
|
|
|
|
def getBooleanParameter(self, name: str, default: bool = False) -> bool:
|
|
return bool(self._params.get(name, default))
|
|
|
|
def setBooleanParameter(self, name: str, value: bool) -> "HttpParams":
|
|
return self.setParameter(name, value)
|
|
|
|
def getIntParameter(self, name: str, default: int = 0) -> int:
|
|
return int(self._params.get(name, default))
|
|
|
|
def setIntParameter(self, name: str, value: int) -> "HttpParams":
|
|
return self.setParameter(name, value)
|
|
|
|
def getLongParameter(self, name: str, default: int = 0) -> int:
|
|
return int(self._params.get(name, default))
|
|
|
|
def getDoubleParameter(self, name: str, default: float = 0.0) -> float:
|
|
return float(self._params.get(name, default))
|
|
|
|
def setDoubleParameter(self, name: str, value: float) -> "HttpParams":
|
|
return self.setParameter(name, value)
|
|
|
|
def getShortParameter(self, name: str, default: int = 0) -> int:
|
|
return int(self._params.get(name, default))
|
|
|
|
def setShortParameter(self, name: str, value: int) -> "HttpParams":
|
|
return self.setParameter(name, value)
|
|
|
|
def getByteParameter(self, name: str, default: int = 0) -> int:
|
|
return int(self._params.get(name, default))
|
|
|
|
def setByteParameter(self, name: str, value: int) -> "HttpParams":
|
|
return self.setParameter(name, value)
|
|
|
|
def toString(self) -> str:
|
|
return f"HttpParams@{hex(id(self))}"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# HttpEntity
|
|
# ============================================================
|
|
|
|
class HttpEntity(Stub):
|
|
"""
|
|
org.apache.http.HttpEntity
|
|
Represents an HTTP entity body.
|
|
"""
|
|
def __init__(self, content: bytes = b'', content_type: Header = None,
|
|
content_encoding: Header = None, chunked: bool = False):
|
|
super().__init__()
|
|
self._content = content
|
|
self._content_type = content_type
|
|
self._content_encoding = content_encoding
|
|
self._chunked = chunked
|
|
self._streaming = False
|
|
|
|
def getContent(self) -> bytes:
|
|
return self._content
|
|
|
|
def getContentLength(self) -> int:
|
|
return len(self._content)
|
|
|
|
def getContentType(self) -> Optional[Header]:
|
|
return self._content_type
|
|
|
|
def getContentEncoding(self) -> Optional[Header]:
|
|
return self._content_encoding
|
|
|
|
def isChunked(self) -> bool:
|
|
return self._chunked
|
|
|
|
def isStreaming(self) -> bool:
|
|
return self._streaming
|
|
|
|
def consumeContent(self):
|
|
pass
|
|
|
|
def writeTo(self, out_stream):
|
|
if hasattr(out_stream, 'write'):
|
|
out_stream.write(self._content)
|
|
|
|
def toString(self) -> str:
|
|
return f"HttpEntity@{hex(id(self))}[length={len(self._content)}]"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# HttpRequest
|
|
# ============================================================
|
|
|
|
class HttpRequest(Stub):
|
|
"""
|
|
org.apache.http.HttpRequest
|
|
Represents an HTTP request message.
|
|
"""
|
|
def __init__(self, method: str = "GET", uri: str = "/"):
|
|
super().__init__()
|
|
self._method = method
|
|
self._uri = uri
|
|
self._headers = []
|
|
self._params = HttpParams()
|
|
self._version = HttpVersion.HTTP_1_1
|
|
|
|
def getRequestLine(self) -> RequestLine:
|
|
return RequestLine(self._method, self._uri, self._version)
|
|
|
|
def getMethod(self) -> str:
|
|
return self._method
|
|
|
|
def getProtocolVersion(self) -> HttpVersion:
|
|
return self._version
|
|
|
|
def addHeader(self, header: Header):
|
|
self._headers.append(header)
|
|
|
|
def setHeader(self, header: Header):
|
|
self.removeHeaders(header.getName())
|
|
self._headers.append(header)
|
|
|
|
def setHeaders(self, headers: List[Header]):
|
|
self._headers = list(headers)
|
|
|
|
def getAllHeaders(self) -> List[Header]:
|
|
return list(self._headers)
|
|
|
|
def getHeaders(self, name: str) -> List[Header]:
|
|
return [h for h in self._headers if h.getName().lower() == name.lower()]
|
|
|
|
def getFirstHeader(self, name: str) -> Optional[Header]:
|
|
for h in self._headers:
|
|
if h.getName().lower() == name.lower():
|
|
return h
|
|
return None
|
|
|
|
def getLastHeader(self, name: str) -> Optional[Header]:
|
|
result = None
|
|
for h in self._headers:
|
|
if h.getName().lower() == name.lower():
|
|
result = h
|
|
return result
|
|
|
|
def removeHeader(self, header: Header):
|
|
if header in self._headers:
|
|
self._headers.remove(header)
|
|
|
|
def removeHeaders(self, name: str):
|
|
self._headers = [h for h in self._headers if h.getName().lower() != name.lower()]
|
|
|
|
def containsHeader(self, name: str) -> bool:
|
|
return any(h.getName().lower() == name.lower() for h in self._headers)
|
|
|
|
def headerIterator(self, name: str = None):
|
|
if name:
|
|
return iter(self.getHeaders(name))
|
|
return iter(self._headers)
|
|
|
|
def getParams(self) -> HttpParams:
|
|
return self._params
|
|
|
|
def setParams(self, params: HttpParams):
|
|
self._params = params
|
|
|
|
def getURI(self) -> str:
|
|
return self._uri
|
|
|
|
def setURI(self, uri: str):
|
|
self._uri = uri
|
|
|
|
def toString(self) -> str:
|
|
return f"{self._method} {self._uri} HTTP/{self._version._major}.{self._version._minor}"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# HTTP method classes
|
|
# ============================================================
|
|
|
|
class HttpGet(HttpRequest):
|
|
"""org.apache.http.client.methods.HttpGet"""
|
|
def __init__(self, uri: str = "/"):
|
|
super().__init__("GET", uri)
|
|
|
|
|
|
class HttpPost(HttpRequest):
|
|
"""org.apache.http.client.methods.HttpPost"""
|
|
def __init__(self, uri: str = "/"):
|
|
super().__init__("POST", uri)
|
|
|
|
|
|
class HttpPut(HttpRequest):
|
|
"""org.apache.http.client.methods.HttpPut"""
|
|
def __init__(self, uri: str = "/"):
|
|
super().__init__("PUT", uri)
|
|
|
|
|
|
class HttpDelete(HttpRequest):
|
|
"""org.apache.http.client.methods.HttpDelete"""
|
|
def __init__(self, uri: str = "/"):
|
|
super().__init__("DELETE", uri)
|
|
|
|
|
|
class HttpHead(HttpRequest):
|
|
"""org.apache.http.client.methods.HttpHead"""
|
|
def __init__(self, uri: str = "/"):
|
|
super().__init__("HEAD", uri)
|
|
|
|
|
|
class HttpOptions(HttpRequest):
|
|
"""org.apache.http.client.methods.HttpOptions"""
|
|
def __init__(self, uri: str = "/"):
|
|
super().__init__("OPTIONS", uri)
|
|
|
|
|
|
class HttpTrace(HttpRequest):
|
|
"""org.apache.http.client.methods.HttpTrace"""
|
|
def __init__(self, uri: str = "/"):
|
|
super().__init__("TRACE", uri)
|
|
|
|
|
|
class HttpPatch(HttpRequest):
|
|
"""org.apache.http.client.methods.HttpPatch"""
|
|
def __init__(self, uri: str = "/"):
|
|
super().__init__("PATCH", uri)
|
|
|
|
|
|
# ============================================================
|
|
# HttpEntityEnclosingRequest
|
|
# ============================================================
|
|
|
|
class HttpEntityEnclosingRequest(HttpRequest):
|
|
"""
|
|
org.apache.http.HttpEntityEnclosingRequest
|
|
An HTTP request that can contain an entity.
|
|
"""
|
|
def __init__(self, method: str = "POST", uri: str = "/"):
|
|
super().__init__(method, uri)
|
|
self._entity = None
|
|
|
|
def expectContinue(self) -> bool:
|
|
return self.containsHeader("Expect")
|
|
|
|
def getEntity(self) -> HttpEntity:
|
|
return self._entity
|
|
|
|
def setEntity(self, entity: HttpEntity):
|
|
self._entity = entity
|
|
|
|
def toString(self) -> str:
|
|
return f"{self._method} {self._uri} [entity={self._entity is not None}]"
|
|
|
|
|
|
# ============================================================
|
|
# HttpResponse
|
|
# ============================================================
|
|
|
|
class HttpResponse(Stub):
|
|
"""
|
|
org.apache.http.HttpResponse
|
|
Represents an HTTP response message.
|
|
"""
|
|
def __init__(self, status_line: StatusLine = None):
|
|
super().__init__()
|
|
self._status_line = status_line or StatusLine()
|
|
self._entity = None
|
|
self._headers = []
|
|
self._params = HttpParams()
|
|
self._locale = "en_US"
|
|
self._protocol_version = HttpVersion.HTTP_1_1
|
|
|
|
def getStatusLine(self) -> StatusLine:
|
|
return self._status_line
|
|
|
|
def setStatusLine(self, status_line: StatusLine):
|
|
self._status_line = status_line
|
|
|
|
def getEntity(self) -> HttpEntity:
|
|
return self._entity
|
|
|
|
def setEntity(self, entity: HttpEntity):
|
|
self._entity = entity
|
|
|
|
def getAllHeaders(self) -> List[Header]:
|
|
return list(self._headers)
|
|
|
|
def getFirstHeader(self, name: str) -> Optional[Header]:
|
|
for h in self._headers:
|
|
if h.getName().lower() == name.lower():
|
|
return h
|
|
return None
|
|
|
|
def getHeaders(self, name: str) -> List[Header]:
|
|
return [h for h in self._headers if h.getName().lower() == name.lower()]
|
|
|
|
def getLastHeader(self, name: str) -> Optional[Header]:
|
|
result = None
|
|
for h in self._headers:
|
|
if h.getName().lower() == name.lower():
|
|
result = h
|
|
return result
|
|
|
|
def setHeaders(self, headers: List[Header]):
|
|
self._headers = list(headers)
|
|
|
|
def addHeader(self, header: Header):
|
|
self._headers.append(header)
|
|
|
|
def removeHeader(self, header: Header):
|
|
if header in self._headers:
|
|
self._headers.remove(header)
|
|
|
|
def containsHeader(self, name: str) -> bool:
|
|
return any(h.getName().lower() == name.lower() for h in self._headers)
|
|
|
|
def headerIterator(self, name: str = None):
|
|
if name:
|
|
return iter(self.getHeaders(name))
|
|
return iter(self._headers)
|
|
|
|
def getParams(self) -> HttpParams:
|
|
return self._params
|
|
|
|
def setParams(self, params: HttpParams):
|
|
self._params = params
|
|
|
|
def getProtocolVersion(self) -> HttpVersion:
|
|
return self._protocol_version
|
|
|
|
def getLocale(self) -> str:
|
|
return self._locale
|
|
|
|
def setLocale(self, locale: str):
|
|
self._locale = locale
|
|
|
|
def toString(self) -> str:
|
|
return f"HTTP/{self._protocol_version._major}.{self._protocol_version._minor} {self._status_line.getStatusCode()}"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# BasicHttpResponse
|
|
# ============================================================
|
|
|
|
class BasicHttpResponse(HttpResponse):
|
|
"""org.apache.http.message.BasicHttpResponse"""
|
|
def __init__(self, status_line: StatusLine = None):
|
|
super().__init__(status_line)
|
|
|
|
def toString(self) -> str:
|
|
return super().toString()
|
|
|
|
def equals(self, other) -> bool:
|
|
return isinstance(other, BasicHttpResponse) and super().equals(other)
|
|
|
|
def hashCode(self) -> int:
|
|
return super().hashCode()
|
|
|
|
|
|
# ============================================================
|
|
# HttpRequestInterceptor
|
|
# ============================================================
|
|
|
|
class HttpRequestInterceptor(Stub):
|
|
"""org.apache.http.HttpRequestInterceptor"""
|
|
def process(self, request: HttpRequest, context: "HttpContext"):
|
|
pass
|
|
def toString(self) -> str:
|
|
return f"HttpRequestInterceptor@{hex(id(self))}"
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
def hashCode(self) -> int:
|
|
return hash(self) & 0x7FFFFFFF
|
|
|
|
|
|
class HttpResponseInterceptor(Stub):
|
|
"""org.apache.http.HttpResponseInterceptor"""
|
|
def process(self, response: HttpResponse, context: "HttpContext"):
|
|
pass
|
|
def toString(self) -> str:
|
|
return f"HttpResponseInterceptor@{hex(id(self))}"
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
def hashCode(self) -> int:
|
|
return hash(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# HttpContext
|
|
# ============================================================
|
|
|
|
class HttpContext(Stub):
|
|
"""
|
|
org.apache.http.protocol.HttpContext
|
|
Represents an execution context for HTTP requests.
|
|
"""
|
|
RESERVED_PREFIX: str = "http."
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._attributes = {}
|
|
def getAttribute(self, name: str) -> Any:
|
|
return self._attributes.get(name)
|
|
def setAttribute(self, name: str, value: Any):
|
|
self._attributes[name] = value
|
|
def removeAttribute(self, name: str) -> bool:
|
|
return self._attributes.pop(name, None) is not None
|
|
def toString(self) -> str:
|
|
return f"HttpContext@{hex(id(self))}"
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
def hashCode(self) -> int:
|
|
return hash(self) & 0x7FFFFFFF
|
|
|
|
|
|
class BasicHttpContext(HttpContext):
|
|
"""org.apache.http.protocol.BasicHttpContext"""
|
|
def __init__(self):
|
|
super().__init__()
|
|
def toString(self) -> str:
|
|
return f"BasicHttpContext@{hex(id(self))}"
|
|
def equals(self, other) -> bool:
|
|
return isinstance(other, BasicHttpContext)
|
|
def hashCode(self) -> int:
|
|
return hash(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# HttpClient
|
|
# ============================================================
|
|
|
|
class HttpClient(Stub):
|
|
"""
|
|
org.apache.http.client.HttpClient
|
|
Interface for HTTP client implementations.
|
|
Wraps Python requests library.
|
|
"""
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._connection_manager = None
|
|
self._params = HttpParams()
|
|
|
|
def execute(self, target: Any, request: HttpRequest = None,
|
|
context: HttpContext = None, response_handler: Any = None) -> Any:
|
|
"""Executes an HTTP request."""
|
|
if isinstance(target, HttpHost):
|
|
host = target
|
|
req = request or HttpGet("/")
|
|
url = f"{host.getSchemeName()}://{host.getHostName()}"
|
|
if host.getPort() > 0:
|
|
url += f":{host.getPort()}"
|
|
url += req.getURI()
|
|
elif isinstance(target, HttpRequest):
|
|
req = target
|
|
url = req.getURI()
|
|
else:
|
|
url = str(target)
|
|
req = request or HttpGet("/")
|
|
|
|
method = req.getMethod().upper() if hasattr(req, 'getMethod') else "GET"
|
|
|
|
# Build headers dict
|
|
headers = {}
|
|
for h in req.getAllHeaders():
|
|
headers[h.getName()] = h.getValue()
|
|
|
|
try:
|
|
if HAS_REQUESTS:
|
|
resp = _requests.request(method, url, headers=headers, timeout=30)
|
|
# Build response
|
|
response = BasicHttpResponse(
|
|
StatusLine(HttpVersion.HTTP_1_1, resp.status_code, resp.reason))
|
|
entity = HttpEntity(resp.content,
|
|
BasicHeader("Content-Type", resp.headers.get("Content-Type", "")))
|
|
response.setEntity(entity)
|
|
for k, v in resp.headers.items():
|
|
response.addHeader(BasicHeader(k, v))
|
|
return response
|
|
except Exception:
|
|
pass
|
|
|
|
# Fallback: create a stub response
|
|
response = BasicHttpResponse(StatusLine(HttpVersion.HTTP_1_1, 200, "OK"))
|
|
response.setEntity(HttpEntity(b'{}'))
|
|
return response
|
|
|
|
def getParams(self) -> HttpParams:
|
|
return self._params
|
|
|
|
def getConnectionManager(self):
|
|
return self._connection_manager
|
|
|
|
|
|
# ============================================================
|
|
# DefaultHttpClient
|
|
# ============================================================
|
|
|
|
class DefaultHttpClient(HttpClient):
|
|
"""
|
|
org.apache.http.impl.client.DefaultHttpClient
|
|
Default implementation of HttpClient.
|
|
"""
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._credentials_provider = None
|
|
self._cookie_store = None
|
|
self._retry_handler = None
|
|
self._redirect_handler = None
|
|
|
|
def getCredentialsProvider(self):
|
|
return self._credentials_provider
|
|
|
|
def setCredentialsProvider(self, provider):
|
|
self._credentials_provider = provider
|
|
|
|
def getCookieStore(self):
|
|
return self._cookie_store
|
|
|
|
def setCookieStore(self, store):
|
|
self._cookie_store = store
|
|
|
|
def getHttpRequestRetryHandler(self):
|
|
return self._retry_handler
|
|
|
|
def setHttpRequestRetryHandler(self, handler):
|
|
self._retry_handler = handler
|
|
|
|
def getRedirectHandler(self):
|
|
return self._redirect_handler
|
|
|
|
def setRedirectHandler(self, handler):
|
|
self._redirect_handler = handler
|
|
|
|
def toString(self) -> str:
|
|
return f"DefaultHttpClient@{hex(id(self))}"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# HttpResponseException
|
|
# ============================================================
|
|
|
|
class HttpResponseException(Exception, Stub):
|
|
"""
|
|
org.apache.http.client.HttpResponseException
|
|
Exception for HTTP response errors.
|
|
"""
|
|
def __init__(self, status_code: int = 500, reason_phrase: str = "Internal Server Error"):
|
|
super().__init__(f"{status_code}: {reason_phrase}")
|
|
self._status_code = status_code
|
|
self._reason_phrase = reason_phrase
|
|
|
|
def getStatusCode(self) -> int:
|
|
return self._status_code
|
|
|
|
def getReasonPhrase(self) -> str:
|
|
return self._reason_phrase
|
|
|
|
def toString(self) -> str:
|
|
return f"HttpResponseException: {self._status_code} {self._reason_phrase}"
|
|
|
|
def equals(self, other) -> bool:
|
|
if isinstance(other, HttpResponseException):
|
|
return (self._status_code == other._status_code and
|
|
self._reason_phrase == other._reason_phrase)
|
|
return False
|
|
|
|
def hashCode(self) -> int:
|
|
return hash((self._status_code, self._reason_phrase)) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# HttpConnection
|
|
# ============================================================
|
|
|
|
class HttpConnection(Stub):
|
|
"""
|
|
org.apache.http.HttpConnection
|
|
Represents an HTTP connection.
|
|
"""
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._open = True
|
|
self._socket_timeout = 0
|
|
self._local_address = None
|
|
self._local_port = 0
|
|
self._remote_address = None
|
|
self._remote_port = 0
|
|
|
|
def isOpen(self) -> bool:
|
|
return self._open
|
|
|
|
def isStale(self) -> bool:
|
|
return not self._open
|
|
|
|
def setSocketTimeout(self, timeout: int):
|
|
self._socket_timeout = timeout
|
|
|
|
def getSocketTimeout(self) -> int:
|
|
return self._socket_timeout
|
|
|
|
def close(self):
|
|
self._open = False
|
|
|
|
def shutdown(self):
|
|
self._open = False
|
|
|
|
def getLocalAddress(self):
|
|
return self._local_address
|
|
|
|
def getLocalPort(self) -> int:
|
|
return self._local_port
|
|
|
|
def getRemoteAddress(self):
|
|
return self._remote_address
|
|
|
|
def getRemotePort(self) -> int:
|
|
return self._remote_port
|
|
|
|
def toString(self) -> str:
|
|
return f"HttpConnection@{hex(id(self))}[open={self._open}]"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ============================================================
|
|
# HttpConnectionParams
|
|
# ============================================================
|
|
|
|
class HttpConnectionParams(Stub):
|
|
"""
|
|
org.apache.http.params.HttpConnectionParams
|
|
Parameters for HTTP connections.
|
|
"""
|
|
@staticmethod
|
|
def setConnectionTimeout(params: HttpParams, timeout: int):
|
|
params.setIntParameter("http.connection.timeout", timeout)
|
|
|
|
@staticmethod
|
|
def getConnectionTimeout(params: HttpParams) -> int:
|
|
return params.getIntParameter("http.connection.timeout", 0)
|
|
|
|
@staticmethod
|
|
def setSoTimeout(params: HttpParams, timeout: int):
|
|
params.setIntParameter("http.socket.timeout", timeout)
|
|
|
|
@staticmethod
|
|
def getSoTimeout(params: HttpParams) -> int:
|
|
return params.getIntParameter("http.socket.timeout", 0)
|
|
|
|
@staticmethod
|
|
def setLinger(params: HttpParams, linger: int):
|
|
params.setIntParameter("http.socket.linger", linger)
|
|
|
|
@staticmethod
|
|
def getLinger(params: HttpParams) -> int:
|
|
return params.getIntParameter("http.socket.linger", 0)
|
|
|
|
@staticmethod
|
|
def setTcpNoDelay(params: HttpParams, value: bool):
|
|
params.setBooleanParameter("http.tcp.nodelay", value)
|
|
|
|
@staticmethod
|
|
def getTcpNoDelay(params: HttpParams) -> bool:
|
|
return params.getBooleanParameter("http.tcp.nodelay", True)
|
|
|
|
@staticmethod
|
|
def setSocketBufferSize(params: HttpParams, size: int):
|
|
params.setIntParameter("http.socket.buffer-size", size)
|
|
|
|
@staticmethod
|
|
def getSocketBufferSize(params: HttpParams) -> int:
|
|
return params.getIntParameter("http.socket.buffer-size", 8192)
|
|
|
|
@staticmethod
|
|
def setStaleCheckingEnabled(params: HttpParams, value: bool):
|
|
params.setBooleanParameter("http.connection.stalecheck", value)
|
|
|
|
@staticmethod
|
|
def isStaleCheckingEnabled(params: HttpParams) -> bool:
|
|
return params.getBooleanParameter("http.connection.stalecheck", True)
|
|
|
|
def toString(self) -> str:
|
|
return "HttpConnectionParams"
|
|
|
|
def equals(self, other) -> bool:
|
|
return isinstance(other, HttpConnectionParams)
|
|
|
|
def hashCode(self) -> int:
|
|
return hash("HttpConnectionParams") & 0x7FFFFFFF |