Levente Uzonyi uploaded a new version of WebClient-Core to project The Treated Inbox: http://source.squeak.org/treated/WebClient-Core-ul.131.mcz
==================== Summary ====================
Name: WebClient-Core-ul.131 Author: ul Time: 11 April 2023, 12:48:04.515814 pm UUID: c3fedba8-7684-4223-802c-e699cbfb4c84 Ancestors: WebClient-Core-mt.130
Speed up MD5 computation in WebUtils: - as suggested by Tim, #md5HashStream: returns the bytes in the output order, so #reversed can be skipped (this is a breaking change for all the senders of WebUtils class >> #md5HashStream:) - use #readInto:startingAt:count: instead of #nextInto: to read from the stream into the buffer. This avoids a few sends and potential reallocation of the buffer. - do not convert the ByteString to ByteArray in #md5Digest:. ByteArray >> #replaceFrom:to:with:startingAt: can copy from a ByteString into the buffer.
Throughput increases by 28% for 16k inputs.
=============== Diff against WebClient-Core-mt.130 ===============
Item was changed: ----- Method: WebUtils class>>md5Digest: (in category 'md5') ----- md5Digest: aStringOrByteArray "This creates a little endian hex string to be used with various auth methods This is the same as htdigest (apache) uses for its md5 digest auth db"
+ ^(self md5HashStream: aStringOrByteArray readStream) hex! - ^(self md5HashStream: (ReadStream on: aStringOrByteArray asByteArray)) reversed hex!
Item was changed: ----- Method: WebUtils class>>md5HashStream: (in category 'md5') ----- md5HashStream: aStream "self md5HashStream: (ReadStream on: 'foo')"
| start buffer chunkSize n words hash | hash := WordArray with: 16r67452301 with: 16rEFCDAB89 with: 16r98BADCFE with: 16r10325476. words := WordArray new: 16. buffer := ByteArray new: 64. start := aStream position. [ + chunkSize := aStream readInto: buffer startingAt: 1 count: 64. - chunkSize := (aStream nextInto: buffer) size. chunkSize < 64 or: [ aStream atEnd ] ] whileFalse: [ 1 to: 16 do:[:i| words at: i put: (buffer unsignedLongAt: i*4-3 bigEndian: false)]. self md5Transform: words hash: hash ]. buffer from: chunkSize +1 to: buffer size put: 0. chunkSize < 56 ifTrue: [ buffer at: chunkSize + 1 put: 128. "trailing bit" ] ifFalse:[ "not enough room for the length, so just pad this one, then..." chunkSize < 64 ifTrue:[buffer at: chunkSize + 1 put: 128]. 1 to: 16 do:[:i| words at: i put: (buffer unsignedLongAt: i*4-3 bigEndian: false)]. self md5Transform: words hash: hash. "process one additional block of padding ending with the length" buffer atAllPut: 0. chunkSize = 64 ifTrue: [buffer at: 1 put: 128]. ]. "Fill in the final 8 bytes with the 64-bit length in bits." n := (aStream position - start) * 8. 7 to: 0 by: -1 do:[:i| buffer at: (buffer size - i) put: ((n bitShift: 7 - i * -8) bitAnd: 255)]. "Final round" 1 to: 16 do:[:i| words at: i put: (buffer unsignedLongAt: i*4-3 bigEndian: false)]. self md5Transform: words hash: hash. ^(ByteArray new: 16) + unsignedLongAt: 1 put: (hash at: 1) bigEndian: false; + unsignedLongAt: 5 put: (hash at: 2) bigEndian: false; + unsignedLongAt: 9 put: (hash at: 3) bigEndian: false; + unsignedLongAt: 13 put: (hash at: 4) bigEndian: false; - unsignedLongAt: 1 put: (hash at: 4) bigEndian: true; - unsignedLongAt: 5 put: (hash at: 3) bigEndian: true; - unsignedLongAt: 9 put: (hash at: 2) bigEndian: true; - unsignedLongAt: 13 put: (hash at: 1) bigEndian: true; yourself!
Item was changed: ----- Method: WebUtils class>>webSocketHandshake:with:with: (in category 'websockets') ----- webSocketHandshake: key1 with: key2 with: data "Do the actual WebSocket handshake computation"
| bytes | bytes := ByteArray new: 16. bytes longAt: 1 put: key1 bigEndian: true. bytes longAt: 5 put: key2 bigEndian: true. bytes replaceFrom: 9 to: 16 with: data. + ^self md5HashStream: bytes readStream! - ^(self md5HashStream: bytes readStream) reversed!
packages@lists.squeakfoundation.org