[Seaside] Seaside-REST, PUT, and the Server adaptors

Tobias Pape Das.Linux at gmx.de
Thu Apr 14 17:29:38 UTC 2011


Am 2011-04-14 um 18:40 schrieb Philippe Marschall:

> 2011/4/5 Tobias Pape <Das.Linux at gmx.de>:
>> Dear all
>> 
>> I played around with the Seaside-REST-portion for SqueakSource3
>> by Phillippe, and I figured, that it depends (at least for Squeak/Pharo)
>>  on the Adaptor whether it is possible to use PUT-Requests or not:
>> 
>> Having this code:
>> putMap: fileName ofProject: projectName
>>        <PUT>
>>        <Path: '/{projectName}/{fileName}.mcm'>
>>        | data |
>>        data := self requestContext request rawBody.
>> 
>> When using the Swazoo-Adaptor, data is nil, whatever I try
>> (certain combinations of raw sending, url-encode, form-encode
>> and the like)
> 
> Do you have a dump of the request? Do you have an easy way to
> reproduce it (Pharo 1.1 doesn't seem to ship with mcm)? I tried
> something very simple and could not reproduce it immediately.

Dump at the end
the point isn't the mcm but the rawBody being nil when Using 
Swazoo.

So any 

putSomething: fileName
	<PUT>
	<Path: '/fileName'>
	| data |
	data := self requestContext request rawBody.

shall result in data being nil.
( I verified in the Seaside OneClick)

put was done using:
curl -v -X PUT -T Seaside-GemStone-REST-Core-topa.2.mcz http://localhost:8888/rest/

So Long,
	-Tobias

=====
MyFilter(Object)>>halt
	Receiver: a MyFilter
	Arguments and temporary variables: 

	Receiver's instance variables: 
		filter: 	a WAValueHolder contents: a MyFilter
		parent: 	a WADispatcher
		configuration: 	a WAUserConfiguration
		routes: 	a WAByMethodRoutes

MyFilter>>putSomething:
	Receiver: a MyFilter
	Arguments and temporary variables: 
		fileName: 	'Seaside-GemStone-REST-Core-topa.2.mcz'
		data: 	nil
	Receiver's instance variables: 
		filter: 	a WAValueHolder contents: a MyFilter
		parent: 	a WADispatcher
		configuration: 	a WAUserConfiguration
		routes: 	a WAByMethodRoutes

WAComplexRoute(WARoute)>>sendSelectorWith:to:
	Receiver: a WAComplexRoute
	Arguments and temporary variables: 
		anArrayOfArguments: 	#('Seaside-GemStone-REST-Core-topa.2.mcz')
		anObject: 	a MyFilter
	Receiver's instance variables: 
		method: 	'PUT'
		selector: 	#putSomething:
		produces: 	a WAWildcardMimeTypeMatch
		consumes: 	a WAWildcardMimeTypeMatch
		pathMatches: 	an OrderedCollection(a WAFullPlaceholderPathMatch)
		parameterMatches: 	a Dictionary()
		isOverlyComplex: 	false

WARouteResult>>sendMessageTo:
	Receiver: a WARouteResult
	Arguments and temporary variables: 
		anObject: 	a MyFilter
		arguments: 	#('Seaside-GemStone-REST-Core-topa.2.mcz')
	Receiver's instance variables: 
		route: 	a WAComplexRoute
		elements: 	#('Seaside-GemStone-REST-Core-topa.2.mcz')
		parameters: 	a WARequestFields()

MyFilter(WARestfulHandler)>>executeResult:
	Receiver: a MyFilter
	Arguments and temporary variables: 
		aRouteResult: 	a WARouteResult
	Receiver's instance variables: 
		filter: 	a WAValueHolder contents: a MyFilter
		parent: 	a WADispatcher
		configuration: 	a WAUserConfiguration
		routes: 	a WAByMethodRoutes

MyFilter(WARestfulHandler)>>handleFiltered:
	Receiver: a MyFilter
	Arguments and temporary variables: 
		aRequestContext: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa...etc...
		result: 	a WARouteResult
	Receiver's instance variables: 
		filter: 	a WAValueHolder contents: a MyFilter
		parent: 	a WADispatcher
		configuration: 	a WAUserConfiguration
		routes: 	a WAByMethodRoutes

[] in MyFilter(WARequestHandler)>>handle:
	Receiver: a MyFilter
	Arguments and temporary variables: 
		aRequestContext: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa...etc...
	Receiver's instance variables: 
		filter: 	a WAValueHolder contents: a MyFilter
		parent: 	a WADispatcher
		configuration: 	a WAUserConfiguration
		routes: 	a WAByMethodRoutes

BlockClosure>>on:do:
	Receiver: [self filter handleFiltered: aRequestContext]
	Arguments and temporary variables: 
		exception: 	WACurrentRequestContext
		handlerAction: 	[:notification | notification resume: anObject]
		handlerActive: 	true
	Receiver's instance variables: 
		outerContext: 	MyFilter(WARequestHandler)>>handle:
		startpc: 	32
		numArgs: 	0

WACurrentRequestContext class(WADynamicVariable class)>>use:during:
	Receiver: WACurrentRequestContext
	Arguments and temporary variables: 
		anObject: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa.2.mcz'...etc...
		aBlock: 	[self filter handleFiltered: aRequestContext]
	Receiver's instance variables: 
		superclass: 	WADynamicVariable
		methodDict: 	a MethodDictionary()
		format: 	140
		instanceVariables: 	nil
		organization: 	('as yet unclassified')

		subclasses: 	nil
		name: 	#WACurrentRequestContext
		classPool: 	nil
		sharedPools: 	nil
		environment: 	a SystemDictionary(lots of globals)
		category: 	#'Seaside-Core-RequestHandling'
		traitComposition: 	{}
		localSelectors: 	nil

[] in WARequestContext>>push:while:
	Receiver: a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa.2.mcz'
	Arguments and temporary variables: 
		aBlock: 	[self filter handleFiltered: aRequestContext]
	Receiver's instance variables: 
		handlers: 	an OrderedCollection(a MyFilter a WADispatcher)
		request: 	a WARequest method: PUT uri: /rest/Seaside-GemStone-REST-Core-topa.2.m...etc...
		response: 	a WABufferedResponse status: 200 message: 'OK'
		codec: 	a GRNullCodec name: '(none)'
		consumer: 	a WAPathConsumer
		properties: 	nil

BlockClosure>>ensure:
	Receiver: [WACurrentRequestContext use: self during: aBlock]
	Arguments and temporary variables: 
		aBlock: 	[handlers removeFirst]
		complete: 	nil
		returnValue: 	nil
	Receiver's instance variables: 
		outerContext: 	WARequestContext>>push:while:
		startpc: 	42
		numArgs: 	0

WARequestContext>>push:while:
	Receiver: a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa.2.mcz'
	Arguments and temporary variables: 
		aRequestHandler: 	a MyFilter
		aBlock: 	[self filter handleFiltered: aRequestContext]
	Receiver's instance variables: 
		handlers: 	an OrderedCollection(a MyFilter a WADispatcher)
		request: 	a WARequest method: PUT uri: /rest/Seaside-GemStone-REST-Core-topa.2.m...etc...
		response: 	a WABufferedResponse status: 200 message: 'OK'
		codec: 	a GRNullCodec name: '(none)'
		consumer: 	a WAPathConsumer
		properties: 	nil

MyFilter(WARequestHandler)>>handle:
	Receiver: a MyFilter
	Arguments and temporary variables: 
		aRequestContext: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa...etc...
	Receiver's instance variables: 
		filter: 	a WAValueHolder contents: a MyFilter
		parent: 	a WADispatcher
		configuration: 	a WAUserConfiguration
		routes: 	a WAByMethodRoutes

WADispatcher>>handleFiltered:named:
	Receiver: a WADispatcher
	Arguments and temporary variables: 
		aRequestContext: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa...etc...
		aString: 	'rest'
	Receiver's instance variables: 
		filter: 	a WAValueHolder contents: a WADispatcher
		parent: 	nil
		configuration: 	a WAUserConfiguration
		defaultName: 	'browse'
		handlers: 	a Dictionary('browse'->a WAApplication 'comet'->a WADispatcher 'confi...etc...

WADispatcher>>handleFiltered:
	Receiver: a WADispatcher
	Arguments and temporary variables: 
		aRequestContext: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa...etc...
		consumer: 	a WAPathConsumer
	Receiver's instance variables: 
		filter: 	a WAValueHolder contents: a WADispatcher
		parent: 	nil
		configuration: 	a WAUserConfiguration
		defaultName: 	'browse'
		handlers: 	a Dictionary('browse'->a WAApplication 'comet'->a WADispatcher 'confi...etc...

[] in WADispatcher(WARequestHandler)>>handle:
	Receiver: a WADispatcher
	Arguments and temporary variables: 
		aRequestContext: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa...etc...
	Receiver's instance variables: 
		filter: 	a WAValueHolder contents: a WADispatcher
		parent: 	nil
		configuration: 	a WAUserConfiguration
		defaultName: 	'browse'
		handlers: 	a Dictionary('browse'->a WAApplication 'comet'->a WADispatcher 'confi...etc...

BlockClosure>>on:do:
	Receiver: [self filter handleFiltered: aRequestContext]
	Arguments and temporary variables: 
		exception: 	WACurrentRequestContext
		handlerAction: 	[:notification | notification resume: anObject]
		handlerActive: 	true
	Receiver's instance variables: 
		outerContext: 	WADispatcher(WARequestHandler)>>handle:
		startpc: 	32
		numArgs: 	0

WACurrentRequestContext class(WADynamicVariable class)>>use:during:
	Receiver: WACurrentRequestContext
	Arguments and temporary variables: 
		anObject: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa.2.mcz'...etc...
		aBlock: 	[self filter handleFiltered: aRequestContext]
	Receiver's instance variables: 
		superclass: 	WADynamicVariable
		methodDict: 	a MethodDictionary()
		format: 	140
		instanceVariables: 	nil
		organization: 	('as yet unclassified')

		subclasses: 	nil
		name: 	#WACurrentRequestContext
		classPool: 	nil
		sharedPools: 	nil
		environment: 	a SystemDictionary(lots of globals)
		category: 	#'Seaside-Core-RequestHandling'
		traitComposition: 	{}
		localSelectors: 	nil

[] in WARequestContext>>push:while:
	Receiver: a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa.2.mcz'
	Arguments and temporary variables: 
		aBlock: 	[self filter handleFiltered: aRequestContext]
	Receiver's instance variables: 
		handlers: 	an OrderedCollection(a MyFilter a WADispatcher)
		request: 	a WARequest method: PUT uri: /rest/Seaside-GemStone-REST-Core-topa.2.m...etc...
		response: 	a WABufferedResponse status: 200 message: 'OK'
		codec: 	a GRNullCodec name: '(none)'
		consumer: 	a WAPathConsumer
		properties: 	nil

BlockClosure>>ensure:
	Receiver: [WACurrentRequestContext use: self during: aBlock]
	Arguments and temporary variables: 
		aBlock: 	[handlers removeFirst]
		complete: 	nil
		returnValue: 	nil
	Receiver's instance variables: 
		outerContext: 	WARequestContext>>push:while:
		startpc: 	42
		numArgs: 	0

WARequestContext>>push:while:
	Receiver: a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa.2.mcz'
	Arguments and temporary variables: 
		aRequestHandler: 	a WADispatcher
		aBlock: 	[self filter handleFiltered: aRequestContext]
	Receiver's instance variables: 
		handlers: 	an OrderedCollection(a MyFilter a WADispatcher)
		request: 	a WARequest method: PUT uri: /rest/Seaside-GemStone-REST-Core-topa.2.m...etc...
		response: 	a WABufferedResponse status: 200 message: 'OK'
		codec: 	a GRNullCodec name: '(none)'
		consumer: 	a WAPathConsumer
		properties: 	nil

WADispatcher(WARequestHandler)>>handle:
	Receiver: a WADispatcher
	Arguments and temporary variables: 
		aRequestContext: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa...etc...
	Receiver's instance variables: 
		filter: 	a WAValueHolder contents: a WADispatcher
		parent: 	nil
		configuration: 	a WAUserConfiguration
		defaultName: 	'browse'
		handlers: 	a Dictionary('browse'->a WAApplication 'comet'->a WADispatcher 'confi...etc...

[] in WASwazooAdaptor(WAServerAdaptor)>>handleRequest:
	Receiver: a WASwazooAdaptor
	Arguments and temporary variables: 
		aRequestContext: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa...etc...
	Receiver's instance variables: 
		manager: 	a WAServerManager
		port: 	8888
		requestHandler: 	nil
		codec: 	a GRNullCodec name: '(none)'
		site: 	a WAPluggableSite

BlockClosure>>on:do:
	Receiver: [self requestHandler handle: aRequestContext]
	Arguments and temporary variables: 
		exception: 	WAResponseNotification
		handlerAction: 	[:n | nil]
		handlerActive: 	true
	Receiver's instance variables: 
		outerContext: 	WASwazooAdaptor(WAServerAdaptor)>>handleRequest:
		startpc: 	34
		numArgs: 	0

WASwazooAdaptor(WAServerAdaptor)>>handleRequest:
	Receiver: a WASwazooAdaptor
	Arguments and temporary variables: 
		aRequestContext: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa...etc...
	Receiver's instance variables: 
		manager: 	a WAServerManager
		port: 	8888
		requestHandler: 	nil
		codec: 	a GRNullCodec name: '(none)'
		site: 	a WAPluggableSite

WASwazooAdaptor(WAServerAdaptor)>>handle:
	Receiver: a WASwazooAdaptor
	Arguments and temporary variables: 
		aRequestContext: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa...etc...
	Receiver's instance variables: 
		manager: 	a WAServerManager
		port: 	8888
		requestHandler: 	nil
		codec: 	a GRNullCodec name: '(none)'
		site: 	a WAPluggableSite

[] in WASwazooAdaptor(WAServerAdaptor)>>process:
	Receiver: a WASwazooAdaptor
	Arguments and temporary variables: 
		context: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa.2.mcz'
	Receiver's instance variables: 
		manager: 	a WAServerManager
		port: 	8888
		requestHandler: 	nil
		codec: 	a GRNullCodec name: '(none)'
		site: 	a WAPluggableSite

BlockClosure>>ensure:
	Receiver: [self handle: context;
		 responseFrom: context]
	Arguments and temporary variables: 
		aBlock: 	[context destroy]
		complete: 	nil
		returnValue: 	nil
	Receiver's instance variables: 
		outerContext: 	WASwazooAdaptor(WAServerAdaptor)>>process:
		startpc: 	42
		numArgs: 	0

WASwazooAdaptor(WAServerAdaptor)>>process:
	Receiver: a WASwazooAdaptor
	Arguments and temporary variables: 
		aNativeRequest: 	a HTTPRequest PUT
	 from: 127.0.0.1
	 at: 14 April 2011 7:26:15...etc...
		context: 	a WARequestContext url: '/rest/Seaside-GemStone-REST-Core-topa.2.mcz'
	Receiver's instance variables: 
		manager: 	a WAServerManager
		port: 	8888
		requestHandler: 	nil
		codec: 	a GRNullCodec name: '(none)'
		site: 	a WAPluggableSite

WAPluggableSite>>answerTo:
	Receiver: a WAPluggableSite
	Arguments and temporary variables: 
		aSwazooRequest: 	a HTTPRequest PUT
	 from: 127.0.0.1
	 at: 14 April 2011 7:26:15...etc...
	Receiver's instance variables: 
		enabled: 	true
		uriPattern: 	an OrderedCollection(a SiteIdentifier)
		parent: 	a ServerRootComposite
		children: 	an OrderedCollection()
		name: 	'JdtXFS6WW74pqWQaTtDjP2FM1351bdiw'
		serving: 	true
		handler: 	a WASwazooAdaptor

WAPluggableSite>>helpResolve:
	Receiver: a WAPluggableSite
	Arguments and temporary variables: 
		aResolution: 	an URIResolution
	Receiver's instance variables: 
		enabled: 	true
		uriPattern: 	an OrderedCollection(a SiteIdentifier)
		parent: 	a ServerRootComposite
		children: 	an OrderedCollection()
		name: 	'JdtXFS6WW74pqWQaTtDjP2FM1351bdiw'
		serving: 	true
		handler: 	a WASwazooAdaptor

URIResolution>>visitResource:
	Receiver: an URIResolution
	Arguments and temporary variables: 
		aResource: 	a WAPluggableSite
	Receiver's instance variables: 
		position: 	1
		request: 	a HTTPRequest PUT
	 from: 127.0.0.1
	 at: 14 April 2011 7:26:15 pm
	 h...etc...

[] in URIResolution>>visitChildrenOf:advancing:
	Receiver: an URIResolution
	Arguments and temporary variables: 
		response: 	a WAPluggableSite
		each: 	#(nil)
	Receiver's instance variables: 
		position: 	1
		request: 	a HTTPRequest PUT
	 from: 127.0.0.1
	 at: 14 April 2011 7:26:15 pm
	 h...etc...

OrderedCollection>>do:
	Receiver: an OrderedCollection(a WAPluggableSite)
	Arguments and temporary variables: 
		aBlock: 	[:each | 
response := self visitResource: each.
	response isNil
		ifFal...etc...
		index: 	3
	Receiver's instance variables: 
		array: 	an Array(nil nil a WAPluggableSite nil nil nil nil nil nil nil)
		firstIndex: 	3
		lastIndex: 	3

URIResolution>>visitChildrenOf:advancing:
	Receiver: an URIResolution
	Arguments and temporary variables: 
		aResource: 	a ServerRootComposite
		aBoolean: 	false
		response: 	#(nil)
	Receiver's instance variables: 
		position: 	1
		request: 	a HTTPRequest PUT
	 from: 127.0.0.1
	 at: 14 April 2011 7:26:15 pm
	 h...etc...

URIResolution>>resolveTransparentComposite:
	Receiver: an URIResolution
	Arguments and temporary variables: 
		aCompositeResource: 	a ServerRootComposite
	Receiver's instance variables: 
		position: 	1
		request: 	a HTTPRequest PUT
	 from: 127.0.0.1
	 at: 14 April 2011 7:26:15 pm
	 h...etc...

URIResolution>>resolveServerRoot:
	Receiver: an URIResolution
	Arguments and temporary variables: 
		aServerRoot: 	a ServerRootComposite
	Receiver's instance variables: 
		position: 	1
		request: 	a HTTPRequest PUT
	 from: 127.0.0.1
	 at: 14 April 2011 7:26:15 pm
	 h...etc...

ServerRootComposite>>helpResolve:
	Receiver: a ServerRootComposite
	Arguments and temporary variables: 
		aResolution: 	an URIResolution
	Receiver's instance variables: 
		enabled: 	true
		uriPattern: 	''
		parent: 	nil
		children: 	an OrderedCollection(a WAPluggableSite)

URIResolution>>visitResource:
	Receiver: an URIResolution
	Arguments and temporary variables: 
		aResource: 	a ServerRootComposite
	Receiver's instance variables: 
		position: 	1
		request: 	a HTTPRequest PUT
	 from: 127.0.0.1
	 at: 14 April 2011 7:26:15 pm
	 h...etc...


--- The full stack ---
MyFilter(Object)>>halt
MyFilter>>putSomething:
WAComplexRoute(WARoute)>>sendSelectorWith:to:
WARouteResult>>sendMessageTo:
MyFilter(WARestfulHandler)>>executeResult:
MyFilter(WARestfulHandler)>>handleFiltered:
[] in MyFilter(WARequestHandler)>>handle:
BlockClosure>>on:do:
WACurrentRequestContext class(WADynamicVariable class)>>use:during:
[] in WARequestContext>>push:while:
BlockClosure>>ensure:
WARequestContext>>push:while:
MyFilter(WARequestHandler)>>handle:
WADispatcher>>handleFiltered:named:
WADispatcher>>handleFiltered:
[] in WADispatcher(WARequestHandler)>>handle:
BlockClosure>>on:do:
WACurrentRequestContext class(WADynamicVariable class)>>use:during:
[] in WARequestContext>>push:while:
BlockClosure>>ensure:
WARequestContext>>push:while:
WADispatcher(WARequestHandler)>>handle:
[] in WASwazooAdaptor(WAServerAdaptor)>>handleRequest:
BlockClosure>>on:do:
WASwazooAdaptor(WAServerAdaptor)>>handleRequest:
WASwazooAdaptor(WAServerAdaptor)>>handle:
[] in WASwazooAdaptor(WAServerAdaptor)>>process:
BlockClosure>>ensure:
WASwazooAdaptor(WAServerAdaptor)>>process:
WAPluggableSite>>answerTo:
WAPluggableSite>>helpResolve:
URIResolution>>visitResource:
[] in URIResolution>>visitChildrenOf:advancing:
OrderedCollection>>do:
URIResolution>>visitChildrenOf:advancing:
URIResolution>>resolveTransparentComposite:
URIResolution>>resolveServerRoot:
ServerRootComposite>>helpResolve:
URIResolution>>visitResource:
 - - - - - - - - - - - - - - -  
			- - - - - - - - - - - - - - - - - -
URIResolution class>>resolveRequest:startingAt:
HTTPServer>>answerTo:
HTTPConnection>>produceResponseFor:
HTTPConnection>>getAndDispatchMessages
[] in [] in [] in HTTPConnection>>interact
BlockClosure>>on:do:
[] in [] in HTTPConnection>>interact
BlockClosure>>ifCurtailed:
[] in HTTPConnection>>interact




More information about the seaside mailing list