DWR

textHtmlHandler not being called when remoting via iframe (uploads)

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Normal Normal
  • Resolution: Fixed
  • Affects Version/s: 3.0.RC1
  • Fix Version/s: 3.0.RC3
  • Component/s: Engine
  • Documentation Required:
    Yes
  • Description:
    The textHtmlHandler is not being called when remoting via a method other than XMLHttpRequest. This can be demonstrated by attempting a file upload or otherwise modifying DWR's remoting method.

Issue Links

Activity

Hide
Mike Wilson added a comment - 07/May/11 5:39 AM

Let's investigate this a bit for 3.0.1 and see if we come up with something.

Show
Mike Wilson added a comment - 07/May/11 5:39 AM Let's investigate this a bit for 3.0.1 and see if we come up with something.
Hide
Alexander Nalbandyan added a comment - 04/Mar/13 7:06 AM

Hi Mike

Do you have any news regarding this bug?
We are currently using 3.0 RC2 and problem still exist.

Thanks in advance
Alexander

Show
Alexander Nalbandyan added a comment - 04/Mar/13 7:06 AM Hi Mike Do you have any news regarding this bug? We are currently using 3.0 RC2 and problem still exist. Thanks in advance Alexander
Hide
David Marginian added a comment - 04/Mar/13 8:02 AM

Alexander, this is a pretty incomplete write-up. Do you have more details? Are you using reverse AJAX?

Show
David Marginian added a comment - 04/Mar/13 8:02 AM Alexander, this is a pretty incomplete write-up. Do you have more details? Are you using reverse AJAX?
Hide
Alexander Nalbandyan added a comment - 04/Mar/13 8:46 AM

Hi David

Thanks for quick feed here is more presized information about it:

According to documentation specified in following page:
http://directwebremoting.org/dwr/documentation/browser/errors.html
"There is currently a limitation in setTextHtmlHandler where it will not be called as a result of fileUpload requests. Future versions of DWR should correct this issue." excerpt from documentation.

And currently I am using 3.0 RC2 and this feature is not yet supported.

Thanks
Alexander

Show
Alexander Nalbandyan added a comment - 04/Mar/13 8:46 AM Hi David Thanks for quick feed here is more presized information about it: According to documentation specified in following page: http://directwebremoting.org/dwr/documentation/browser/errors.html "There is currently a limitation in setTextHtmlHandler where it will not be called as a result of fileUpload requests. Future versions of DWR should correct this issue." excerpt from documentation. And currently I am using 3.0 RC2 and this feature is not yet supported. Thanks Alexander
Hide
David Marginian added a comment - 04/Mar/13 9:05 AM

Thanks Alexander. If you have a raw response handy that you can paste here that would be helpful to me.

Show
David Marginian added a comment - 04/Mar/13 9:05 AM Thanks Alexander. If you have a raw response handy that you can paste here that would be helpful to me.
Hide
Alexander Nalbandyan added a comment - 04/Mar/13 9:14 AM

This file contains file request flow captured by network sniffer.
First request contain file upload request.
Then goes redirection responses.

Show
Alexander Nalbandyan added a comment - 04/Mar/13 9:14 AM This file contains file request flow captured by network sniffer. First request contain file upload request. Then goes redirection responses.
Hide
Alexander Nalbandyan added a comment - 04/Mar/13 9:16 AM

I have attached raw requests information.
Also here is my dwr setup
if ( (typeof dwr !== "undefined") && dwr.engine) { dwr.engine.setTimeout(20000); dwr.engine.setErrorHandler(errorHandler); dwr.engine.setTextHtmlHandler(sessionExpiredHandler); }

Show
Alexander Nalbandyan added a comment - 04/Mar/13 9:16 AM I have attached raw requests information. Also here is my dwr setup if ( (typeof dwr !== "undefined") && dwr.engine) { dwr.engine.setTimeout(20000); dwr.engine.setErrorHandler(errorHandler); dwr.engine.setTextHtmlHandler(sessionExpiredHandler); }
Hide
David Marginian added a comment - 04/Mar/13 9:26 AM

Your server is sending back a 302 (redirect). I have recently added the capability to handle redirects per http://directwebremoting.org/jira/browse/DWR-421.

You will need RC3 to use this and you will need to look at the comments in the JIRA issue for information on how to set up your handler.

I am closing this issue as a by-produce of 421.

Show
David Marginian added a comment - 04/Mar/13 9:26 AM Your server is sending back a 302 (redirect). I have recently added the capability to handle redirects per http://directwebremoting.org/jira/browse/DWR-421. You will need RC3 to use this and you will need to look at the comments in the JIRA issue for information on how to set up your handler. I am closing this issue as a by-produce of 421.
Hide
David Marginian added a comment - 04/Mar/13 9:28 AM

The issue was that the textHtmlHandler was not capable of handling redirects. This has been fixed per DWR-421.

Show
David Marginian added a comment - 04/Mar/13 9:28 AM The issue was that the textHtmlHandler was not capable of handling redirects. This has been fixed per DWR-421.
Hide
Alexander Nalbandyan added a comment - 04/Mar/13 10:14 AM

David

I have tried following version http://ci.directwebremoting.org/bamboo/browse/DWRTRUNK-ALL-454/artifact

The problems still exists i.e. textHtmlHandler is not called.

Show
Alexander Nalbandyan added a comment - 04/Mar/13 10:14 AM David I have tried following version http://ci.directwebremoting.org/bamboo/browse/DWRTRUNK-ALL-454/artifact The problems still exists i.e. textHtmlHandler is not called.
Hide
David Marginian added a comment - 04/Mar/13 10:20 AM

You need to read the comments in that JIRA please: Per my comments in 421:

1) I created a new handler called textOrRedirectHandler that can handle both 300 level status codes and text/html responses.
2) I have left textHtmlHandler in place. It can be used with textOrRedirectHandler to handle text/html responses separately from 300 level status codes (not that this is likely to be required but it is not much additional code so why not?).

Show
David Marginian added a comment - 04/Mar/13 10:20 AM You need to read the comments in that JIRA please: Per my comments in 421: 1) I created a new handler called textOrRedirectHandler that can handle both 300 level status codes and text/html responses. 2) I have left textHtmlHandler in place. It can be used with textOrRedirectHandler to handle text/html responses separately from 300 level status codes (not that this is likely to be required but it is not much additional code so why not?).
Hide
Alexander Nalbandyan added a comment - 04/Mar/13 10:20 AM

Also I want to mention that the redirection flow of session-expired.htm is working for other pages where we don't use file upload i.e. textHtmlHander is called when session is expired.

So textHtmlHadler is not called only in case of file upload.

Please check it on file upload.

Show
Alexander Nalbandyan added a comment - 04/Mar/13 10:20 AM Also I want to mention that the redirection flow of session-expired.htm is working for other pages where we don't use file upload i.e. textHtmlHander is called when session is expired. So textHtmlHadler is not called only in case of file upload. Please check it on file upload.
Hide
David Marginian added a comment - 04/Mar/13 10:25 AM

Like I said earlier, textHtmlHandler was not designed to handle redirection, you can infer from the name that it was designed to handle a text/html response from the server. It would be misleading to have it handle 300 response codes which is why the new handler was created.

Show
David Marginian added a comment - 04/Mar/13 10:25 AM Like I said earlier, textHtmlHandler was not designed to handle redirection, you can infer from the name that it was designed to handle a text/html response from the server. It would be misleading to have it handle 300 response codes which is why the new handler was created.
Hide
Alexander Nalbandyan added a comment - 04/Mar/13 10:52 AM

I have tried what you have mentioned sorry I miss typed "textHtmlHandler" instead of "textOrRedirectHandler"
dwr.engine.setTextOrRedirectHandler(sessionExpiredHandler);

But unfortunately it is not working for file uploads "sessionExpiredHandler" function is not called.

Also want to mention that when changed to setTextOrRedirectHandler instead of setTextHtmlHandler "sessionExpiredHandler" is not called also in case of simple dwr calls which doesn't include file uploads.

Show
Alexander Nalbandyan added a comment - 04/Mar/13 10:52 AM I have tried what you have mentioned sorry I miss typed "textHtmlHandler" instead of "textOrRedirectHandler" dwr.engine.setTextOrRedirectHandler(sessionExpiredHandler); But unfortunately it is not working for file uploads "sessionExpiredHandler" function is not called. Also want to mention that when changed to setTextOrRedirectHandler instead of setTextHtmlHandler "sessionExpiredHandler" is not called also in case of simple dwr calls which doesn't include file uploads.
Hide
Alexander Nalbandyan added a comment - 04/Mar/13 10:57 AM

I guess that the original problem is related to the approach that iframe is used when uploading file asynchronously.

Show
Alexander Nalbandyan added a comment - 04/Mar/13 10:57 AM I guess that the original problem is related to the approach that iframe is used when uploading file asynchronously.
Hide
David Marginian added a comment - 04/Mar/13 11:19 AM

You are correct that the problem is related to IFrame remoting. This problem will exist for other remoting methods as well (ScriptTag, etc) so I modified the issue to be more descriptive.

Regarding setTextOrRedirectHandler not being called for simple DWR calls if you want to help out, can you place a breakpoint in engine.js - dwr.engine._handleTextHtmlResponse?

Show
David Marginian added a comment - 04/Mar/13 11:19 AM You are correct that the problem is related to IFrame remoting. This problem will exist for other remoting methods as well (ScriptTag, etc) so I modified the issue to be more descriptive. Regarding setTextOrRedirectHandler not being called for simple DWR calls if you want to help out, can you place a breakpoint in engine.js - dwr.engine._handleTextHtmlResponse?
Hide
Alexander Nalbandyan added a comment - 05/Mar/13 3:41 AM

Hi David

Sorry for late feedback.
I have placed breakpoint in dwr.engine._handleTextHtmlResponse and in dwr.engine._handleTextOrRedirectResponse. Neither of methods are stopped in case session expiry when using file upload. SO it confirms that these methods are not called in that case.

Show
Alexander Nalbandyan added a comment - 05/Mar/13 3:41 AM Hi David Sorry for late feedback. I have placed breakpoint in dwr.engine._handleTextHtmlResponse and in dwr.engine._handleTextOrRedirectResponse. Neither of methods are stopped in case session expiry when using file upload. SO it confirms that these methods are not called in that case.
Hide
David Marginian added a comment - 05/Mar/13 4:14 AM

I wanted you to do it for a simple DWR call to see why _handleTextOrRedirectResponse is not being called.

Show
David Marginian added a comment - 05/Mar/13 4:14 AM I wanted you to do it for a simple DWR call to see why _handleTextOrRedirectResponse is not being called.
Hide
Alexander Nalbandyan added a comment - 05/Mar/13 5:47 AM

Ok here is result of debugging

Actually the dwr.engine._handleTextOrRedirectResponse method is called and the reason why my text handler is not called is implementation of setTextOrRedirectHandler
"
dwr.engine.setTextOrRedirectHandler = function(handler) { dwr.engine_textOrRedirectHandler = handler; };
"
So it sets "engine_textOrRedirectHandler" instead of "engine._textOrRedirectHandler" which is checked in _handleTextOrRedirectResponse method by following lines
"
else if (dwr.engine._textOrRedirectHandler) dwr.engine._textOrRedirectHandler(textHtmlObj)
"
So setTextOrRedirectHandler implementation should be fixed to set "engine._textOrRedirectHandler" value instead.

Show
Alexander Nalbandyan added a comment - 05/Mar/13 5:47 AM Ok here is result of debugging Actually the dwr.engine._handleTextOrRedirectResponse method is called and the reason why my text handler is not called is implementation of setTextOrRedirectHandler " dwr.engine.setTextOrRedirectHandler = function(handler) { dwr.engine_textOrRedirectHandler = handler; }; " So it sets "engine_textOrRedirectHandler" instead of "engine._textOrRedirectHandler" which is checked in _handleTextOrRedirectResponse method by following lines " else if (dwr.engine._textOrRedirectHandler) dwr.engine._textOrRedirectHandler(textHtmlObj) " So setTextOrRedirectHandler implementation should be fixed to set "engine._textOrRedirectHandler" value instead.
Hide
David Marginian added a comment - 05/Mar/13 6:52 AM - edited

Thanks. I appreciate you looking into that for me. I have just checked in a fix. I am working on adding test cases for the html and redirect handlers. I will also start taking a look at this. My initial thoughts is that it is not a trivial fix.

Show
David Marginian added a comment - 05/Mar/13 6:52 AM - edited Thanks. I appreciate you looking into that for me. I have just checked in a fix. I am working on adding test cases for the html and redirect handlers. I will also start taking a look at this. My initial thoughts is that it is not a trivial fix.
Hide
Alexander Nalbandyan added a comment - 05/Mar/13 9:31 PM

You are welcome.
Looking forward to the news regarding original problem.

Show
Alexander Nalbandyan added a comment - 05/Mar/13 9:31 PM You are welcome. Looking forward to the news regarding original problem.
Hide
David Marginian added a comment - 09/Mar/13 2:24 PM - edited

I thought about this issue a bit more and I don't think it makes a whole lot of sense. When DWR is remoting normally (XHR) the textHtmlHandler is called when the response code from the server is 200 and the content-type is text/html. Generally this indicates that the server has sent some type of error page, login page, etc. When DWR is remoting via iframes the response from the server will always be text/html. So having a textHtmlHandler for iframe remoting does not make any sense as it doesn't indicate anything and would always be called.

A problem also exists for handling redirects (300 codes). I was thinking it would be possible for us to grab the response code and send it to the client. However this is also problematic. Java 5 doesn't expose the status on the HttpServletResponse, so in order to support this we would have to extend HttpServletResponse and write a servlet filter that would save the status. Doing this within DWR is problematic because it would require end users to set-up a filter in their web.xml.

It seems to me this situation can be handled easily in the callback. The callback should be called even when the response from the server is a 302. The data passed to the callback will be the response from the server which you can check and take action on. If you wanted to be fancy you could do this in a servlet filter (intercept certain responses, for example the login page, etc.) and send back a custom message, etc. to the client.

Show
David Marginian added a comment - 09/Mar/13 2:24 PM - edited I thought about this issue a bit more and I don't think it makes a whole lot of sense. When DWR is remoting normally (XHR) the textHtmlHandler is called when the response code from the server is 200 and the content-type is text/html. Generally this indicates that the server has sent some type of error page, login page, etc. When DWR is remoting via iframes the response from the server will always be text/html. So having a textHtmlHandler for iframe remoting does not make any sense as it doesn't indicate anything and would always be called. A problem also exists for handling redirects (300 codes). I was thinking it would be possible for us to grab the response code and send it to the client. However this is also problematic. Java 5 doesn't expose the status on the HttpServletResponse, so in order to support this we would have to extend HttpServletResponse and write a servlet filter that would save the status. Doing this within DWR is problematic because it would require end users to set-up a filter in their web.xml. It seems to me this situation can be handled easily in the callback. The callback should be called even when the response from the server is a 302. The data passed to the callback will be the response from the server which you can check and take action on. If you wanted to be fancy you could do this in a servlet filter (intercept certain responses, for example the login page, etc.) and send back a custom message, etc. to the client.
Hide
Alexander Nalbandyan added a comment - 09/Mar/13 11:22 PM

Hi David

Thanks for detailed explanations. Could you please answer to the following question.
Lets consider following situation.
We are using dwr to upload file to the server from client.
How we can handle session-expired cases when uploading files?

Show
Alexander Nalbandyan added a comment - 09/Mar/13 11:22 PM Hi David Thanks for detailed explanations. Could you please answer to the following question. Lets consider following situation. We are using dwr to upload file to the server from client. How we can handle session-expired cases when uploading files?
Hide
David Marginian added a comment - 10/Mar/13 6:55 AM - edited

Alexander, sorry I wasn't clear. DWR will call the callback with the response from the server. You can parse the response and determine if the server has sent back the login page/an error page, etc. Give this a try and let me know how it works for you.

Show
David Marginian added a comment - 10/Mar/13 6:55 AM - edited Alexander, sorry I wasn't clear. DWR will call the callback with the response from the server. You can parse the response and determine if the server has sent back the login page/an error page, etc. Give this a try and let me know how it works for you.
Hide
Alexander Nalbandyan added a comment - 11/Mar/13 4:21 AM

Thanks David

I have tried and html handler is called in case of session expiration for file upload.
Unfortunately I have another problem with dwr.util.getValue('element_id');
I have debugged and seems that the problem is in following method implementation. Variable elem2 value is not used and so elem variable doesn't get expected value. I get error message in browser console indicating that element was not found with provided id.
Please have a look.

dwr.util.byId = function() {
var elems = [];
for ( var i = 0; i < arguments.length; i++) {
var idOrElem = arguments[i];
var elem;
if (typeof idOrElem == 'string') {
var elem2 = document.getElementById(idOrElem);
// Workaround for IE and Opera that may return element based on name
if (document.all && elem2 && dwr.util._getId(elem2) != idOrElem) {
elem2 = null;
var maybeElems = document.all[idOrElem];
if (maybeElems.tagName)
maybeElems = [ maybeElems ];
for ( var j = 0; j < maybeElems.length; j++) {
if (dwr.util._getId(maybeElems[j]) == idOrElem) { elem = maybeElems[j]; break; }
}
}
} else { elem = idOrElem; }
if (arguments.length == 1) { return elem; }
elems.push(elem);
}
return elems;
};

Show
Alexander Nalbandyan added a comment - 11/Mar/13 4:21 AM Thanks David I have tried and html handler is called in case of session expiration for file upload. Unfortunately I have another problem with dwr.util.getValue('element_id'); I have debugged and seems that the problem is in following method implementation. Variable elem2 value is not used and so elem variable doesn't get expected value. I get error message in browser console indicating that element was not found with provided id. Please have a look. dwr.util.byId = function() { var elems = []; for ( var i = 0; i < arguments.length; i++) { var idOrElem = arguments[i]; var elem; if (typeof idOrElem == 'string') { var elem2 = document.getElementById(idOrElem); // Workaround for IE and Opera that may return element based on name if (document.all && elem2 && dwr.util._getId(elem2) != idOrElem) { elem2 = null; var maybeElems = document.all[idOrElem]; if (maybeElems.tagName) maybeElems = [ maybeElems ]; for ( var j = 0; j < maybeElems.length; j++) { if (dwr.util._getId(maybeElems[j]) == idOrElem) { elem = maybeElems[j]; break; } } } } else { elem = idOrElem; } if (arguments.length == 1) { return elem; } elems.push(elem); } return elems; };
Hide
David Marginian added a comment - 11/Mar/13 4:45 AM

Alexander, I said callback not html handler. Please re-read what I wrote.

For the second issue you must have just downloaded a recent development build (that change was checked in on Saturday, I am working on hooking up DWR to JSHint validation, I will revert that change.

Show
David Marginian added a comment - 11/Mar/13 4:45 AM Alexander, I said callback not html handler. Please re-read what I wrote. For the second issue you must have just downloaded a recent development build (that change was checked in on Saturday, I am working on hooking up DWR to JSHint validation, I will revert that change.
Hide
Alexander Nalbandyan added a comment - 11/Mar/13 4:54 AM

David I have noticed that you mention callback not htmlHandler but as I could not find method dwr.engine.setCallback method I thought that you mean dwr.engine.setTextOrRedirectHandler.
Please provide me information about how to configure callback or where I can find information about this may be I am missing something.

Show
Alexander Nalbandyan added a comment - 11/Mar/13 4:54 AM David I have noticed that you mention callback not htmlHandler but as I could not find method dwr.engine.setCallback method I thought that you mean dwr.engine.setTextOrRedirectHandler. Please provide me information about how to configure callback or where I can find information about this may be I am missing something.
Hide
David Marginian added a comment - 11/Mar/13 5:02 AM

A callback is specific to a call and is normally specified as the last argument:
YourFileUploadDWRClass.yourFileUploadDWRMethod(param1, param2, etc., callbackFunction);

function callbackFunction(serverResponse) { // Process response here. }

Show
David Marginian added a comment - 11/Mar/13 5:02 AM A callback is specific to a call and is normally specified as the last argument: YourFileUploadDWRClass.yourFileUploadDWRMethod(param1, param2, etc., callbackFunction); function callbackFunction(serverResponse) { // Process response here. }
Hide
Alexander Nalbandyan added a comment - 11/Mar/13 5:27 AM

Ok understood I was expecting something new .
I have tried but callback is not called in case of session expiry.
Here is excerpt from implementation.
var asynchResult = {
callback:function (imageId) { //callback here },
errorHandler: function (errorString, exception) { //error handling here },
exceptionHandler:function (errorString, exception) { //exception handling here },
timeout: 120000
};

PetService.savePetPhoto(petImageInput, petId, asynchResult);

Show
Alexander Nalbandyan added a comment - 11/Mar/13 5:27 AM Ok understood I was expecting something new . I have tried but callback is not called in case of session expiry. Here is excerpt from implementation. var asynchResult = { callback:function (imageId) { //callback here }, errorHandler: function (errorString, exception) { //error handling here }, exceptionHandler:function (errorString, exception) { //exception handling here }, timeout: 120000 }; PetService.savePetPhoto(petImageInput, petId, asynchResult);
Hide
David Marginian added a comment - 11/Mar/13 5:44 AM

Is the error handler called? Or any other handler?

Show
David Marginian added a comment - 11/Mar/13 5:44 AM Is the error handler called? Or any other handler?
Hide
Alexander Nalbandyan added a comment - 11/Mar/13 6:05 AM

No unfortunately none of them.

Show
Alexander Nalbandyan added a comment - 11/Mar/13 6:05 AM No unfortunately none of them.
Hide
David Marginian added a comment - 11/Mar/13 7:06 AM

Ok, I will look into it. My testing was done with a simple redirect as it is an easy scenario to test. In the meantime if you want to help out, here are some questions I have:

1) Are there any JS errors in your browsers JS console?
2) In engine.js do either of the following functions get called, beginIFrameResponse, endIFrameResponse (just place breakpoints there).

Show
David Marginian added a comment - 11/Mar/13 7:06 AM Ok, I will look into it. My testing was done with a simple redirect as it is an easy scenario to test. In the meantime if you want to help out, here are some questions I have: 1) Are there any JS errors in your browsers JS console? 2) In engine.js do either of the following functions get called, beginIFrameResponse, endIFrameResponse (just place breakpoints there).
Hide
David Marginian added a comment - 11/Mar/13 6:56 PM

Alexander, forget answering my questions in the previous post. I set-up a test environment and I was able to reproduce the issue. I will be looking into it.

Show
David Marginian added a comment - 11/Mar/13 6:56 PM Alexander, forget answering my questions in the previous post. I set-up a test environment and I was able to reproduce the issue. I will be looking into it.
Hide
Mike Wilson added a comment - 12/Mar/13 6:26 AM

Hey guys, there seems to be a lot of different discussions going on in this ticket
Maybe the talk about redirect handlers and file upload progress could be moved to the mailing list or another ticket?

My comments on the original issue:
Yes, this is a non-trivial thing to fix as only XMLHttpRequest will give us the HTTP status, as David already said. Adding a filter used across all remoting channels, and changing DWR's remoting protocol to carry the status, could solve it but there would still be scenarios where we would compete for being the "first" filter and could be preceeded by security filters.
I think the correct solution is to provide another kind of error handler that, rather than reporting about a text/html response, reports about lost connection with the server session. Then the way of detecting this can be performed in a more flexible way.

In the meantime, if your application wants to detect session expiry AND use other remoting channels than XMLHttpRequest, I think you should implement the session check yourself in your application code, possibly with help from a DWR XMLHttpRequest based call.

Show
Mike Wilson added a comment - 12/Mar/13 6:26 AM Hey guys, there seems to be a lot of different discussions going on in this ticket Maybe the talk about redirect handlers and file upload progress could be moved to the mailing list or another ticket? My comments on the original issue: Yes, this is a non-trivial thing to fix as only XMLHttpRequest will give us the HTTP status, as David already said. Adding a filter used across all remoting channels, and changing DWR's remoting protocol to carry the status, could solve it but there would still be scenarios where we would compete for being the "first" filter and could be preceeded by security filters. I think the correct solution is to provide another kind of error handler that, rather than reporting about a text/html response, reports about lost connection with the server session. Then the way of detecting this can be performed in a more flexible way. In the meantime, if your application wants to detect session expiry AND use other remoting channels than XMLHttpRequest, I think you should implement the session check yourself in your application code, possibly with help from a DWR XMLHttpRequest based call.
Hide
David Marginian added a comment - 12/Mar/13 7:03 AM

Mike, there may be an alternative. Currently we rely on the server calling the callback. Obviously in cases of session expiration, the DWR code isn't getting a chance to execute. What if we add an onload/readystatechange listener to the iframe and call the callback when the iframe's data has loaded? I am thinking this would work and would result in us always calling the callback when a response is received. Thoughts?

Alexander, you should be able to do what I mention above in your code. After the upload request you can at an interval check the content of the iframe that dwr created during the upload and when there is content you can parse it and take the appropriate action.

Show
David Marginian added a comment - 12/Mar/13 7:03 AM Mike, there may be an alternative. Currently we rely on the server calling the callback. Obviously in cases of session expiration, the DWR code isn't getting a chance to execute. What if we add an onload/readystatechange listener to the iframe and call the callback when the iframe's data has loaded? I am thinking this would work and would result in us always calling the callback when a response is received. Thoughts? Alexander, you should be able to do what I mention above in your code. After the upload request you can at an interval check the content of the iframe that dwr created during the upload and when there is content you can parse it and take the appropriate action.
Hide
Mike Wilson added a comment - 12/Mar/13 7:51 AM

Yes, that alternative is more in the spirit of my second suggestion - solve the use case with a different error handler. FWIW, I think that if we can't solve textHtmlHandler for all transports then we should deprecate and eventually remove it.

Looking at the iframe.onload altenative it's actually an omission that we aren't already doing this. I added exactly this functionality to the script tag transport a while back (see event handlers for load, error, and readystatechange) so iframe should be analogous.
Once this is sorted out, responses would fail with an "Incomplete reply from server" error, which should be detected instead of using textHtmlHandler.

Show
Mike Wilson added a comment - 12/Mar/13 7:51 AM Yes, that alternative is more in the spirit of my second suggestion - solve the use case with a different error handler. FWIW, I think that if we can't solve textHtmlHandler for all transports then we should deprecate and eventually remove it. Looking at the iframe.onload altenative it's actually an omission that we aren't already doing this. I added exactly this functionality to the script tag transport a while back (see event handlers for load, error, and readystatechange) so iframe should be analogous. Once this is sorted out, responses would fail with an "Incomplete reply from server" error, which should be detected instead of using textHtmlHandler.
Hide
David Marginian added a comment - 12/Mar/13 7:56 AM

Ok, I will take a look at this. I do believe the textHtmlHandler still has a place. However, it should never be called for IFrame remoting since the response will always be text/html.

Show
David Marginian added a comment - 12/Mar/13 7:56 AM Ok, I will take a look at this. I do believe the textHtmlHandler still has a place. However, it should never be called for IFrame remoting since the response will always be text/html.
Hide
Alexander Nalbandyan added a comment - 12/Mar/13 9:19 AM

Hi Guys

I have some notes about last conversations.

At first regarding following comment by Mike:
"In the meantime, if your application wants to detect session expiry AND use other remoting channels than XMLHttpRequest, I think you should implement the session check yourself in your application code, possibly with help from a DWR XMLHttpRequest based call."

Mike if by "your application" you mean application which uses dwr then (XMLHttpRequest and Iframe) are actually implementation details of DWR and client application just uses API and have to know about actual implementation details.

Second note is about comment by David:
"Alexander, you should be able to do what I mention above in your code. After the upload request you can at an interval check the content of the iframe that dwr created during the upload and when there is content you can parse it and take the appropriate action."

Session expiry is just one case of error which can happen when calling dwr service and according to documentation to handle this error you need to register textHtmlHander and again I want to mention that iframe is just specific implementation for file upload because XMLHttpRequest v1 doesn't support file upload.
So there should be some general interface to handle error cases specifically session expiry(not exposing implementation details).

Please correct me if I am wrong.

Show
Alexander Nalbandyan added a comment - 12/Mar/13 9:19 AM Hi Guys I have some notes about last conversations. At first regarding following comment by Mike: "In the meantime, if your application wants to detect session expiry AND use other remoting channels than XMLHttpRequest, I think you should implement the session check yourself in your application code, possibly with help from a DWR XMLHttpRequest based call." Mike if by "your application" you mean application which uses dwr then (XMLHttpRequest and Iframe) are actually implementation details of DWR and client application just uses API and have to know about actual implementation details. Second note is about comment by David: "Alexander, you should be able to do what I mention above in your code. After the upload request you can at an interval check the content of the iframe that dwr created during the upload and when there is content you can parse it and take the appropriate action." Session expiry is just one case of error which can happen when calling dwr service and according to documentation to handle this error you need to register textHtmlHander and again I want to mention that iframe is just specific implementation for file upload because XMLHttpRequest v1 doesn't support file upload. So there should be some general interface to handle error cases specifically session expiry(not exposing implementation details). Please correct me if I am wrong.
Hide
David Marginian added a comment - 12/Mar/13 9:41 AM - edited

The docs need to be updated. textHtmlHandler does not and never will apply to iframe remoting.

As far as adding some general session expiry handler if you think about it it should become clear to you why this is not possible within a framework like DWR. When the session expires DWR's code on the server does not even have a chance to execute and the server generally sends back the login page, some other HTML page, etc. We have no generic way of determining that the session has expired as it is specific to the page sent back, etc. textHtmlHandler is a best attempt at allowing users to handle this situation and is called when a 200 text/html response is sent back to the client. This could indicate other things, but generally it indicates session expiration. Of course the user can determine this via the parameters passed to to textHtmlHandler.

For iframe remoting this is even more challenging because the response is always text/html. Since the response code is not available (as previously explained) to us we cannot even catch redirects, etc. So the question is what is the best way to handle this? There is a flaw in the current iframe logic in DWR in that when the session expires the call just hangs. We can resolve this by adding a load/readystatechange handler to the iframe so that we know at a minimum when the response has loaded into the iframe. Then we can either call the callback with that response or throw some other type of error per Mike's request. I am thinking whatever we do we need to expose the content of the iframe to the user so they can take appropriate action based on the specifics of that response (redirect to login page, etc.).

Show
David Marginian added a comment - 12/Mar/13 9:41 AM - edited The docs need to be updated. textHtmlHandler does not and never will apply to iframe remoting. As far as adding some general session expiry handler if you think about it it should become clear to you why this is not possible within a framework like DWR. When the session expires DWR's code on the server does not even have a chance to execute and the server generally sends back the login page, some other HTML page, etc. We have no generic way of determining that the session has expired as it is specific to the page sent back, etc. textHtmlHandler is a best attempt at allowing users to handle this situation and is called when a 200 text/html response is sent back to the client. This could indicate other things, but generally it indicates session expiration. Of course the user can determine this via the parameters passed to to textHtmlHandler. For iframe remoting this is even more challenging because the response is always text/html. Since the response code is not available (as previously explained) to us we cannot even catch redirects, etc. So the question is what is the best way to handle this? There is a flaw in the current iframe logic in DWR in that when the session expires the call just hangs. We can resolve this by adding a load/readystatechange handler to the iframe so that we know at a minimum when the response has loaded into the iframe. Then we can either call the callback with that response or throw some other type of error per Mike's request. I am thinking whatever we do we need to expose the content of the iframe to the user so they can take appropriate action based on the specifics of that response (redirect to login page, etc.).
Hide
Alexander Nalbandyan added a comment - 12/Mar/13 11:57 AM

David
Thanks for great explanation. I understand the points you have mentioned.

I actually expect some dataFilter which can be registered and could receive any response which is returned from the server and which provides client application to check whether it was session expiry error or not.

And this dataFilter could be registered for any type of call.

Also if I understand right http redirects are handled by iframe automatically so that finally iframe gets 200 OK response with corresponding response body.

Thanks
Alexander.

Show
Alexander Nalbandyan added a comment - 12/Mar/13 11:57 AM David Thanks for great explanation. I understand the points you have mentioned. I actually expect some dataFilter which can be registered and could receive any response which is returned from the server and which provides client application to check whether it was session expiry error or not. And this dataFilter could be registered for any type of call. Also if I understand right http redirects are handled by iframe automatically so that finally iframe gets 200 OK response with corresponding response body. Thanks Alexander.
Hide
David Marginian added a comment - 12/Mar/13 12:07 PM

I am not sure we need anything additional. The problem now is that we are doing nothing, when we should be responding in some way. I think calling the callback with the response would be acceptable for iframe remoting.

Well, a redirect is a 30x code. If you look at firebug you will see the 30x. But then the response (html page being redirected to) will get loaded into the iframe.

Show
David Marginian added a comment - 12/Mar/13 12:07 PM I am not sure we need anything additional. The problem now is that we are doing nothing, when we should be responding in some way. I think calling the callback with the response would be acceptable for iframe remoting. Well, a redirect is a 30x code. If you look at firebug you will see the 30x. But then the response (html page being redirected to) will get loaded into the iframe.
Hide
Mike Wilson added a comment - 12/Mar/13 1:21 PM

Alexander,
My "in the meantime" solution was about how to workaround the problem right now, it was not intended as the correct or permanent solution. Once we implement the iframe.onload check, you will get notified about a communication failure independent of transport (xhr, iframe etc). textHtmlHandler will never work for all transports.

Show
Mike Wilson added a comment - 12/Mar/13 1:21 PM Alexander, My "in the meantime" solution was about how to workaround the problem right now, it was not intended as the correct or permanent solution. Once we implement the iframe.onload check, you will get notified about a communication failure independent of transport (xhr, iframe etc). textHtmlHandler will never work for all transports.
Hide
David Marginian added a comment - 12/Mar/13 6:58 PM

Alexander,

I have checked in a fix for this. With the fix the errorHandler will be called when the session has expired and an upload is attempted. The third parameter of the error handler will be the batch.

errorHandler : function(message, ex, batch) { ... }

You can use the batch to check the content of the iframe and determine the appropriate action to take. For example - batch.iframe.contentDocument.URL. Please let me know how this works for you.

Mike needs to review the change so it is possible the way this works will change in the coming days.

The latest build with this change can be found on our bamboo server:
http://ci.directwebremoting.org/bamboo/browse/DWRTRUNK-ALL-476/artifact

Show
David Marginian added a comment - 12/Mar/13 6:58 PM Alexander, I have checked in a fix for this. With the fix the errorHandler will be called when the session has expired and an upload is attempted. The third parameter of the error handler will be the batch. errorHandler : function(message, ex, batch) { ... } You can use the batch to check the content of the iframe and determine the appropriate action to take. For example - batch.iframe.contentDocument.URL. Please let me know how this works for you. Mike needs to review the change so it is possible the way this works will change in the coming days. The latest build with this change can be found on our bamboo server: http://ci.directwebremoting.org/bamboo/browse/DWRTRUNK-ALL-476/artifact
Hide
Alexander Nalbandyan added a comment - 13/Mar/13 9:17 AM

Hi David

Thanks for provided fix I will try it and let you know about the result as soon as I have time.
Regarding (batch.iframe.contentDocument.URL) I would say that it will be great to have errorHandler called in both cases for simple and Iframe requests and 3rd parameter not specific to iframe may be it can be "contentDocument" instead, just something which is common for iframe and simple asynchrone requests.

Thanks
Alexander

Show
Alexander Nalbandyan added a comment - 13/Mar/13 9:17 AM Hi David Thanks for provided fix I will try it and let you know about the result as soon as I have time. Regarding (batch.iframe.contentDocument.URL) I would say that it will be great to have errorHandler called in both cases for simple and Iframe requests and 3rd parameter not specific to iframe may be it can be "contentDocument" instead, just something which is common for iframe and simple asynchrone requests. Thanks Alexander
Hide
David Marginian added a comment - 13/Mar/13 9:21 AM

I am not sure what you are asking. The error handler is called in both iframe and simple cases and the batch which is common to both is passed to the error handler in both cases. I can't pass something more specific (contentDocument, etc.) than that because it will not be common across remoting types.

Show
David Marginian added a comment - 13/Mar/13 9:21 AM I am not sure what you are asking. The error handler is called in both iframe and simple cases and the batch which is common to both is passed to the error handler in both cases. I can't pass something more specific (contentDocument, etc.) than that because it will not be common across remoting types.
Hide
Alexander Nalbandyan added a comment - 18/Mar/13 8:15 AM

Hi David

At first I want to mention that I have tried the version you have suggested to try and it works exactly the way you have mentioned in comment:
http://bugs.directwebremoting.org/jira/browse/DWR-508?focusedCommentId=12193&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_12193

Now I want to go back to my comment:
I will to explain what I understand regarding session expiry error handling so far.

1) In case of iframe file upload to handle session expiry I need to register error handler which will receive batch as parameter by which I can check whether it was session expiry or not.

2) In case of simple DWR calls I need to register TEXTHandler which will be called on session expiry. (I have checked that error handler is not called in this case)

3) other cases unknown ....

So my question is.
Could we have general error handling mechanism for session expiry to not have to handle different cases separately.

Thanks in advance
Alexander.

Show
Alexander Nalbandyan added a comment - 18/Mar/13 8:15 AM Hi David At first I want to mention that I have tried the version you have suggested to try and it works exactly the way you have mentioned in comment: http://bugs.directwebremoting.org/jira/browse/DWR-508?focusedCommentId=12193&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_12193 Now I want to go back to my comment: I will to explain what I understand regarding session expiry error handling so far. 1) In case of iframe file upload to handle session expiry I need to register error handler which will receive batch as parameter by which I can check whether it was session expiry or not. 2) In case of simple DWR calls I need to register TEXTHandler which will be called on session expiry. (I have checked that error handler is not called in this case) 3) other cases unknown .... So my question is. Could we have general error handling mechanism for session expiry to not have to handle different cases separately. Thanks in advance Alexander.
Hide
David Marginian added a comment - 18/Mar/13 8:28 AM

I don't see how we can do this, which I think I have explained thoroughly in my previous comments. In order to be able to do this we have to know or be able to make an educated guess as to when a session expiration has occurred. In the case of iframe remoting we can't do this. Because:

1) The response from the server will ALWAYS be text/html.
2) Whether or not there is a session expiration depends entirely on the specifics of the html response which will be different in each environment.
3) We do not have access to the response codes so we can't even do something with redirects (300).

This differs from XHR remoting when:

1) The response is only going to be text/html when something weird like session expiration occurs.
2) The status codes are available so we can do specific things with redirects (300).

Show
David Marginian added a comment - 18/Mar/13 8:28 AM I don't see how we can do this, which I think I have explained thoroughly in my previous comments. In order to be able to do this we have to know or be able to make an educated guess as to when a session expiration has occurred. In the case of iframe remoting we can't do this. Because: 1) The response from the server will ALWAYS be text/html. 2) Whether or not there is a session expiration depends entirely on the specifics of the html response which will be different in each environment. 3) We do not have access to the response codes so we can't even do something with redirects (300). This differs from XHR remoting when: 1) The response is only going to be text/html when something weird like session expiration occurs. 2) The status codes are available so we can do specific things with redirects (300).
Hide
Alexander Nalbandyan added a comment - 18/Mar/13 8:35 AM

I think there is misunderstanding again.
What you have mentioned I have understood. And what I am asking for is handler where I can receive html response and decide by content whether it was session expiry or not I don't want dwr to check whether it was session expiry or not I just want to have those three cases mentioned in my last comment merged into one and to have handler like following which will be called in all cases.

errorHandler(....., responseDocument, ....) { //check Code here }

Show
Alexander Nalbandyan added a comment - 18/Mar/13 8:35 AM I think there is misunderstanding again. What you have mentioned I have understood. And what I am asking for is handler where I can receive html response and decide by content whether it was session expiry or not I don't want dwr to check whether it was session expiry or not I just want to have those three cases mentioned in my last comment merged into one and to have handler like following which will be called in all cases. errorHandler(....., responseDocument, ....) { //check Code here }
Hide
David Marginian added a comment - 18/Mar/13 9:29 AM - edited

Alexander, I will take another look at this. I actually think there may be a way around the fact that the response is always text/html.

Mike, my thinking is that in the load handler we can actually look at the iframes content and call the textHtmlHandler if a DWR signature is not present, e.g.:

r.beginIFrameResponse

or
//#DWR-INSERT

or
//#DWR-REPLY

The problem with this approach is that there may be legitimate error conditions in which we will be calling the textHtmlHandler.

Show
David Marginian added a comment - 18/Mar/13 9:29 AM - edited Alexander, I will take another look at this. I actually think there may be a way around the fact that the response is always text/html. Mike, my thinking is that in the load handler we can actually look at the iframes content and call the textHtmlHandler if a DWR signature is not present, e.g.: r.beginIFrameResponse or //#DWR-INSERT or //#DWR-REPLY The problem with this approach is that there may be legitimate error conditions in which we will be calling the textHtmlHandler.
Hide
Mike Wilson added a comment - 23/Mar/13 6:34 AM

Yes, that might be neat, although it doesn't handle the script tag transport.
Will you go ahead and look at this and at the other solution we discussed by email, and see which makes the best fit?

The problem with this approach is that there may be legitimate error conditions in which we will be calling the textHtmlHandler.

Are you thinking about f ex http status pages like 404, 500 etc?
I think it must always be up to user code to check the returned html and decide if it's a login page or something else.

Show
Mike Wilson added a comment - 23/Mar/13 6:34 AM Yes, that might be neat, although it doesn't handle the script tag transport. Will you go ahead and look at this and at the other solution we discussed by email, and see which makes the best fit?
The problem with this approach is that there may be legitimate error conditions in which we will be calling the textHtmlHandler.
Are you thinking about f ex http status pages like 404, 500 etc? I think it must always be up to user code to check the returned html and decide if it's a login page or something else.
Hide
David Marginian added a comment - 23/Mar/13 10:53 AM - edited

I looked at this condition when remoting via script-tag. I don't think there is anyway to get at the html response which means we will never be able to have a textHtmlHandler when script-tag remoting is being used. I think the current code is handling this in the best way we possibly can - simply calling the error handler with dwr.engine.incompleteReply. Even if we were to use the error approach you recommended in our email thread we would still not be able to handle script-tags consistently because we wouldn't be able to set the html on the error.

However, I do think that we can handle iframe and xhr consistently per my previous comment - calling the textHtmlHandler for both but for the IFrame only calling it if there is not DWR specific mark-up in the response. I think this is the way to go.

"Are you thinking about f ex http status pages like 404, 500 etc?
I think it must always be up to user code to check the returned html and decide if it's a login page or something else."

That can be handled by the users textHtmlHandler. Is there something else I haven't thought of that would make calling the textHtmlHandler inappropriate?

Show
David Marginian added a comment - 23/Mar/13 10:53 AM - edited I looked at this condition when remoting via script-tag. I don't think there is anyway to get at the html response which means we will never be able to have a textHtmlHandler when script-tag remoting is being used. I think the current code is handling this in the best way we possibly can - simply calling the error handler with dwr.engine.incompleteReply. Even if we were to use the error approach you recommended in our email thread we would still not be able to handle script-tags consistently because we wouldn't be able to set the html on the error. However, I do think that we can handle iframe and xhr consistently per my previous comment - calling the textHtmlHandler for both but for the IFrame only calling it if there is not DWR specific mark-up in the response. I think this is the way to go. "Are you thinking about f ex http status pages like 404, 500 etc? I think it must always be up to user code to check the returned html and decide if it's a login page or something else." That can be handled by the users textHtmlHandler. Is there something else I haven't thought of that would make calling the textHtmlHandler inappropriate?
Hide
Mike Wilson added a comment - 24/Mar/13 1:09 PM

I prefer user code to be able to be independent of remoting transport (xhr/iframe/script), so I guess I disagree to some extent .
The problem as I see it is that user code will have to use the textHtmlHandler to detect "login page style" failures when the XHR and iframe transports are used. If the page is switched to use the script tag transport, user code will instead have to use the errorHandler and look for the incompleteReply error. The errorHandler is not triggered above for XHR or iframe transports so it can't be used as a catch all solution (it is worth noting that this is the current behaviour of DWR, but IMO it's not right).

I want user code to be able to look the same for all transports. Either we find a way to always trigger the textHtmlHandler or we allow code to always be notified through the errorHandler.
A good compromise might be the following:

  1. Implement your solution as suggested.
  2. Make sure the global textHtmlHandler keeps a "null" default.
  3. Change validate() so it issues an "emptyReply" error when there are no replies at all
  4. When there is no textHtmlHandler defined let _handleTextHtmlResponse forward to handleError with "emptyReply".

This way user code that wants the xhr/iframe specific behaviour can use textHtmlHandler just like before, but user code that wants a single code path independent of transport can keep textHtmlHandler undefined and instead check for error="emptyReply".

Show
Mike Wilson added a comment - 24/Mar/13 1:09 PM I prefer user code to be able to be independent of remoting transport (xhr/iframe/script), so I guess I disagree to some extent . The problem as I see it is that user code will have to use the textHtmlHandler to detect "login page style" failures when the XHR and iframe transports are used. If the page is switched to use the script tag transport, user code will instead have to use the errorHandler and look for the incompleteReply error. The errorHandler is not triggered above for XHR or iframe transports so it can't be used as a catch all solution (it is worth noting that this is the current behaviour of DWR, but IMO it's not right). I want user code to be able to look the same for all transports. Either we find a way to always trigger the textHtmlHandler or we allow code to always be notified through the errorHandler. A good compromise might be the following:
  1. Implement your solution as suggested.
  2. Make sure the global textHtmlHandler keeps a "null" default.
  3. Change validate() so it issues an "emptyReply" error when there are no replies at all
  4. When there is no textHtmlHandler defined let _handleTextHtmlResponse forward to handleError with "emptyReply".
This way user code that wants the xhr/iframe specific behaviour can use textHtmlHandler just like before, but user code that wants a single code path independent of transport can keep textHtmlHandler undefined and instead check for error="emptyReply".
Hide
David Marginian added a comment - 25/Mar/13 7:13 AM

Ok, Mike. You convinced me. I have made some changes that will essentially deprecate the textHtml and redirect handler. The validate now calls a function that populates the responseText, etc. if available (pulled off of the batch's iframe, or request for XHR remoting). Then the error handler is called with the responseText, etc. If a textHtml or redirect handler exists and the error has a responseText it will be called, otherwise the error handler executes with the emptyReply error. I will be checking these changes in sometime in the next few days.

Show
David Marginian added a comment - 25/Mar/13 7:13 AM Ok, Mike. You convinced me. I have made some changes that will essentially deprecate the textHtml and redirect handler. The validate now calls a function that populates the responseText, etc. if available (pulled off of the batch's iframe, or request for XHR remoting). Then the error handler is called with the responseText, etc. If a textHtml or redirect handler exists and the error has a responseText it will be called, otherwise the error handler executes with the emptyReply error. I will be checking these changes in sometime in the next few days.
Hide
David Marginian added a comment - 25/Mar/13 4:26 PM - edited

I have checked in the change for this. The textHtml and redirect handlers are now deprecated, however they will continue to function with the added bonus of also working on iframe responses.

The favored way of handling session expiration, etc. will be in the errorHandler. When the exception name is "dwr.engine.emptyReply", DWR has not received any replies from the server. If available (XHR and iframe remoting) we will also set a htmlResponseText property on the error detail object with the html response.

Show
David Marginian added a comment - 25/Mar/13 4:26 PM - edited I have checked in the change for this. The textHtml and redirect handlers are now deprecated, however they will continue to function with the added bonus of also working on iframe responses. The favored way of handling session expiration, etc. will be in the errorHandler. When the exception name is "dwr.engine.emptyReply", DWR has not received any replies from the server. If available (XHR and iframe remoting) we will also set a htmlResponseText property on the error detail object with the html response.
Hide
David Marginian added a comment - 20/Apr/13 6:13 AM

The comments on this issue were getting out of control so I removed them so people looking at this issue in the future will not be confused.

Show
David Marginian added a comment - 20/Apr/13 6:13 AM The comments on this issue were getting out of control so I removed them so people looking at this issue in the future will not be confused.

People

Dates

  • Created:
    06/May/11 4:13 AM
    Updated:
    Monday 8:12 PM
    Resolved:
    Monday 8:12 PM