=htp Apply remaining review feedback
This commit is contained in:
parent
3747196356
commit
e7ef23f6f8
6 changed files with 89 additions and 40 deletions
|
|
@ -5,11 +5,15 @@
|
|||
package akka.http.model
|
||||
|
||||
import java.io.File
|
||||
import akka.stream.FlowMaterializer
|
||||
import akka.stream.scaladsl.Flow
|
||||
import org.reactivestreams.Publisher
|
||||
import akka.stream.impl.SynchronousPublisherFromIterable
|
||||
import scala.collection.immutable
|
||||
import headers._
|
||||
|
||||
import scala.concurrent.{ ExecutionContext, Future }
|
||||
|
||||
trait MultipartParts {
|
||||
def parts: Publisher[BodyPart]
|
||||
}
|
||||
|
|
@ -47,8 +51,26 @@ object MultipartByteRanges {
|
|||
* All parts must contain a Content-Disposition header with a type form-data
|
||||
* and a name parameter that is unique.
|
||||
*/
|
||||
final case class MultipartFormData(parts: Publisher[BodyPart]) extends MultipartParts {
|
||||
// def get(partName: String): Option[BodyPart] = fields.find(_.name.exists(_ == partName))
|
||||
case class MultipartFormData(parts: Publisher[BodyPart]) extends MultipartParts {
|
||||
/**
|
||||
* Turns this instance into its strict specialization using the given `maxFieldCount` as the field number cut-off
|
||||
* hint.
|
||||
*/
|
||||
def toStrict(materializer: FlowMaterializer, maxFieldCount: Int = 1000)(implicit ec: ExecutionContext): Future[StrictMultipartFormData] =
|
||||
Flow(parts).grouped(maxFieldCount).toFuture(materializer).map(new StrictMultipartFormData(_))
|
||||
}
|
||||
|
||||
/**
|
||||
* A specialized `MultipartFormData` that allows full random access to its parts.
|
||||
*/
|
||||
class StrictMultipartFormData(val fields: immutable.Seq[BodyPart]) extends MultipartFormData(SynchronousPublisherFromIterable(fields)) {
|
||||
/**
|
||||
* Returns the BodyPart with the given name, if found.
|
||||
*/
|
||||
def get(partName: String): Option[BodyPart] = fields.find(_.name.exists(_ == partName))
|
||||
|
||||
override def toStrict(materializer: FlowMaterializer, maxFieldCount: Int)(implicit ec: ExecutionContext): Future[StrictMultipartFormData] =
|
||||
Future.successful(this)
|
||||
}
|
||||
|
||||
object MultipartFormData {
|
||||
|
|
|
|||
|
|
@ -37,12 +37,15 @@ private[http] final class BodyPartParser(defaultContentType: ContentType,
|
|||
|
||||
sealed trait StateResult // phantom type for ensuring soundness of our parsing method setup
|
||||
|
||||
private[this] val needle = new Array[Byte](boundary.length + 4)
|
||||
needle(0) = '\r'.toByte
|
||||
needle(1) = '\n'.toByte
|
||||
needle(2) = '-'.toByte
|
||||
needle(3) = '-'.toByte
|
||||
boundary.getAsciiBytes(needle, 4)
|
||||
private[this] val needle: Array[Byte] = {
|
||||
val array = new Array[Byte](boundary.length + 4)
|
||||
array(0) = '\r'.toByte
|
||||
array(1) = '\n'.toByte
|
||||
array(2) = '-'.toByte
|
||||
array(3) = '-'.toByte
|
||||
boundary.getAsciiBytes(array, 4)
|
||||
array
|
||||
}
|
||||
|
||||
// we use the Boyer-Moore string search algorithm for finding the boundaries in the multipart entity,
|
||||
// TODO: evaluate whether an upgrade to the more efficient FJS is worth the implementation cost
|
||||
|
|
@ -64,13 +67,14 @@ private[http] final class BodyPartParser(defaultContentType: ContentType,
|
|||
try state(input)
|
||||
catch {
|
||||
case e: ParsingException ⇒ fail(e.info)
|
||||
case NotEnoughDataException ⇒ throw new IllegalStateException // we are missing a try/catch{continue} wrapper somewhere
|
||||
case NotEnoughDataException ⇒ throw new IllegalStateException(NotEnoughDataException) // we are missing a try/catch{continue} wrapper somewhere
|
||||
}
|
||||
result.toList
|
||||
}
|
||||
|
||||
def tryParseInitialBoundary(input: ByteString): StateResult = {
|
||||
// we don't use boyerMoore here because we are looking for the boundary *without* a preceding CRLF
|
||||
// we don't use boyerMoore here because we are testing for the boundary *without* a
|
||||
// preceding CRLF and at a known location (the very beginning of the entity)
|
||||
try {
|
||||
@tailrec def rec(ix: Int): StateResult =
|
||||
if (ix < needle.length) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue