Skip to content

Commit

Permalink
[ENH] Verify clients use HTTP 1.1 + (#1416)
Browse files Browse the repository at this point in the history
## Description of changes

This change adds FastAPI server-side verification that clients are using
HTTP 1.1 or 2, and adds an appropriate `ChromaError` called
`InvalidHTTPVersion` if they're not.

The `requests` library used by the Chroma python client uses 1.1 by
default so no changes are needed.

## Test plan
Tested manually by setting 


https://github.com/chroma-core/chroma/blob/2e6602072a3191407a2aff189e398ba73ba952fc/chromadb/server/fastapi/__init__.py#L95

to instead be

```python
 http_version not in ["1"]
```

And observed that attempting to connect raises the appropriate
exception, propagated from the server:

```
Traceback (most recent call last):
  File "/Users/antontroynikov/Projects/chroma/chromadb/api/client.py", line 427, in _validate_tenant_database
    self._admin_client.get_tenant(name=tenant)
  File "/Users/antontroynikov/Projects/chroma/chromadb/api/client.py", line 472, in get_tenant
    return self._server.get_tenant(name=name)
  File "/Users/antontroynikov/Projects/chroma/chromadb/telemetry/opentelemetry/__init__.py", line 127, in wrapper
    return f(*args, **kwargs)
  File "/Users/antontroynikov/Projects/chroma/chromadb/api/fastapi.py", line 198, in get_tenant
    raise_chroma_error(resp)
  File "/Users/antontroynikov/Projects/chroma/chromadb/api/fastapi.py", line 625, in raise_chroma_error
    raise chroma_error
chromadb.errors.InvalidHTTPVersion: HTTP version 1.1 is not supported
```

The same test with the Javascript client returns a `400` error as
expected.

## Documentation Changes
N/A

## TODO
- [x] Check Javascript client
  • Loading branch information
atroyn authored Nov 21, 2023
1 parent 7289e49 commit 65f3bb9
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
8 changes: 8 additions & 0 deletions chromadb/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,18 @@ def name(cls) -> str:
return "InvalidUUID"


class InvalidHTTPVersion(ChromaError):
@classmethod
@overrides
def name(cls) -> str:
return "InvalidHTTPVersion"


error_types: Dict[str, Type[ChromaError]] = {
"InvalidDimension": InvalidDimensionException,
"InvalidCollection": InvalidCollectionException,
"IDAlreadyExists": IDAlreadyExistsError,
"DuplicateID": DuplicateIDError,
"InvalidUUID": InvalidUUIDError,
"InvalidHTTPVersion": InvalidHTTPVersion,
}
11 changes: 11 additions & 0 deletions chromadb/server/fastapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
ChromaError,
InvalidUUIDError,
InvalidDimensionException,
InvalidHTTPVersion,
)
from chromadb.server.fastapi.types import (
AddEmbedding,
Expand Down Expand Up @@ -87,6 +88,15 @@ async def catch_exceptions_middleware(
return JSONResponse(content={"error": repr(e)}, status_code=500)


async def check_http_version_middleware(
request: Request, call_next: Callable[[Request], Any]
) -> Response:
http_version = request.scope.get("http_version")
if http_version not in ["1.1", "2"]:
raise InvalidHTTPVersion(f"HTTP version {http_version} is not supported")
return await call_next(request)


def _uuid(uuid_str: str) -> UUID:
try:
return UUID(uuid_str)
Expand Down Expand Up @@ -131,6 +141,7 @@ def __init__(self, settings: Settings):
self._opentelemetry_client = self._api.require(OpenTelemetryClient)
self._system.start()

self._app.middleware("http")(check_http_version_middleware)
self._app.middleware("http")(catch_exceptions_middleware)
self._app.add_middleware(
CORSMiddleware,
Expand Down

0 comments on commit 65f3bb9

Please sign in to comment.