Yes, it does have to do with the headers. I accidentally replied to
Chuck off-list, but the only difference in the headers between an app
built as a .woa and one built as a .war is in the case of the header
keys. It turns out that this makes a difference...
There is a bug in the way WebObjects 5.4 handles HTTP headers when
applications are deployed in servlet containers.
When WebObjects applications are deployed in servlet containers, the
WebObjects application does not receive requests or generate responses
directly. Instead, the WOServletAdaptor sits in between the WebObjects
application and the servlet container. All requests and responses are
sent to the servlet container, which then dispatches them to the
WOServletAdaptor, which dispatches them to the underlying WebObjects
application. Responses are handled in the same way, but in the
opposite direction.
A bug exists in how the WOServletAdaptor and the WOMessage and
WORequest classes handle HTTP headers. It seems that WOMessage and
WORequest expect all headers to be lower-case - and that the
WOServletAdaptor does not make sure all headers are lower-case.
This means that when a WebObjects application is deployed in a servlet
container, the following rather strange situation occurs:
A HTTP request is sent to the application (via the servlet container
and WOServletAdaptor) containing a Content-Type header:
eg. Content-Type = ( multipart/form-data; boundary=----
WebKitFormBoundarytAEgAmILbXskfM9V);
The WOServletAdaptor passes this header on to the WebObjects
application, so if we were to enumerate the headers with the following
code, we'd see something like:
NSDictionary headers = this.context().request().headers();
for(int i=0;i<headers.allKeys().count();i++) {
String header = (String)
headers.allKeys().objectAtIndex(i);
System.out.println(header + ": ");
System.out.println(headers.valueForKey(header));
}
<snip>
Content-Type:
( multipart/form-data; boundary=----WebKitFormBoundarytAEgAmILbXskfM9V )
</snip>
However, a problem exists because the valueForHeader() method in
WOMessage assumes all headers are lower-case, so when WORequest
attempts to determine if the request isMultipartFormData(), it does so
by asking for the contentType() - which results in a call to
valueForHeader(), which in turn calls the get() method of the
underlying TreeMap of _httpHeaders, but mistakenly does so with a
lower-case version of the key:
(List)_httpHeaders.get(aKey.toString().toLowerCase());
This problem can be confirmed by adding the following to the earlier
enumeration of headers:
NSDictionary headers = this.context().request().headers();
for(int i=0;i<headers.allKeys().count();i++) {
String header = (String)
headers.allKeys().objectAtIndex(i);
System.out.println(header + ": ");
System.out.println(headers.valueForKey(header));
System.out.println(this.context().request().headerForKey(header));
}
When this is deployed as a .woa, it produces the following correct
output:
<snip>
content-type:
( multipart/form-data; boundary=----WebKitFormBoundaryZdrwLAre6TArzAid )
multipart/form-data; boundary=----WebKitFormBoundaryZdrwLAre6TArzAid
</snip>
But when it is run in a servlet container, it produces the following,
obviously incorrect output:
<snip>
Content-Type:
( multipart/form-data; boundary=----WebKitFormBoundaryonU48QK5I46+pA1T )
null
</snip>
The result of all of this is that if you specify the "enctype" of your
form as "multipart/form-data" none of the bindings for your form will
get values.
As for a work-around, it is pretty hacky but you can write your own
WOSerlvetAdaptor sub-class and override the default implementation of
doPost to change the case of any HTTP headers before handling the
request.
Regards,
Jake MacMullin
On 29/01/2008, at 11:18 AM, Chuck Hill wrote:
What are the difference in headers in the two requests?
Chuck
On Jan 28, 2008, at 4:00 PM, Jake MacMullin wrote:
Hi All,
I think I've found a bug - and before I submit a bug report I
thought I'd check to see if anyone else has encountered it and if
there are any work-arounds.
It seems that WOForms with an enctype of "multipart/form-data" are
broken in WebObjects 5.4 when you're deploying an application as a
WAR.
I've got the following simple component:
HTML:
<wo:WOForm>
<wo:WOTextField value =
"[message]"></wo:WOTextField>
<wo:WOSubmitButton action =
"[sayHello]"></wo:WOSubmitButton>
</wo:WOForm>
<wo:WOForm enctype = "multipart/form-data">
<wo:WOTextField value =
"[message]"></wo:WOTextField>
<wo:WOSubmitButton action =
"[sayHello]"></wo:WOSubmitButton>
</wo:WOForm>
<wo:WOString value = "[message]"></wo:WOString>
Java:
public String message;
public Main(WOContext context) {
super(context);
}
public WOComponent sayHello() {
message = "hello, " + message + "!";
return(this);
}
If I build my application as a .woa everything works as I'd expect
it to, however, if I build my application as a WAR then the form
with the enctype of "multipart/form-data" fails. My instance
variable does not get assigned a value - but remains null.
This is obviously a problem as it means that WOFileUpload doesn't
work with WO 5.4 applications built as a WAR. Anyone else
encountered this? Any idea of a work-around?
Regards,
Jake
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/chill%40global-village.net
This email sent to [EMAIL PROTECTED]
--
Practical WebObjects - for developers who want to increase their
overall knowledge of WebObjects or who are trying to solve specific
problems.
http://www.global-village.net/products/practical_webobjects
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [EMAIL PROTECTED]