@@ -16,6 +16,7 @@ import org.apache.pekko.pattern.{CircuitBreaker, CircuitBreakerOpenException}
1616import org .apache .pekko .stream .ThrottleMode
1717import org .apache .pekko .stream .scaladsl .{Flow , Sink , Source }
1818import org .apache .pekko .util .ByteString
19+ import org .bouncycastle .util .encoders .Hex
1920import org .slf4j .{Logger , LoggerFactory }
2021
2122import java .security .MessageDigest
@@ -172,12 +173,19 @@ object ReverseProxy extends App {
172173 uri
173174 }
174175
175- def computeHashWithPayloadAndPayloadLength : Flow [ByteString , (MessageDigest , ByteString , Int ), NotUsed ] =
176- Flow [ByteString ].fold((MessageDigest .getInstance(" SHA-256" ), ByteString .empty, 0 )) { (acc, chunk) =>
177- acc._1.update(chunk.toByteBuffer)
178- (acc._1, acc._2 ++ chunk, acc._3 + chunk.length)
176+ case class HashAccumulator (digest : MessageDigest , payload : ByteString , length : Int )
177+
178+ def computeHashFromPayloadAndPayloadLength : Flow [ByteString , HashAccumulator , NotUsed ] =
179+ Flow [ByteString ].fold(HashAccumulator (
180+ MessageDigest .getInstance(" SHA-256" ),
181+ ByteString .empty,
182+ 0 )) { (acc, chunk) =>
183+ val bytes = chunk.toArray
184+ acc.digest.update(bytes, 0 , bytes.length)
185+ HashAccumulator (acc.digest, acc.payload ++ chunk, acc.length + chunk.length)
179186 }
180187
188+
181189 services.get(mode) match {
182190 case Some (rawSeq) =>
183191 val seq = rawSeq.flatMap(t => (1 to t.weight).map(_ => t))
@@ -196,12 +204,13 @@ object ReverseProxy extends App {
196204
197205 // Example of an on-the-fly processing scenario
198206 val hashFuture = request.entity.dataBytes
199- .via(computeHashWithPayloadAndPayloadLength )
207+ .via(computeHashFromPayloadAndPayloadLength )
200208 .runWith(Sink .head)
201- .map { case (digest, _, _) =>
202- RawHeader (" X-Content-Hash" , digest.digest().map( " %02x " .format(_)).mkString )
209+ .map { accumulator =>
210+ RawHeader (" X-Content-Hash" , Hex .toHexString(accumulator.digest.digest()) )
203211 }
204212
213+
205214 hashFuture.flatMap { hashHeader =>
206215 val proxyReq = request
207216 .withUri(uri(target))
@@ -217,7 +226,6 @@ object ReverseProxy extends App {
217226 case None => Future .successful(NotFound (id, host))
218227 }
219228 }
220-
221229 val futReverseProxy = Http ().newServerAt(proxyHost, proxyPort).bind(handlerWithCircuitBreaker)
222230
223231 futReverseProxy.onComplete {
0 commit comments