Skip to content

Commit

Permalink
hard work but... now I can store correctly the file
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiago Peczenyj committed Jan 2, 2012
1 parent 44a872d commit 3e84666
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 49 deletions.
1 change: 0 additions & 1 deletion scala2/src/generate-mocks/scala/GenerateMocks.scala
Expand Up @@ -3,6 +3,5 @@ package com.uplpipe
import org.scalamock.annotation.{mock, mockObject}
import javax.servlet.ServletInputStream

@mock[UplpipeServletInputStream]
@mockObject(Config)
class Dummy
95 changes: 75 additions & 20 deletions scala2/src/main/scala/Uplpipe.scala
@@ -1,35 +1,90 @@
package com.uplpipe

import java.io.File
import java.io.{File, FileOutputStream, FileInputStream, BufferedOutputStream}

object Config {
def chunk = 8*1024
def chunk = 8*1024
def basePath = "/tmp/pqp"
def fieldName = "f"
}
class Session {
def update(uuid :String, readed :Int, max :Int) = {}
def setComplete(uuid:String) = {}
}
class UplpipeWebApp(session :Session) {
def handleUpload(uuid :String, contentLength :Int, contentType :String, inputReadLine: (Array[Byte], Int, Int) => Int) = {
val input = new UplpipeServletInputStream(contentLength, inputReadLine, {
(readed :Int) => session.update(uuid,readed,contentLength)
})

val boundary = extractBoundary(contentType)
val parser = new UplpipeMultipartRequestParser(uuid, boundary, input)

val file = parser.getFileFromInput(Config.fieldName).getOrElse{ errorFileNotFound }

val changed = _rename(file)
session.setComplete(uuid)
}

val contentRegex = "multipart/form-data; boundary=(-+\\w+)".r

def errorBoundary = throw new Exception("it is not a multipart request!")

def extractBoundary(content:String):String =
contentRegex findFirstMatchIn(content) map { "--" + _.group(1) } getOrElse { errorBoundary }

def errorFileNotFound = throw new Exception("file not found!")

def _rename(tmpfile :File) :Boolean = tmpfile.renameTo(new File(tmpfile.getPath.replace("incoming-","")))
}

class UplpipeMultipartRequestParser(uuid :String, boundary :String, input :UplpipeServletInputStream){
if (! input.readLineString.startsWith(boundary) ) throw new IllegalArgumentException("data corrupt")
val dispositionRegex = """.*Content-Disposition: form-data; name="(.+)"; filename="(.+)".*""".r

if (! input.readLine.startsWith(boundary) ) throw new IllegalArgumentException("data corrupt")

def getFileFromInput(name :String):Option[File] = {
val contentDisposition = input readLineString
var contentType = input readLineString
var emptyLine = input readLineString
val contentDisposition = input readLine
var contentType = input readLine
var emptyLine = input readLine

if(contentType.isEmpty || !emptyLine.isEmpty) error_malformed_content_disposition

val fieldName = extractFieldName(contentDisposition)
val fileName = extractFilename(contentDisposition)

val fieldName = dispositionRegex findFirstMatchIn(contentDisposition) map { _.group(1) } getOrElse {
error_malformed_content_disposition
}

if (fieldName != name) return None

Option(new File("/tmp/a"))
val file = new File("%s/incoming-%s".format(Config.basePath,uuid))
val fos = new FileOutputStream(file)
val out = new BufferedOutputStream(fos, 8*1024)
val bbuf = new Array[Byte](8*1024)

var result = -1
while({ result = input.readLine(bbuf, 0, bbuf.length)
result != -1 && ! reach_end_of_part(bbuf,result) }){
out.write(bbuf, 0, result);
}

out.flush ; out.close ; fos.close

_truncate(file)

Option(file)
}
val dispositionRegex = """Content-Disposition: form-data; name="(.+)"; filename="(.+)"""".r

def error_malformed_content_disposition = throw new IllegalArgumentException("malformed Content-Disposition")

def extractFieldName(line:String):String =
dispositionRegex findFirstMatchIn(line) map { _.group(1) } getOrElse { error_malformed_content_disposition }
def reach_end_of_part(bbuf :Array[Byte], result:Int) : Boolean =
result > 2 && bbuf(0) == '-' && bbuf(1) == '-' && new String(bbuf, 0, result).startsWith(boundary)

def error_malformed_content_disposition = throw new IllegalArgumentException("malformed Content-Disposition")

def extractFilename(line:String): String =
dispositionRegex findFirstMatchIn(line) map { _.group(2) } getOrElse { error_malformed_content_disposition }
def _truncate(file :File) = {
val fos = new FileOutputStream(file,true)
val chan = fos.getChannel() // truncate by last 2 characteres
chan.truncate(chan.size -2)
chan.close() ; fos.close()
}
}

class UplpipeServletInputStream(
Expand All @@ -40,20 +95,20 @@ class UplpipeServletInputStream(

var readedBytes = 0

def readLineString:String = {
def readLine:String = {
var result = 0
val buf = new Array[Byte](chunk)
val sbuf = new StringBuffer()

do {
result = readLineArray(buf, 0, buf.length)
result = readLine(buf, 0, buf.length)
if (result != -1) sbuf.append(new String(buf, 0, result))
}while (result == buf.length)

sbuf.toString.stripLineEnd
}

def readLineArray(b :Array[Byte], off:Int, len:Int): Int =
def readLine(b :Array[Byte], off:Int, len:Int): Int =
if (maxBytes > readedBytes) {
var result = inputReadLine(b, off, len)
readedBytes += result
Expand Down
56 changes: 28 additions & 28 deletions scala2/target/.history
@@ -1,31 +1,3 @@
clean
generate-mocks
compile
test
last
compile
generate-mocks
test
compile
test
compile
test
compile
test
compile
test
compile
test
generate-mocks
compile
test
compile
generate-mocks
test
generate-mocks
test
generate-mocks
compile
clean\
clean compile generate-mocks test
clean
Expand Down Expand Up @@ -499,3 +471,31 @@ generate-mocks
compile
test
exit
jacoco:test
jacoco:report
test
jacoco:test
jacoco:report
jacoco:test
jacoco:report
jacoco:test
jacoco:report
exit
test
clean
generate-mocks
test
generate-mocks
test
clean
generate-mocks
test
jacoco:test
clean
generate-mocks
test
clean
compile
jacoco:test
jacoco:report
exit

0 comments on commit 3e84666

Please sign in to comment.