@@ -16,18 +16,17 @@ package org.apache.pekko.http.impl.engine.parsing
1616import org .apache .pekko
1717import pekko .NotUsed
1818import pekko .annotation .InternalApi
19-
20- import scala .annotation .tailrec
2119import pekko .event .LoggingAdapter
22- import org .parboiled2 .CharPredicate
20+ import pekko .http .impl .util ._
21+ import pekko .http .scaladsl .model ._
22+ import pekko .http .scaladsl .model .headers ._
23+ import pekko .stream .{ Attributes , FlowShape , Inlet , Outlet }
2324import pekko .stream .scaladsl .Source
2425import pekko .stream .stage ._
2526import pekko .util .ByteString
26- import pekko .http .scaladsl .model ._
27- import pekko .http .impl .util ._
28- import pekko .stream .{ Attributes , FlowShape , Inlet , Outlet }
29- import pekko .http .scaladsl .model .headers ._
27+ import org .parboiled2 .CharPredicate
3028
29+ import scala .annotation .tailrec
3130import scala .collection .mutable .ListBuffer
3231
3332/**
@@ -355,15 +354,38 @@ private[http] object BodyPartParser {
355354 }
356355
357356 case class UndefinedEndOfLineConfiguration (boundary : String ) extends EndOfLineConfiguration {
357+ import HttpConstants ._
358+
358359 override def eol : String = " \r\n "
359360
360361 override def defineOnce (byteString : ByteString ): EndOfLineConfiguration = {
361362 // Hypothesis: There is either CRLF or LF as EOL, no mix possible
362- val crLfNeedle = ByteString (s " $boundary\r\n " )
363- val lfNeedle = ByteString (s " $boundary\n " )
364- if (byteString.containsSlice(crLfNeedle)) DefinedEndOfLineConfiguration (" \r\n " , boundary)
365- else if (byteString.containsSlice(lfNeedle)) DefinedEndOfLineConfiguration (" \n " , boundary)
366- else this
363+ checkForBoundary(byteString) match {
364+ case CR_BYTE => DefinedEndOfLineConfiguration (" \r\n " , boundary)
365+ case LF_BYTE => DefinedEndOfLineConfiguration (" \n " , boundary)
366+ case _ => this
367+ }
368+ }
369+
370+ // returns CR for CRLF, LF for LF, 0 otherwise
371+ private def checkForBoundary (byteString : ByteString ): Byte = {
372+ val check = ByteString (boundary)
373+ @ tailrec def findBoundary (offset : Int ): Byte = {
374+ val index = byteString.indexOfSlice(check, offset)
375+ if (index != - 1 ) {
376+ val newIndex = index + boundary.length
377+ byteAt(byteString, newIndex) match {
378+ case CR_BYTE =>
379+ if (byteAt(byteString, newIndex + 1 ) == LF_BYTE ) CR_BYTE else findBoundary(index + 1 )
380+ case LF_BYTE => LF_BYTE
381+ case _ => findBoundary(index + 1 )
382+ }
383+ } else 0
384+ }
385+ try findBoundary(0 )
386+ catch {
387+ case NotEnoughDataException => 0
388+ }
367389 }
368390 }
369391}
0 commit comments