[Seaside] [FIX][FIX] large files / WAFile & MultipartChunk & WAKom
streaming
Colin Curtin
alpine at umail.ucsb.edu
Sat Apr 10 01:01:14 CEST 2004
Please disregard my last post and changeset. I have made streaming work
in the way expected. All it took was subclassing WAGenericResponse, and
overriding #contents and making a new method, #contents:.
The download time for an 80mb file is 1:38.00 This is a significant
improvement, and does not require the file's contents to be uploaded to
memory before sending the file.
Attached is the complete changeset including the changes to the Html
renderer for using #anchorStreamedDocument:.
Thanks!
-------------- next part --------------
'From Squeak3.6 of ''6 October 2003'' [latest update: #5429] on 9 April 2004 at 4:00:30 pm'!
Object subclass: #WAFile
instanceVariableNames: 'contents fileName tempFile '
classVariableNames: ''
poolDictionaries: ''
category: 'Seaside/Base-Utilities'!
TestCase subclass: #WAFileTest
instanceVariableNames: 'file localfilestream filename '
classVariableNames: ''
poolDictionaries: ''
category: 'Seaside/Base-Utilities'!
WADocumentHandler subclass: #WAStreamedDocumentHandler
instanceVariableNames: 'stream '
classVariableNames: ''
poolDictionaries: ''
category: 'Seaside/Base-Handlers'!
WAGenericResponse subclass: #WAStreamedResponse
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Seaside/Base-Responses'!
WAComponent subclass: #WAStreamedUploadTest
instanceVariableNames: 'file '
classVariableNames: ''
poolDictionaries: ''
category: 'Seaside/Examples-Test'!
!WAFile methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 18:33'!
clearTemp
self tempDir deleteFileNamed: self tempFile! !
!WAFile methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 15:55'!
contents
^ self stream contents! !
!WAFile methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 18:32'!
stream
^ self tempDir readOnlyFileNamed: self tempFile! !
!WAFile methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 18:00'!
tempDir
| default tempName |
default _ FileDirectory default.
tempName _ 'seaside-tmp'.
(default directoryExists: tempName) ifFalse: [ default createDirectory: tempName ].
^ default directoryNamed: tempName! !
!WAFile methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 17:37'!
tempFile
^ tempFile! !
!WAFile methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 17:37'!
tempFile: aFileDirectory
tempFile _ aFileDirectory! !
!WAFile class methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 18:04'!
fileName: aName stream: aStream
| tmpfilename newfile |
tmpfilename _ UUID new asString.
newfile _ self new.
newfile tempDir putFile: aStream named: tmpfilename.
^ newfile tempFile: tmpfilename; fileName: aName.! !
!WAFileTest methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 18:20'!
setUp
| ws |
filename _ 'testing'.
ws _ FileDirectory default forceNewFileNamed: filename.
ws nextPutAll: 'this is a test'.
ws close.
localfilestream _ FileDirectory default fileNamed: filename.
file _ WAFile fileName: filename stream: localfilestream.! !
!WAFileTest methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 18:06'!
tearDown
localfilestream close.
FileDirectory default deleteFileNamed: filename.
file _ nil.! !
!WAFileTest methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 17:53'!
testContent
self assert: file contents = 'this is a test'! !
!WAFileTest methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 17:54'!
testFilename
self assert: file fileName = filename! !
!WAHtmlRenderer methodsFor: 'documents' stamp: 'cc 4/7/2004 17:18'!
anchorWithStreamedDocument: aStream mimeType: mimeType fileName: fileName text: aString
self openAnchorWithStreamedDocument: aStream mimeType: mimeType fileName: fileName.
self text: aString.
self close.! !
!WAHtmlRenderer methodsFor: 'documents' stamp: 'cc 4/7/2004 17:18'!
openAnchorWithStreamedDocument: aStream mimeType: mimeType fileName: fileName
self attributeAt: 'href' put: (self urlForStreamedDocument: aStream mimeType: mimeType fileName: fileName).
self openTag: #a.! !
!WAHtmlRenderer methodsFor: 'documents' stamp: 'cc 4/7/2004 17:14'!
urlForStreamedDocument: aStream mimeType: mimeType fileName: fileName
^ WASession currentSession application urlForRequestHandler:
(WAStreamedDocumentHandler
stream: aStream
mimeType: mimeType
fileName: fileName)! !
!WAKom methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 19:21'!
processMultipartFields: aRequest
aRequest multipartFormFieldsDo:
[:chunk |
chunk fileName isEmptyOrNil ifFalse:
[| file |
file _ WAFile fileName: chunk fileName stream: chunk fileContents readStream.
aRequest postFields at: chunk fieldName put: file]].! !
!WAStreamedDocumentHandler methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 19:32'!
= other
^ (other species = self species
and: [other stream asString = self stream asString])
and: [other mimeType = self mimeType]! !
!WAStreamedDocumentHandler methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 17:12'!
document
^ self shouldNotImplement! !
!WAStreamedDocumentHandler methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 19:31'!
hash
^ self stream hash bitXor: self mimeType hash! !
!WAStreamedDocumentHandler methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 19:27'!
initializeWithStream: aStream mimeType: mimeString fileName: fileString
stream _ aStream.
mimeType _ mimeString.
fileName _ fileString.! !
!WAStreamedDocumentHandler methodsFor: 'as yet unclassified' stamp: 'cc 4/8/2004 03:08'!
response
| response buffer |
response _ WAGenericResponse new.
buffer _ String new: 50000.
[self stream atEnd] whileFalse:
[response nextPutAll: (self stream nextInto: buffer)].
self stream close.
response contentType: mimeType.
response headerAt: 'Expires' put: 'Thu, 01 Jan 2095 12:00:00 GMT'.
fileName ifNotNil:
[response headerAt: 'Content-Disposition' put: 'attachment; filename=' , fileName].
^ response! !
!WAStreamedDocumentHandler methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 17:05'!
stream
^ stream! !
!WAStreamedDocumentHandler methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 17:05'!
stream: aStream
stream _ aStream! !
!WAStreamedDocumentHandler class methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 19:29'!
stream: aStream mimeType: mimeString fileName: fileString
^ self basicNew initializeWithStream: aStream mimeType: mimeString fileName: fileString! !
!WAStreamedResponse methodsFor: 'as yet unclassified' stamp: 'cc 4/9/2004 13:41'!
contents
^ stream! !
!WAStreamedResponse methodsFor: 'as yet unclassified' stamp: 'cc 4/9/2004 13:41'!
contents: aReadStream
stream _ aReadStream! !
!WAStreamedUploadTest methodsFor: 'as yet unclassified' stamp: 'cc 4/7/2004 18:35'!
renderContentOn: html
html heading: 'Upload Streamed File (for large files)'.
html attributeAt: 'enctype' put: 'multipart/form-data'.
html form: [
html fileUploadWithCallback: [:f | file _ f].
html submitButton.
].
file ifNotNil: [
[html anchorWithStreamedDocument: file stream mimeType: 'application/octet-stream' fileName: file fileName text: file fileName]
ensure: [file clearTemp]].! !
More information about the Seaside
mailing list