diff --git a/repository/Seaside-Core.package/WAComboResponse.class/class/external..st b/repository/Seaside-Core.package/WAComboResponse.class/class/external..st deleted file mode 100644 index 198616151..000000000 --- a/repository/Seaside-Core.package/WAComboResponse.class/class/external..st +++ /dev/null @@ -1,5 +0,0 @@ -instance creation -external: anExternalStream - ^ self - onBuffered: (GRPlatform current writeCharacterStreamOn: (String new: 4096)) - external: anExternalStream \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/class/onBuffered.external..st b/repository/Seaside-Core.package/WAComboResponse.class/class/onBuffered.external..st deleted file mode 100644 index da998c54e..000000000 --- a/repository/Seaside-Core.package/WAComboResponse.class/class/onBuffered.external..st +++ /dev/null @@ -1,3 +0,0 @@ -instance creation -onBuffered: aBufferedStream external: anExternalStream - ^ self basicNew initializeOnBuffered: aBufferedStream external: anExternalStream \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/class/onStream.bufferSize.codec..st b/repository/Seaside-Core.package/WAComboResponse.class/class/onStream.bufferSize.codec..st new file mode 100644 index 000000000..a758fb706 --- /dev/null +++ b/repository/Seaside-Core.package/WAComboResponse.class/class/onStream.bufferSize.codec..st @@ -0,0 +1,5 @@ +instance creation +onStream: aStream bufferSize: anInteger codec: aGRCodec + ^ self basicNew + initializeOnStream: aStream bufferSize: anInteger codec: aGRCodec; + yourself \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/binary.st b/repository/Seaside-Core.package/WAComboResponse.class/instance/binary.st index 95256c943..e9b61c427 100644 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/binary.st +++ b/repository/Seaside-Core.package/WAComboResponse.class/instance/binary.st @@ -2,5 +2,5 @@ streaming binary "put the response stream into binary mode" - bufferedStream := (GRCountingStream on: (GRPlatform current readWriteByteStream)). + bufferedStream := GRPlatform current readWriteByteStream. externalStream binary \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/bufferedStream..st b/repository/Seaside-Core.package/WAComboResponse.class/instance/bufferedStream..st deleted file mode 100644 index a3e6e42f4..000000000 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/bufferedStream..st +++ /dev/null @@ -1,5 +0,0 @@ -accessing -bufferedStream: aStream - "The stream to buffer data before sending it" - - bufferedStream := aStream \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/bufferedStream.st b/repository/Seaside-Core.package/WAComboResponse.class/instance/bufferedStream.st deleted file mode 100644 index 1581421d1..000000000 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/bufferedStream.st +++ /dev/null @@ -1,5 +0,0 @@ -accessing -bufferedStream - "The stream to buffer data before sending it" - - ^ bufferedStream \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/close.st b/repository/Seaside-Core.package/WAComboResponse.class/instance/close.st index 1e6bf13b8..3459ac55f 100644 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/close.st +++ b/repository/Seaside-Core.package/WAComboResponse.class/instance/close.st @@ -3,5 +3,14 @@ close "Send a zero-sized chunk to end the data transfer." closed ifTrue: [ self error: 'Response is closed' ]. - externalStream nextPutAll: '0'; crlf; crlf; flush. + externalStream + "zero length chunk" + nextPut: 0; + "crlf" + nextPut: 13; + nextPut: 10; + "crlf" + nextPut: 13; + nextPut: 10; + flush. closed := true \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/commit.st b/repository/Seaside-Core.package/WAComboResponse.class/instance/commit.st index f32d6ee2b..ac5da2456 100644 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/commit.st +++ b/repository/Seaside-Core.package/WAComboResponse.class/instance/commit.st @@ -1,5 +1,6 @@ initialization commit + | encodingStream | "Begin a partial transmission" self committedCheck. @@ -8,7 +9,20 @@ commit self headerAt: 'Transfer-Encoding' put: 'chunked'. committed := true. - self writeStatusOn: externalStream. - self writeHeadersOn: externalStream. - self writeCookiesOn: externalStream. - externalStream crlf; flush \ No newline at end of file + + "The external stream is usually byte based. Unfortunately, the + streams aren't compatible enough at the moment such that everything + could be written to the external stream directly (in particular, writing of + single characters doesn't work). Luckily, the encoders already translate + characters to bytes, so we only need to wrap the stream with the appropariate + encoder. Header data is always ASCII encoded. + Because older versions of Seaside don't have a dedicated ASCII encoder we + use UTF-8 here (ASCII is a subset of UTF-8)." + encodingStream := (GRCodec forEncoding: 'utf-8') encoderFor: externalStream. + self + writeStatusOn: encodingStream; + writeHeadersOn: encodingStream; + writeCookiesOn: encodingStream. + encodingStream + crlf; + flush diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/destroy.st b/repository/Seaside-Core.package/WAComboResponse.class/instance/destroy.st index 8bef51679..5a2d40415 100644 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/destroy.st +++ b/repository/Seaside-Core.package/WAComboResponse.class/instance/destroy.st @@ -4,4 +4,5 @@ destroy super destroy. bufferedStream := nil. - externalStream := nil \ No newline at end of file + externalStream := nil. + codec := nil diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/externalStream..st b/repository/Seaside-Core.package/WAComboResponse.class/instance/externalStream..st deleted file mode 100644 index 8f6b63496..000000000 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/externalStream..st +++ /dev/null @@ -1,5 +0,0 @@ -accessing -externalStream: aSocketStream - "The external (socket) stream to send data to" - - externalStream := aSocketStream \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/externalStream.st b/repository/Seaside-Core.package/WAComboResponse.class/instance/externalStream.st deleted file mode 100644 index 2004cf945..000000000 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/externalStream.st +++ /dev/null @@ -1,5 +0,0 @@ -accessing -externalStream - "The external (socket) stream to send data to" - - ^ externalStream \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/flush.st b/repository/Seaside-Core.package/WAComboResponse.class/instance/flush.st index 5031c3103..bb6d9def5 100644 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/flush.st +++ b/repository/Seaside-Core.package/WAComboResponse.class/instance/flush.st @@ -1,9 +1,8 @@ public flush "Flush the receiver and send partial content" - committed ifFalse: [ self commit ]. "Write the partial content if any" - self nextChunk: bufferedStream count put: bufferedStream contents. + self nextChunk: bufferedStream size put: bufferedStream contents. bufferedStream reset \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/initializeOnBuffered.external..st b/repository/Seaside-Core.package/WAComboResponse.class/instance/initializeOnBuffered.external..st deleted file mode 100644 index 67c936032..000000000 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/initializeOnBuffered.external..st +++ /dev/null @@ -1,9 +0,0 @@ -initialization -initializeOnBuffered: aBufferedStream external: anExternalStream - "Initialize the receiver" - - self initialize. - bufferedStream := aBufferedStream. - externalStream := anExternalStream. - committed := false. - closed := false \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/initializeOnStream.bufferSize.codec..st b/repository/Seaside-Core.package/WAComboResponse.class/instance/initializeOnStream.bufferSize.codec..st new file mode 100644 index 000000000..8674b1819 --- /dev/null +++ b/repository/Seaside-Core.package/WAComboResponse.class/instance/initializeOnStream.bufferSize.codec..st @@ -0,0 +1,12 @@ +initialization +initializeOnStream: aStream bufferSize: anInteger codec: aGRCodec + "Initialize the receiver" + + | rawBufferedStream | + self initialize. + codec := aGRCodec. + rawBufferedStream := GRPlatform current writeCharacterStreamOn: (aGRCodec encodedStringClass new: anInteger). + bufferedStream := aGRCodec encoderFor: rawBufferedStream. + externalStream := aStream. + committed := false. + closed := false \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/nextChunk.put..st b/repository/Seaside-Core.package/WAComboResponse.class/instance/nextChunk.put..st index 12d64c2b8..f4c1c3601 100644 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/nextChunk.put..st +++ b/repository/Seaside-Core.package/WAComboResponse.class/instance/nextChunk.put..st @@ -1,13 +1,19 @@ streaming nextChunk: anInteger put: data - "Write a chunk of data to the external stream. Does NOT write if no data is provided since this would logically end the chunked transfer. To end data transfer use #close instead. Raise an error if the response has been committed and closed. - - Unfortunately the size of the chunk is not measured in bytes but characters so we need the ability to pass in the chunk size - see also - http://code.google.com/p/seaside/issues/detail?id=733" + "Write a chunk of data to the external stream. Does NOT write if no data is provided since this would logically end the chunked transfer. To end data transfer use #close instead. Raise an error if the response has been committed and closed." data isEmpty ifTrue: [ ^ self ]. closed ifTrue: [ self error: 'Response is closed' ]. - externalStream nextPutAll: (anInteger printStringBase: 16); crlf. - externalStream nextPutAll: data; crlf; flush \ No newline at end of file + "Per specification, write the length of the chunk as hexadecimal number. + See https://httpwg.org/specs/rfc7230.html#chunked.encoding" + externalStream + nextPutAll: (anInteger printStringBase: 16) asByteArray; + "crlf" + nextPut: 13; + nextPut: 10; + nextPutAll: data; + "crlf" + nextPut: 13; + nextPut: 10; + flush \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/nextChunkPut..st b/repository/Seaside-Core.package/WAComboResponse.class/instance/nextChunkPut..st deleted file mode 100644 index a3d5ce1af..000000000 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/nextChunkPut..st +++ /dev/null @@ -1,5 +0,0 @@ -streaming -nextChunkPut: data - "Write a chunk of data to the external stream. Does NOT write if no data is provided since this would logically end the chunked transfer. To end data transfer use #close instead. Raise an error if the response has been committed and closed." - - self nextChunk: data size put: data \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/instance/writeHeadersOn..st b/repository/Seaside-Core.package/WAComboResponse.class/instance/writeHeadersOn..st index c19fb49d1..2666fd367 100644 --- a/repository/Seaside-Core.package/WAComboResponse.class/instance/writeHeadersOn..st +++ b/repository/Seaside-Core.package/WAComboResponse.class/instance/writeHeadersOn..st @@ -2,6 +2,6 @@ writing writeHeadersOn: aStream self isChunked ifFalse: [ self - headerAt: 'Content-Length' - put: bufferedStream position ]. + headerAt: 'Content-Length' + put: bufferedStream position ]. super writeHeadersOn: aStream \ No newline at end of file diff --git a/repository/Seaside-Core.package/WAComboResponse.class/properties.json b/repository/Seaside-Core.package/WAComboResponse.class/properties.json index 13d822eec..e8a58e292 100644 --- a/repository/Seaside-Core.package/WAComboResponse.class/properties.json +++ b/repository/Seaside-Core.package/WAComboResponse.class/properties.json @@ -1,15 +1,17 @@ { - "commentStamp" : "pmm 8/25/2019 11:14", + "commentStamp" : "ar 8/4/2010 20:31", "super" : "WAResponse", "category" : "Seaside-Core-HTTP", "classinstvars" : [ ], "pools" : [ ], "classvars" : [ ], "instvars" : [ - "bufferedStream", - "externalStream", + "codec", "committed", - "closed" + "externalStream", + "closed", + "bufferedStream", + "countingStream" ], "name" : "WAComboResponse", "type" : "normal" diff --git a/repository/Seaside-Core.package/monticello.meta/categories.st b/repository/Seaside-Core.package/monticello.meta/categories.st index c60fc8765..6d88cf02e 100644 --- a/repository/Seaside-Core.package/monticello.meta/categories.st +++ b/repository/Seaside-Core.package/monticello.meta/categories.st @@ -1,17 +1,17 @@ -SystemOrganization addCategory: #'Seaside-Core'! -SystemOrganization addCategory: #'Seaside-Core-Backtracking'! -SystemOrganization addCategory: #'Seaside-Core-Base'! -SystemOrganization addCategory: #'Seaside-Core-Cache'! -SystemOrganization addCategory: #'Seaside-Core-Callbacks'! -SystemOrganization addCategory: #'Seaside-Core-Configuration'! -SystemOrganization addCategory: #'Seaside-Core-Document'! SystemOrganization addCategory: #'Seaside-Core-Document-Elements'! -SystemOrganization addCategory: #'Seaside-Core-Exceptions'! -SystemOrganization addCategory: #'Seaside-Core-Filter'! -SystemOrganization addCategory: #'Seaside-Core-HTTP'! -SystemOrganization addCategory: #'Seaside-Core-Libraries'! -SystemOrganization addCategory: #'Seaside-Core-Manifest'! -SystemOrganization addCategory: #'Seaside-Core-Rendering'! -SystemOrganization addCategory: #'Seaside-Core-RequestHandling'! -SystemOrganization addCategory: #'Seaside-Core-Server'! -SystemOrganization addCategory: #'Seaside-Core-Utilities'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Backtracking'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Base'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Cache'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Callbacks'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Configuration'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Document'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Exceptions'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Filter'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-HTTP'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Libraries'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Manifest'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Rendering'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-RequestHandling'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Server'! +SystemOrganization addCategory: #'Seaside-Core-Document-Elements-Seaside-Core-Utilities'! diff --git a/repository/Seaside-Tests-Core.package/WAComboResponseTest.class/instance/response.st b/repository/Seaside-Tests-Core.package/WAComboResponseTest.class/instance/response.st index b5dfcaf1e..65d426be6 100644 --- a/repository/Seaside-Tests-Core.package/WAComboResponseTest.class/instance/response.st +++ b/repository/Seaside-Tests-Core.package/WAComboResponseTest.class/instance/response.st @@ -1,3 +1,7 @@ accessing response - ^ super response ifNil: [ response := WAComboResponse external: (GRPlatform current writeCharacterStreamOn: (String new: 4096)) ] \ No newline at end of file + ^ super response ifNil: [ + response := WAComboResponse + onStream: (GRPlatform current writeCharacterStreamOn: (ByteArray new: 1024)) + bufferSize: 1024 + codec: (GRCodec forEncoding: 'utf-8') ] \ No newline at end of file diff --git a/repository/Seaside-Tests-Core.package/WAComboResponseTest.class/instance/testCommit.st b/repository/Seaside-Tests-Core.package/WAComboResponseTest.class/instance/testCommit.st new file mode 100644 index 000000000..9d0870309 --- /dev/null +++ b/repository/Seaside-Tests-Core.package/WAComboResponseTest.class/instance/testCommit.st @@ -0,0 +1,8 @@ +tests +testCommit + self response + contentType: 'text/html'; + nextPutAll: 'Visit seaside.st.'; + commit. + + self assert: self response isCommitted \ No newline at end of file diff --git a/repository/Seaside-Tests-Core.package/WAComboResponseTest.class/instance/testWithBinaryStream.st b/repository/Seaside-Tests-Core.package/WAComboResponseTest.class/instance/testWithBinaryStream.st new file mode 100644 index 000000000..8dc0e0d10 --- /dev/null +++ b/repository/Seaside-Tests-Core.package/WAComboResponseTest.class/instance/testWithBinaryStream.st @@ -0,0 +1,14 @@ +tests +testWithBinaryStream + ByteArray streamContents: [ :stream | + response := WAComboResponse + onStream: stream + bufferSize: 1024 + codec: (GRCodec forEncoding: 'utf-8'). + + response + nextPut: Character space; + flush; + close ] + + \ No newline at end of file diff --git a/repository/Zinc-Seaside.package/ZnZincStreamingServerAdaptor.class/instance/responseFor..st b/repository/Zinc-Seaside.package/ZnZincStreamingServerAdaptor.class/instance/responseFor..st index 324ad6379..9df0db915 100644 --- a/repository/Zinc-Seaside.package/ZnZincStreamingServerAdaptor.class/instance/responseFor..st +++ b/repository/Zinc-Seaside.package/ZnZincStreamingServerAdaptor.class/instance/responseFor..st @@ -1,8 +1,6 @@ converting responseFor: aZnRequest - | bufferedStream codecStream | - bufferedStream := GRPlatform current writeCharacterStreamOn: (self codec encodedStringClass new: 4096). - codecStream := self codec encoderFor: bufferedStream. ^ WAComboResponse - onBuffered: (GRCountingStream on: codecStream) - external: aZnRequest stream \ No newline at end of file + onStream: aZnRequest stream + bufferSize: 4096 + codec: self codec \ No newline at end of file