简体   繁体   English

在完全读取请求之前,Akka-Http文件上传发送响应

[英]Akka-Http File Upload sending response before request is completely read

I have the following route in my akka-http server: 我的akka​​-http服务器中有以下路线:

def tempDestination(fileInfo: FileInfo): File = {
    log.info(s"File info for upload: [$fileInfo]")
    File.createTempFile(fileInfo.fileName, ".tmp")
}
...
post {
    log.info("Inside the file upload path")
    fileUpload("zip") {
      case (fileInfo, bytes) =>
        val dest = tempDestination(fileInfo)
        val uploadedF: Future[(FileInfo, File)] =
          bytes
            .runWith(FileIO.toPath(dest.toPath))
            .map(_ => (fileInfo, dest))

        onSuccess(uploadedF) { (info, file) =>
            val fileCreated: Future[MyFile] = (fileRegistryActor ? NewFile(file)).mapTo[MyFile]
            complete((StatusCodes.Created, fileCreated))
        }
    }
}

After uploading a file to this via a form, I see this in the logs: 通过表单将文件上传到此文件后,我在日志中看到了该文件:

Sending an 2xx 'early' response before end of request was received... Note that the connection will be closed after this response. Also, many clients will not read early responses! Consider only issuing this response after the request data has been completely read!

I thought that the uploadedF Future would not be completed until the Sink's IOResult was created and completed. 我认为uploadedF直到水槽的IOResult创建并完成未来将无法完成。 What am I missing? 我想念什么? And what's the proper mechanism to determine whether my whole request has been read AND my file has been completely written to disk? 确定我的整个请求是否已被读取以及文件是否已完全写入磁盘的适当机制是什么?

So what appeared to solve this for me was changing the route from just post to post & extractRequest . 因此,为我解决此问题的方法是将路线从just post更改为post & extractRequest

def tempDestination(fileInfo: FileInfo): File = {
    log.info(s"File info for upload: [$fileInfo]")
    File.createTempFile(fileInfo.fileName, ".tmp")
}
...
(post & extractRequest) { _ =>
    log.info("Inside the file upload path")
    fileUpload("zip") {
      case (fileInfo, bytes) =>
        val dest = tempDestination(fileInfo)
        val uploadedF: Future[(FileInfo, File)] =
          bytes
            .runWith(FileIO.toPath(dest.toPath))
            .map(_ => (fileInfo, dest))

        onSuccess(uploadedF) { (info, file) =>
            val fileCreated: Future[MyFile] = (fileRegistryActor ? NewFile(file)).mapTo[MyFile]
            complete((StatusCodes.Created, fileCreated))
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM