Skip to content

Commit a84aa93

Browse files
committed
feat: config.Provider has new poperty: type; allow future support with other uri's beginning with http/https.
1 parent 9d31f56 commit a84aa93

14 files changed

Lines changed: 255 additions & 112 deletions

File tree

Dockerfile

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,23 @@ COPY docker /app
1919
COPY requirements.d /app/requirements.d
2020

2121
RUN \
22-
# install build's depends ---
23-
apk add --no-cache --virtual .build-deps build-base libffi-dev openldap-dev \
22+
# install python depends ---
23+
apk add --no-cache --virtual .build-deps build-base libffi-dev \
24+
# --- LDAP
25+
openldap-dev \
26+
# --- WebHDFS
27+
krb5-dev \
28+
# --- build & install
2429
&& pip install --no-cache-dir -r /app/requirements.d/docker.txt \
25-
# cleanup ---
30+
# --- cleanup
2631
&& apk del .build-deps \
2732
&& rm -rf /root/.cache \
2833
&& find /usr/local/lib/python*/ -type f -name '*.py[cod]' -delete \
2934
&& find /usr/local/lib/python*/ -type d -name "__pycache__" -delete \
3035
# LDAP client's depends ---
3136
&& apk add --no-cache libsasl libldap \
3237
# create non-root user ---
33-
&& apk add --no-cache shadow su-exec\
38+
&& apk add --no-cache shadow su-exec \
3439
&& addgroup -S -g $GID runner \
3540
&& adduser -S -D -G runner -u $UID -s /bin/sh runner \
3641
# support timezone ---

asgi_webdav/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ class Provider:
7575

7676
prefix: str
7777
uri: str
78+
type: str = ""
79+
7880
home_dir: bool = False
7981
read_only: bool = False
8082
ignore_property_extra: bool = True

asgi_webdav/exception.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ class DAVExceptionRequestParserFailed(DAVException):
1111

1212

1313
class DAVExceptionProviderInitFailed(DAVException):
14-
"""will be trigger sys.exit(?)"""
15-
1614
pass
1715

1816

asgi_webdav/provider/dev_provider.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121

2222
class DAVProvider:
23+
type: str
24+
2325
def __init__(
2426
self,
2527
config: Config,

asgi_webdav/provider/file_system.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ async def _dav_response_data_generator(
140140

141141

142142
class FileSystemProvider(DAVProvider):
143+
type = "fs"
144+
143145
def __init__(self, *args, **kwargs):
144146
super().__init__(*args, **kwargs)
145147
self.support_content_range = True

asgi_webdav/provider/memory.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ def copy_member(
205205

206206

207207
class MemoryProvider(DAVProvider):
208+
type = "memory"
209+
208210
def __init__(self, *args, **kwargs):
209211
super().__init__(*args, **kwargs)
210212
self.support_content_range = True

asgi_webdav/provider/webhdfs.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ class FileStatus(TypedDict):
3434

3535

3636
class WebHDFSProvider(DAVProvider):
37+
type = "webhdfs"
38+
3739
def __init__(self, *args, **kwargs):
38-
if not httpx or not HTTPKerberosAuth:
40+
if httpx is None or HTTPKerberosAuth is None:
3941
raise DAVExceptionProviderInitFailed(
4042
"httpx and httpx_kerberos are required for WebHDFSProvider, please check your installation"
4143
)

asgi_webdav/web_dav.py

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from os import getenv
55

66
from asgi_webdav import __version__
7-
from asgi_webdav.config import Config
7+
from asgi_webdav.config import Config, Provider
88
from asgi_webdav.constants import DAVDepth, DAVMethod, DAVPath, DAVTime
99
from asgi_webdav.exception import DAVException, DAVExceptionProviderInitFailed
1010
from asgi_webdav.helpers import (
@@ -71,6 +71,8 @@
7171
_CONTENT_TBODY_FILE_TEMPLATE = """<tr><td><a href="{}">{}</a></td><td>{}</td>
7272
<td class="align-right">{}</td><td class="align-right">{}</td></tr>"""
7373

74+
_HTTP_PROVIDERS = {p.type: p for p in [WebHDFSProvider]}
75+
7476

7577
@dataclass
7678
class PrefixProviderInfo:
@@ -102,39 +104,33 @@ class WebDAV:
102104

103105
def __init__(self, config: Config):
104106
# init prefix => provider
105-
for pm in config.provider_mapping:
106-
if pm.uri.startswith("file://"):
107-
provider_factory = FileSystemProvider
108-
109-
elif pm.uri.startswith("http://") or pm.uri.startswith("https://"):
110-
provider_factory = WebHDFSProvider
111-
112-
elif pm.uri.startswith("memory://"):
113-
provider_factory = MemoryProvider
114-
115-
else:
116-
raise
107+
for p_config in config.provider_mapping:
108+
try:
109+
provider_class = self.match_provider_class(p_config)
110+
except DAVExceptionProviderInitFailed as e:
111+
logger.error(f"{e}, please check your config, skip!")
112+
continue
117113

118114
try:
119-
provider = provider_factory(
115+
provider = provider_class(
120116
config=config,
121-
prefix=DAVPath(pm.prefix),
122-
uri=pm.uri,
123-
home_dir=pm.home_dir,
124-
read_only=pm.read_only,
125-
ignore_property_extra=pm.ignore_property_extra,
117+
prefix=DAVPath(p_config.prefix),
118+
uri=p_config.uri,
119+
home_dir=p_config.home_dir,
120+
read_only=p_config.read_only,
121+
ignore_property_extra=p_config.ignore_property_extra,
126122
)
127123
except DAVExceptionProviderInitFailed as e:
128-
logger.error(f"Provider init failed: {pm}, {e}, skip!")
124+
logger.error(f"Provider init failed: {p_config}, {e}, skip!")
129125
continue
130126

131127
ppi = PrefixProviderInfo(
132-
prefix=DAVPath(pm.prefix),
133-
prefix_weight=len(pm.prefix),
128+
prefix=DAVPath(p_config.prefix),
129+
prefix_weight=len(p_config.prefix),
134130
provider=provider,
135-
home_dir=pm.home_dir,
136-
read_only=pm.read_only,
137-
ignore_property_extra=pm.ignore_property_extra,
131+
home_dir=p_config.home_dir,
132+
read_only=p_config.read_only,
133+
ignore_property_extra=p_config.ignore_property_extra,
138134
)
139135
self.prefix_provider_mapping.append(ppi)
140136
logger.info(f"Mapping Prefix: {ppi}")
@@ -149,12 +145,33 @@ def __init__(self, config: Config):
149145
# init hide file in dir
150146
self._hide_file_in_dir = DAVHideFileInDir(config)
151147

152-
# Please check environment variable
148+
# check environment variable
153149
try:
154150
self.timezone = paser_timezone_key(getenv("TZ", "UTC"))
155151
except DAVException as e:
156152
DAVException(f"Please check environment variable: TZ, {e}")
157153

154+
@staticmethod
155+
def match_provider_class(
156+
p_config: Provider,
157+
) -> type[DAVProvider]:
158+
if p_config.uri.startswith("file://"):
159+
return FileSystemProvider
160+
161+
elif p_config.uri.startswith("memory://"):
162+
return MemoryProvider
163+
164+
elif p_config.uri.startswith("http://") or p_config.uri.startswith("https://"):
165+
provider_class = _HTTP_PROVIDERS.get(p_config.type)
166+
if provider_class is None:
167+
raise DAVExceptionProviderInitFailed(
168+
f"Provider not found: {p_config}",
169+
)
170+
171+
return provider_class
172+
173+
raise DAVExceptionProviderInitFailed(f"Provider uri not supported: {p_config}")
174+
158175
def match_provider(self, request: DAVRequest) -> DAVProvider | None:
159176
weight = None
160177
provider = None

docs/changelog.en.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
- feat: new config, Compression.enable
88
- feat: both support .toml and .json config file
99
- feat: support optional anonymous user, thanks [PIC](https://www.pic.es)
10-
- Implement a WebHDFS provider, contributed by [PIC](https://www.pic.es)
10+
- feat: Implement a WebHDFS provider, contributed by [PIC](https://www.pic.es)
1111

1212
## 1.5.0 - 20250628
1313

docs/index.zh.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
- 符合 [ASGI](https://asgi.readthedocs.io) 标准
1818
- 符合 WebDAV 标准: [RFC4918](https://www.ietf.org/rfc/rfc4918.txt)
19-
- 支持多来源: FileProvider, MemoryProvider
19+
- 支持多来源: FileSystemProvider, MemoryProvider, WebHDFSProvider
2020
- 支持多账号以及权限控制
2121
- 支持可选的匿名用户
2222
- 支持可选的家目录

0 commit comments

Comments
 (0)