Repository: streamlit/streamlit
File: lib/streamlit/web/server/upload_file_request_handler.py (Python)

Code before:

        When a browser is making a CORS request, it may sometimes first
        send an OPTIONS request, to check whether the server understands the
        CORS protocol. This is optional, and doesn't happen for every request
        or in every browser. If an OPTIONS request does get sent, and is not
        then handled by the server, the browser will fail the underlying
        request.

        The proper way to handle this is to send a 204 response ("no content")
        with the CORS headers attached. (These headers are automatically added
        to every outgoing response, including OPTIONS responses,
        via set_default_headers().)

        See https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
        """
        self.set_status(204)
        self.finish()

    def put(self, **kwargs: Any) -> None:
        """Receive an uploaded file and add it to our UploadedFileManager."""

        args: dict[str, list[bytes]] = {}
        files: dict[str, list[Any]] = {}

        if not self.path_kwargs:
            self.send_error(404, reason="No path kwargs provided.")
            return

        session_id = self.path_kwargs["session_id"]
        file_id = self.path_kwargs["file_id"]

        tornado.httputil.parse_body_arguments(
            content_type=self.request.headers["Content-Type"],
            body=self.request.body,
            arguments=args,
            files=files,
        )

        try:
            if not self._is_active_session(session_id):
                self.send_error(400, reason="Invalid session_id")
                return
        except Exception as ex:
            self.send_error(400, reason=str(ex))
            return

        uploaded_files: list[UploadedFileRec] = []

        for flist in files.values():
            uploaded_files.extend(
                UploadedFileRec(

Review comment (suggestion):
**question:** This is a user-facing error string, right? If so, consider a more user-friendly reason we can give here. It would be best if it indicated an action a user could take to help fix the error themselves.

Code after:

        When a browser is making a CORS request, it may sometimes first
        send an OPTIONS request, to check whether the server understands the
        CORS protocol. This is optional, and doesn't happen for every request
        or in every browser. If an OPTIONS request does get sent, and is not
        then handled by the server, the browser will fail the underlying
        request.

        The proper way to handle this is to send a 204 response ("no content")
        with the CORS headers attached. (These headers are automatically added
        to every outgoing response, including OPTIONS responses,
        via set_default_headers().)

        See https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
        """
        self.set_status(204)
        self.finish()

    def put(self, **kwargs: Any) -> None:
        """Receive an uploaded file and add it to our UploadedFileManager."""

        args: dict[str, list[bytes]] = {}
        files: dict[str, list[Any]] = {}

        if not self.path_kwargs:
            # This is not expected to happen with normal Streamlit usage.
            self.send_error(
                400,
                reason="No path arguments provided. Please provide a session_id and file_id in the URL.",
            )
            return

        session_id = self.path_kwargs["session_id"]
        file_id = self.path_kwargs["file_id"]

        tornado.httputil.parse_body_arguments(
            content_type=self.request.headers["Content-Type"],
            body=self.request.body,
            arguments=args,
            files=files,
        )

        try:
            if not self._is_active_session(session_id):
                self.send_error(400, reason="Invalid session_id")
                return
        except Exception as ex:
            self.send_error(400, reason=str(ex))
            return

        uploaded_files: list[UploadedFileRec] = []