diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index cc3850a4..069c6998 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -7,10 +7,10 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - smalltalk: [ Pharo64-10 , Pharo64-9.0 , Pharo64-8.0 , Pharo64-7.0 ] + smalltalk: [ Pharo64-11, Pharo64-10 , Pharo64-9.0 , Pharo64-8.0 , Pharo64-7.0 ] name: ${{ matrix.smalltalk }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: hpi-swa/setup-smalltalkCI@v1 with: smalltalk-version: ${{ matrix.smalltalk }} diff --git a/README.md b/README.md index 3a69838d..a0230507 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,11 @@ Zinc HTTP Components is an open-source Smalltalk framework to deal with the HTTP networking protocol. [![CI](https://github.com/svenvc/zinc/actions/workflows/CI.yml/badge.svg)](https://github.com/svenvc/zinc/actions/workflows/CI.yml) +[![Pharo 7.0](https://img.shields.io/badge/Pharo-7.0-informational)](https://pharo.org) +[![Pharo 8.0](https://img.shields.io/badge/Pharo-8.0-informational)](https://pharo.org) +[![Pharo 9.0](https://img.shields.io/badge/Pharo-9.0-informational)](https://pharo.org) +[![Pharo 10](https://img.shields.io/badge/Pharo-10-informational)](https://pharo.org) +[![Pharo 11](https://img.shields.io/badge/Pharo-11-informational)](https://pharo.org) Based on core classes modelling all main HTTP concepts, a full featured HTTP client and server are provided. diff --git a/repository/BaselineOfZincHTTPComponents.package/BaselineOfZincHTTPComponents.class/instance/baseline..st b/repository/BaselineOfZincHTTPComponents.package/BaselineOfZincHTTPComponents.class/instance/baseline..st index e462274f..346f5057 100644 --- a/repository/BaselineOfZincHTTPComponents.package/BaselineOfZincHTTPComponents.class/instance/baseline..st +++ b/repository/BaselineOfZincHTTPComponents.package/BaselineOfZincHTTPComponents.class/instance/baseline..st @@ -1,9 +1,9 @@ baselines baseline: spec - spec for: #common do: [ + spec for: #common do: [ spec baseline: 'NeoJSON' with: [ spec repository: 'github://svenvc/NeoJSON:master/repository' ]. - spec project: 'XML Support' with: [ spec className: 'ConfigurationOfXMLSupport'; repository: 'http://www.squeaksource.com/MetacelloRepository' ]. + spec baseline: 'XMLParser' with: [ spec repository: 'github://pharo-contributions/XML-XMLParser:master/src' ]. spec package: 'Zodiac-Core' with: [ spec repository: 'github://svenvc/zodiac:master/repository' ]. spec package: 'Zodiac-Tests' with: [ spec repository: 'github://svenvc/zodiac:master/repository' ]. spec @@ -17,13 +17,13 @@ baseline: spec package: 'Zinc-Zodiac-Core' with: [ spec requires: #('Zinc-HTTP' 'Zodiac-Core') ]; package: 'Zinc-Zodiac-Tests' with: [ spec requires: #('Zinc-Zodiac-Core') ]. spec - package: 'Zinc-AWS' with: [ spec requires: #('Zinc-HTTP' 'XML Support') ]; + package: 'Zinc-AWS' with: [ spec requires: #('Zinc-HTTP' 'XMLParser') ]; package: 'Zinc-REST' with: [ spec requires: #('Zinc-HTTP' 'NeoJSON') ]; package: 'Zinc-WebSocket-Core' with: [ spec requires: 'Zinc-HTTP' ]; package: 'Zinc-WebSocket-Tests' with: [ spec requires: 'Zinc-WebSocket-Core' ]; package: 'Zinc-SSO-OAuth1-Core' with: [ spec requires: #('Zinc-HTTP' 'NeoJSON') ]; package: 'Zinc-SSO-OAuth2-Core' with: [ spec requires: #('Zinc-HTTP' 'NeoJSON') ]; - package: 'Zinc-SSO-OpenID-Core' with: [ spec requires: #('Zinc-HTTP' 'XML Support') ]; + package: 'Zinc-SSO-OpenID-Core' with: [ spec requires: #('Zinc-HTTP' 'XMLParser') ]; package: 'Zinc-SSO-Demo' with: [ spec requires: #('Zinc-SSO-OAuth1-Core' 'Zinc-SSO-OAuth2-Core' 'Zinc-SSO-OpenID-Core') ]; package: 'Zinc-SSO-OAuth1-Tests' with: [ spec requires: #('Zinc-SSO-OAuth1-Core') ]; package: 'Zinc-SSO-OpenID-Tests' with: [ spec requires: #('Zinc-SSO-OpenID-Core') ]; diff --git a/repository/Zinc-Character-Encoding-Core.package/ZnBufferedReadStream.class/instance/back.st b/repository/Zinc-Character-Encoding-Core.package/ZnBufferedReadStream.class/instance/back.st index 7c7a9f2f..b1a3eb91 100644 --- a/repository/Zinc-Character-Encoding-Core.package/ZnBufferedReadStream.class/instance/back.st +++ b/repository/Zinc-Character-Encoding-Core.package/ZnBufferedReadStream.class/instance/back.st @@ -6,16 +6,17 @@ back ifTrue: [ stream back ] ifFalse: [ | targetPosition bufferPosition char | - position = 1 ifTrue: + position = 1 ifTrue: [ stream position = 0 ifTrue: [ self error: 'Cannot move back from beginning' ] ifFalse: [ targetPosition := self position - 1. + "Assume that the caller may want to go back a few elements before reading forward again" bufferPosition := targetPosition - 10 max: 0. self position: bufferPosition. self nextBuffer. - self position: targetPosition ]. - self peek ] + self position: targetPosition. + self peek ] ] ifFalse: [ char := buffer at: position. position := position - 1. diff --git a/repository/Zinc-Character-Encoding-Tests.package/ZnBufferedReadStreamTest.class/instance/testBack.st b/repository/Zinc-Character-Encoding-Tests.package/ZnBufferedReadStreamTest.class/instance/testBack.st new file mode 100644 index 00000000..93b65f79 --- /dev/null +++ b/repository/Zinc-Character-Encoding-Tests.package/ZnBufferedReadStreamTest.class/instance/testBack.st @@ -0,0 +1,20 @@ +tests +testBack + "Check that ZnBufferedReadStream>>#back behaves as expected" + + | stream source | + + "Allocate a buffer larger than the default size (65536)" + self assert: ZnBufferedReadStream basicNew defaultBufferSize < 66000. + source := ByteArray new: 70000. + 1 to: 70000 do: [ :i | + source at: i put: i \\ 256 ]. + + stream := ZnBufferedReadStream on: source readStream. + stream position: 1. + self assert: stream peek equals: (source at: 2). + self assert: stream back equals: (source at: 1). + "Position the stream beyond the end of the initial buffer" + stream position: 66000. + self assert: stream peek equals: (source at: 66001). + self assert: stream back equals: (source at: 66000). \ No newline at end of file diff --git a/repository/Zinc-HTTP-UnixSocket.package/NetNameResolver.extension/class/addressForSocketPath..st b/repository/Zinc-HTTP-UnixSocket.package/NetNameResolver.extension/class/addressForSocketPath..st new file mode 100644 index 00000000..d3c485ff --- /dev/null +++ b/repository/Zinc-HTTP-UnixSocket.package/NetNameResolver.extension/class/addressForSocketPath..st @@ -0,0 +1,11 @@ +*Zinc-HTTP-UnixSocket +addressForSocketPath: socketPath + "Resolve a socketPath, a Unix Domain Socket, to a SocketAddress" + + | addressSize socketAddress | + self initializeNetwork. + self primGetAddressInfoHost: '' service: socketPath flags: 0 family: 1 type: 0 protocol: 0. + addressSize := self primGetAddressInfoSize. + socketAddress := SocketAddress new: addressSize withAll: 0. + self primGetAddressInfoResult: socketAddress. + ^ socketAddress \ No newline at end of file diff --git a/repository/Zinc-HTTP-UnixSocket.package/NetNameResolver.extension/properties.json b/repository/Zinc-HTTP-UnixSocket.package/NetNameResolver.extension/properties.json new file mode 100644 index 00000000..624889a0 --- /dev/null +++ b/repository/Zinc-HTTP-UnixSocket.package/NetNameResolver.extension/properties.json @@ -0,0 +1,3 @@ +{ + "name" : "NetNameResolver" +} \ No newline at end of file diff --git a/repository/Zinc-HTTP-UnixSocket.package/ZnNetworkingUtils.extension/instance/socketStreamToUnixSocketFile..st b/repository/Zinc-HTTP-UnixSocket.package/ZnNetworkingUtils.extension/instance/socketStreamToUnixSocketFile..st index b6a4ef09..f1d26f7e 100644 --- a/repository/Zinc-HTTP-UnixSocket.package/ZnNetworkingUtils.extension/instance/socketStreamToUnixSocketFile..st +++ b/repository/Zinc-HTTP-UnixSocket.package/ZnNetworkingUtils.extension/instance/socketStreamToUnixSocketFile..st @@ -2,4 +2,4 @@ socketStreamToUnixSocketFile: socketFile | ipcSocket | ipcSocket := self unixSocketOnFile: socketFile. - ^ ZnNetworkingUtils socketStreamOn: ipcSocket. \ No newline at end of file + ^ self socketStreamOn: ipcSocket \ No newline at end of file diff --git a/repository/Zinc-HTTP-UnixSocket.package/ZnNetworkingUtils.extension/instance/unixSocketOnFile..st b/repository/Zinc-HTTP-UnixSocket.package/ZnNetworkingUtils.extension/instance/unixSocketOnFile..st index 18bd61c3..29ef61b3 100644 --- a/repository/Zinc-HTTP-UnixSocket.package/ZnNetworkingUtils.extension/instance/unixSocketOnFile..st +++ b/repository/Zinc-HTTP-UnixSocket.package/ZnNetworkingUtils.extension/instance/unixSocketOnFile..st @@ -1,25 +1,13 @@ *Zinc-HTTP-UnixSocket unixSocketOnFile: socketFile - | addressSize socketAddress ipcSocket | - socketFile exists ifFalse: [ + | socketAddress ipcSocket | + socketFile exists ifFalse: [ ZnMissingUnixSocket new file: socketFile; signal ]. - - NetNameResolver initializeNetwork. - NetNameResolver - primGetAddressInfoHost: '' - service: socketFile fullName - flags: 0 - family: 1 - type: 0 - protocol: 0. - addressSize := NetNameResolver primGetAddressInfoSize. - socketAddress := SocketAddress new: addressSize withAll: 0. - NetNameResolver primGetAddressInfoResult: socketAddress. - + socketAddress := NetNameResolver addressForSocketPath: socketFile fullName. ipcSocket := Socket newIPC. - ipcSocket ifNil: [ - ZnCannotCreateUnixSocket new file: socketFile; signal ]. + ipcSocket ifNil: [ + ZnCannotCreateUnixSocket new file: socketFile; signal ]. ipcSocket connectTo: socketAddress. - ipcSocket isConnected ifFalse: [ - ZnCannotConnectUnixSocket new file: socketFile; signal ]. + ipcSocket isConnected ifFalse: [ + ZnCannotConnectUnixSocket new file: socketFile; signal ]. ^ ipcSocket \ No newline at end of file diff --git a/repository/Zinc-HTTP.package/ZnByteArrayEntity.class/instance/readFrom..st b/repository/Zinc-HTTP.package/ZnByteArrayEntity.class/instance/readFrom..st index 0e2ffabe..8abf2b65 100644 --- a/repository/Zinc-HTTP.package/ZnByteArrayEntity.class/instance/readFrom..st +++ b/repository/Zinc-HTTP.package/ZnByteArrayEntity.class/instance/readFrom..st @@ -1,18 +1,16 @@ initialize-release readFrom: stream - self contentLength ifNil: [ self bytes: (ZnUtils readUpToEnd: stream limit: (ZnCurrentOptions at: #maximumEntitySize)). - self contentLength: self bytes size - ] - ifNotNil: [ | byteArray | - + self contentLength: self bytes size ] + ifNotNil: [ | byteArray readCount | self contentLength > (ZnCurrentOptions at: #maximumEntitySize) ifTrue: [ ZnEntityTooLarge signal ]. byteArray := ByteArray ofSize: self contentLength. - self contentLength > ZnUtils streamingBufferSize + readCount := self contentLength > ZnUtils streamingBufferSize ifTrue: [ ZnUtils streamFrom: stream to: byteArray writeStream size: self contentLength ] - ifFalse: [ stream next: self contentLength into: byteArray ]. - self bytes: byteArray - ] \ No newline at end of file + ifFalse: [ stream readInto: byteArray startingAt: 1 count: self contentLength ]. + readCount = self contentLength + ifTrue: [ self bytes: byteArray ] + ifFalse: [ self bytes: (byteArray copyFrom: 1 to: readCount); contentLength: readCount ] ] \ No newline at end of file diff --git a/repository/Zinc-HTTP.package/ZnStringEntity.class/instance/readFrom..st b/repository/Zinc-HTTP.package/ZnStringEntity.class/instance/readFrom..st index 4bc40252..40bc2d7c 100644 --- a/repository/Zinc-HTTP.package/ZnStringEntity.class/instance/readFrom..st +++ b/repository/Zinc-HTTP.package/ZnStringEntity.class/instance/readFrom..st @@ -5,7 +5,7 @@ readFrom: stream readStream := total ifNotNil: [ ZnLimitedReadStream on: stream limit: total ] ifNil: [ stream ]. buffer := String new: (ZnUtils streamingBufferSize min: (total ifNil: [ ZnUtils streamingBufferSize ])). stringStream := nil. - totalRead := 0. + totalRead := read := 0. self initializeEncoder. [ readStream atEnd ] whileFalse: [ [ read := encoder readInto: buffer startingAt: 1 count: buffer size fromStream: readStream ] @@ -22,7 +22,7 @@ readFrom: stream ifTrue: [ ZnEntityTooLarge signal ]. stringStream ifNil: [ readStream atEnd - ifTrue: [ ^ self string: (buffer copyFrom: 1 to: read) ] + ifTrue: [ ^ self string: (buffer copyFrom: 1 to: read); computeContentLength ] ifFalse: [ stringStream := (total ifNil: [ buffer species new ] ifNotNil: [ buffer species new: total ]) writeStream ] ]. stringStream next: read putAll: buffer startingAt: 1. ZnUtils signalProgress: totalRead total: total ]. diff --git a/repository/Zinc-HTTP.package/ZnUtils.class/class/streamFrom.to.size..st b/repository/Zinc-HTTP.package/ZnUtils.class/class/streamFrom.to.size..st index 81433730..66cdfef7 100644 --- a/repository/Zinc-HTTP.package/ZnUtils.class/class/streamFrom.to.size..st +++ b/repository/Zinc-HTTP.package/ZnUtils.class/class/streamFrom.to.size..st @@ -4,13 +4,14 @@ streamFrom: inputStream to: outputStream size: totalSize bufferSize := self streamingBufferSize min: totalSize. buffer := (inputStream isBinary ifTrue: [ ByteArray ] ifFalse: [ String ]) new: bufferSize. leftToRead := totalSize. - [ leftToRead > 0 ] - whileTrue: [ | readCount | - readCount := bufferSize min: leftToRead. - inputStream next: readCount into: buffer. + [ leftToRead > 0 and: [ inputStream atEnd not ] ] + whileTrue: [ | toReadCount readCount | + toReadCount := bufferSize min: leftToRead. + readCount := inputStream readInto: buffer startingAt: 1 count: toReadCount. leftToRead := leftToRead - readCount. outputStream next: readCount putAll: buffer startingAt: 1. leftToRead > 0 ifTrue: [ self signalProgress: (totalSize - leftToRead) total: totalSize. - outputStream flush ] ] \ No newline at end of file + outputStream flush ] ]. + ^ totalSize - leftToRead \ No newline at end of file