1

I'm doing a FastAPI app, with a function that authenticates to a CouchDB instance. In order to request Couchdb, I use the (yet unmaintained) library python-couchdb.

Here is the relevant portion of code that illustrates my issue:

from fastapi import FastAPI
from couchdb import http
resource = http.Resource(url, http.Session())
from couchdb import Unauthorized
from pydantic import BaseModel

app = FastAPI()

class RegisteredUser(BaseModel):
    email: str
    password: str

@app.post("/login")
async def log_user(user: RegisteredUser):

    # some email format verifications here
    # ...

    try:

        status, headers, _ = resource.post_json('_session', {
            'name': user.email,
            'password': user.password,
        })

    except Exception as e:
        if isinstance(e, Unauthorized):
            return 403
        else:
            return 500

    # tests
    print(headers)

The headers look like:

Cache-Control: must-revalidate
Content-Length: 54
Content-Type: application/json
Date: Sat, 08 Aug 2020 19:19:49 GMT
Server: CouchDB/3.1.0 (Erlang OTP/22)
Set-Cookie: AuthSession=am9zZWJvdmVAam9zZWJvdmUuY29tOjVGMkVGQUQ2Op-UUD22VvdxYzbMNp92e30Er_z0; Version=1; Expires=Sat, 08-Aug-2020 20:59:50 GMT; Max-Age=6000;     Path=/; HttpOnly

At this point (if no error raised), I'd like to send back to the (browser) client the cookie that CouchDb provides. Something like:

    ...

    # tests
    print(headers)

    if status == 200 and 'Set-Cookie' in headers:
        return JSONResponse(content=True, headers=headers)
    else:
        return status
  1. I'm not used to sessions-cookie and I'm not sure if I should send back the full headers or just the headers['Set-Cookie'] part

  2. Whatever I do, I end up with the same error message

RuntimeError: Response content shorter than Content-Length

Would you mine to explain to me what the error is saying, and how I can solve my case? Ty!

Found this SO thread but no clue neither FastAPI middleware peeking into responses


Here is one solution:

 if status == 200 and 'Set-Cookie' in headers:
     return JSONResponse(content=True, headers={
         'Set-Cookie' : headers['Set-Cookie']
     })
 else:
     return status

Ty @HernánAlarcón

Guillaume Fe
  • 369
  • 4
  • 16
  • 3
    Is `True` the body of the response you are returning? Because it looks like the headers of your response say that the `Content-Length` is `54`. Maybe the body of your response is not consistent with the headers. – Hernán Alarcón Aug 08 '20 at 20:01
  • @DonFoumare The error occurs when I try to login from the browser, with a javascript fetch function, in the server it breaks when it comes to `JSONResponse`. I used PDB, but the error seems (to me) deeply nested into fastapi and starlette (which is based on) – Guillaume Fe Aug 08 '20 at 20:08
  • "POST /login HTTP/1.1" 200 OK RuntimeError: Response content shorter than Content-Length > /Users/guillaumefe/.pyenv/versions/3.8.3/lib/python3.8/site-packages/starlette/routing.py(44)app() -> await response(scope, receive, send) (Pdb) n Internal StopIteration: False > /Users/guillaumefe/.pyenv/versions/3.8.3/lib/python3.8/site-packages/fastapi/applications.py(181)__call__() -> await super().__call__(scope, receive, send) (Pdb) n ERROR: Exception in ASGI application – Guillaume Fe Aug 08 '20 at 20:09
  • @HernánAlarcón I think you are pointing me into the right direction with that. IYO should I build another response header (with correct content-length)? And then integrate setCookie in it? – Guillaume Fe Aug 08 '20 at 20:11
  • ok it was that, TY, sorry for the nooby, should have seen that... I edit my question with the solution i use. – Guillaume Fe Aug 08 '20 at 20:27

0 Answers0