[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