예제 #1
0
def upload(request: HttpRequest) -> JsonResponse:
    logging.log_request_received(
        logger,
        request.META['PATH_INFO'] if 'PATH_INFO' in request.META.keys() else '-path to file UNAVAILABLE-',
        FileTransferToken.Operation.upload
    )

    if request.content_type in ['multipart/form-data', '', None] or request.content_type.isspace():
        return gatekeeper_access_denied_response(
            'Unsupported content type.',
            FileTransferToken.Operation.upload,
            ErrorCode.HEADER_CONTENT_TYPE_NOT_SUPPORTED,
            request.META['PATH_INFO'] if 'PATH_INFO' in request.META.keys() else 'UNAVAILABLE'
        )
    path_to_file = request.get_full_path().partition(reverse('gatekeeper:upload'))[2]

    response_or_file_info = parse_headers(request, path_to_file, FileTransferToken.Operation.upload)

    if not isinstance(response_or_file_info, FileTransferToken.FileInfo):
        assert isinstance(response_or_file_info, JsonResponse)
        return response_or_file_info

    response = JsonResponse({"message": "Request passed all upload validations."}, status = 200)
    response["Concent-File-Size"] = response_or_file_info["size"]
    response["Concent-File-Checksum"] = response_or_file_info["checksum"]

    return response
예제 #2
0
def report_upload(_request: HttpRequest, file_path: str) -> HttpResponse:

    log_request_received(logger, file_path, FileTransferToken.Operation.upload)
    # If there's a corresponding VerificationRequest, the load it and link it to UploadReport.
    try:
        verification_request = VerificationRequest.objects.select_for_update(
        ).get(
            Q(source_package_path=file_path)
            | Q(result_package_path=file_path))
    except VerificationRequest.DoesNotExist:
        verification_request = None

    # The app creates a new instance of UploadReport in the database.
    upload_report = UploadReport(
        path=file_path,
        verification_request=verification_request,
    )
    upload_report.full_clean()
    upload_report.save()

    # The app gets the VerificationRequest and checks if both source and result packages have reports.
    if (verification_request is not None
            and verification_request.blender_subtask_definition is not None
            and verification_request.upload_reports.filter(
                path=verification_request.source_package_path).exists()
            and verification_request.upload_reports.filter(
                path=verification_request.result_package_path).exists()
            and verification_request.upload_reports.filter(
                path=file_path).count() == 1):
        assert file_path in [
            verification_request.source_package_path,
            verification_request.result_package_path
        ]

        # If all expected files have been uploaded, the app sends upload_finished task to the work queue.
        upload_finished.delay(verification_request.subtask_id)

        verification_request.upload_finished = True
        verification_request.full_clean()
        verification_request.save()

        log(logger,
            'All expected files have been uploaded',
            f'Result package path: {verification_request.result_package_path}.'
            f'Source package path: {verification_request.source_package_path}.',
            subtask_id=verification_request.subtask_id)

    # If ResultTransferRequest matching the file exists, report finished upload.
    result_transfer_request = ResultTransferRequest.objects.filter(
        result_package_path=file_path).first()
    if result_transfer_request is not None:
        update_upload_report(
            file_path=file_path,
            result_transfer_request=result_transfer_request,
        )

    return HttpResponse()
예제 #3
0
파일: views.py 프로젝트: PaweuB/concent
def download(request):
    logging.log_request_received(
        logger,
        request.META['PATH_INFO'] if 'PATH_INFO' in request.META.keys() else '-path to file UNAVAILABLE-',
        FileTransferToken.Operation.download
    )
    # The client should not sent Content-Type header with GET requests.
    # FIXME: When running on `manage.py runserver` in development, empty or missing Concent-Type gets replaced
    # with text/plain. gunicorn does not do this. Looks like a bug to me. We'll let it pass for now sice we ignore
    # the body anyway and the check is mostly to inform the client about its mistake.
    if request.content_type != 'text/plain' and request.content_type != '':
        return gatekeeper_access_denied_response(
            'Download request cannot have data in the body.',
            FileTransferToken.Operation.download,
            ErrorCode.REQUEST_BODY_NOT_EMPTY,
        )

    path_to_file = request.get_full_path().partition(reverse('gatekeeper:download'))[2]
    response_or_file_info = parse_headers(request, path_to_file, FileTransferToken.Operation.download)
    if not isinstance(response_or_file_info, FileTransferToken.FileInfo):
        assert isinstance(response_or_file_info, JsonResponse)
        return response_or_file_info
    return JsonResponse({"message": "Request passed all download validations."}, status = 200)