播放可恢复的上传权限错误

时间:2016-02-03 02:03:05

标签: java scala playframework playframework-2.0 resumablejs

我无法找到使用Play Scala和Resumable.js上传文件时出现此错误的原因:

  

线程“application-akka.actor.default-dispatcher-3”:controllers.Resumable $$ anonfun $ doPost $ 1.apply(Resumable.scala:44)

     

来自resumableParams的一些(resumableInfo)=>:ResumableInfo(作者姓名,1048576,1430174,1430174-AllegrofromDuetinCMajormp3,来自C Major.mp3的Duet的Allegro,来自C Major.mp3的Duet的Allegro,来自C大调的Duet的Allegro) .mp3.temp)

[error] p.c.s.n.PlayDefaultUpstreamHandler - Cannot invoke the action
java.io.FileNotFoundException: /Allegro from Duet in C Major.mp3.temp (Permission denied)
    at java.io.RandomAccessFile.open0(Native Method) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.open(RandomAccessFile.java:316) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:243) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:124) ~[na:1.8.0_71]
    at controllers.Resumable$$anonfun$doPost$1.apply(Resumable.scala:46) ~[classes/:na]
    at controllers.Resumable$$anonfun$doPost$1.apply(Resumable.scala:22) ~[classes/:na]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:408) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:407) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.Action$.invokeBlock(Action.scala:533) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.Action$.invokeBlock(Action.scala:530) ~[play_2.11-2.4.6.jar:2.4.6]
[error] application - 

! @6p27df40a - Internal server error, for (POST) [/resumable] ->

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[FileNotFoundException: /Allegro from Duet in C Major.mp3.temp (Permission denied)]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:265) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:191) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.GlobalSettings$class.onError(GlobalSettings.scala:179) [play_2.11-2.4.6.jar:2.4.6]
    at play.api.DefaultGlobal$.onError(GlobalSettings.scala:212) [play_2.11-2.4.6.jar:2.4.6]
    at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:94) [play_2.11-2.4.6.jar:2.4.6]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:266) [play-netty-server_2.11-2.4.6.jar:2.4.6]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:262) [play-netty-server_2.11-2.4.6.jar:2.4.6]
    at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344) [scala-library-2.11.7.jar:na]
    at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343) [scala-library-2.11.7.jar:na]
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32) [scala-library-2.11.7.jar:na]
Caused by: java.io.FileNotFoundException: /Allegro from Duet in C Major.mp3.temp (Permission denied)
    at java.io.RandomAccessFile.open0(Native Method) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.open(RandomAccessFile.java:316) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:243) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:124) ~[na:1.8.0_71]
    at controllers.Resumable$$anonfun$doPost$1.apply(Resumable.scala:46) ~[classes/:na]
    at controllers.Resumable$$anonfun$doPost$1.apply(Resumable.scala:22) ~[classes/:na]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:408) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:407) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.Action$.invokeBlock(Action.scala:533) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.Action$.invokeBlock(Action.scala:530) ~[play_2.11-2.4.6.jar:2.4.6]

制作文件的代码就是这样......

def checkIfUploadFinished:Boolean = {     val count:Int = Math.ceil(resumableTotalSize.toDouble / resumableChunkSize.toDouble).toInt     1.until(count)foreach {i:Int =&gt;       if(!uploadedChunks.contains(i))返回false     }

val file: File = new File(resumableFilePath)
val newPath: String = file.getAbsolutePath.substring(0, file.getAbsolutePath.length - ".temp".length)
file.renameTo(new File(newPath))
true

}

重新运行它给了我这个......

[error] p.c.s.n.PlayDefaultUpstreamHandler - Cannot invoke the action
java.io.FileNotFoundException: /Allegro from Duet in C Major.mp3.temp (Permission denied)
    at java.io.RandomAccessFile.open0(Native Method) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.open(RandomAccessFile.java:316) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:243) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:124) ~[na:1.8.0_71]
    at controllers.Resumable$$anonfun$doPost$1.apply(Resumable.scala:46) ~[classes/:2.4.6]
    at controllers.Resumable$$anonfun$doPost$1.apply(Resumable.scala:22) ~[classes/:2.4.6]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:408) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:407) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.Action$.invokeBlock(Action.scala:533) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.Action$.invokeBlock(Action.scala:530) ~[play_2.11-2.4.6.jar:2.4.6]
[error] application - 

! @6p2c3mpkb - Internal server error, for (POST) [/resumable] ->

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[FileNotFoundException: /Allegro from Duet in C Major.mp3.temp (Permission denied)]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:265) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:191) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.GlobalSettings$class.onError(GlobalSettings.scala:179) [play_2.11-2.4.6.jar:2.4.6]
    at play.api.DefaultGlobal$.onError(GlobalSettings.scala:212) [play_2.11-2.4.6.jar:2.4.6]
    at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:94) [play_2.11-2.4.6.jar:2.4.6]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:266) [play-netty-server_2.11-2.4.6.jar:2.4.6]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:262) [play-netty-server_2.11-2.4.6.jar:2.4.6]
    at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344) [scala-library-2.11.7.jar:na]
    at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343) [scala-library-2.11.7.jar:na]
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32) [scala-library-2.11.7.jar:na]
Caused by: java.io.FileNotFoundException: /Allegro from Duet in C Major.mp3.temp (Permission denied)
    at java.io.RandomAccessFile.open0(Native Method) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.open(RandomAccessFile.java:316) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:243) ~[na:1.8.0_71]
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:124) ~[na:1.8.0_71]
    at controllers.Resumable$$anonfun$doPost$1.apply(Resumable.scala:46) ~[classes/:2.4.6]
    at controllers.Resumable$$anonfun$doPost$1.apply(Resumable.scala:22) ~[classes/:2.4.6]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:408) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:407) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.Action$.invokeBlock(Action.scala:533) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.mvc.Action$.invokeBlock(Action.scala:530) ~[play_2.11-2.4.6.jar:2.4.6]

1 个答案:

答案 0 :(得分:1)

According to the error, you're trying to save the file to /Allegro from Duet in C Major.mp3.temp, and you don't have permission to open that file. Which is a good thing, allowing users to upload any arbitrarily named file to your root file system would be a serious security issue. In fact, it probably is a serious security issue anyway, since they could choose any file name, eg /etc/passwd, and next thing you know, they've created new user accounts for themselves on your system.

You should select a file name in a temporary directory, and avoid using the same file name as they've sent you, as that avoids a whole range of potential security problems. A better solution is to use a hash of the file name combined with the users user name. So the file you should use would be:

new File(someTempDirectory, username + "-" + file.getName.hashCode())