Commons FileUpload
  1. Commons FileUpload
  2. FILEUPLOAD-19

File Upload Not Compatible With IE 5.2.3 MacOS X

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Duplicate
    • Affects Version/s: 1.0 Final
    • Fix Version/s: None
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: Other

      Description

      I've got a Struts 1.1 application with a file upload field that works on all the browsers that I can
      think of (IE5/6 PC, Mozilla, Safari, etc) except IE5 Macintosh. I get this exception whether or not a
      file has been selected to upload:

      [Thread-50] ERROR org.apache.struts.upload.CommonsMultipartRequestHandler - Failed to parse
      multipart request
      org.apache.commons.fileupload.FileUploadException: Processing of multipart/form-data request
      failed. Stream ended unexpectedly
      at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:429)
      at
      org.apache.struts.upload.CommonsMultipartRequestHandler.handleRequest(CommonsMultipartRe
      questHandler.java:233)
      at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:1209)
      at org.apache.struts.action.RequestProcessor.processPopulate(RequestProcessor.java:821)
      at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:254)
      at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
      at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
      at
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
      at org.etp.voter.web.client.LoginFilter.doFilter(LoginFilter.java:49)
      at
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:213)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
      at org.etp.voter.web.HibernateFilter.doFilter(HibernateFilter.java:84)
      at
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:213)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
      at org.etp.commons.web.UnicodeFormFilter.doFilter(UnicodeFormFilter.java:35)
      at
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:213)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
      at
      org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipel
      ine.java:643)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      at
      org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipel
      ine.java:643)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
      at
      org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipel
      ine.java:641)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
      at
      org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipel
      ine.java:643)
      at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
      at
      org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipel
      ine.java:641)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
      at
      org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipel
      ine.java:641)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
      at
      org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipel
      ine.java:643)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
      at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:261)
      at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:360)
      at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:604)
      at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:562)
      at org.apache.jk.common.SocketConnection.runIt(ChannelSocket.java:679)
      at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:530)
      at java.lang.Thread.run(Thread.java:554)

      1. ASF.LICENSE.NOT.GRANTED--IE5OSXsniff.tgz
        25 kB
        Jesse Costello-Good
      2. ASF.LICENSE.NOT.GRANTED--mac_upload_bug_diff.txt
        0.6 kB
        David Snyderman
      3. ASF.LICENSE.NOT.GRANTED--MultipartStream.java
        28 kB
        David Snyderman

        Activity

        Hide
        Martin Cooper added a comment -

        Does this happen every time, or only sometimes? Is there any way you could
        capture the request input stream (e.g. using a sniffer) so that we can see the
        data that's causing the problem? Unfortunately I don't have access to a MacOS X
        system to test with.

        Show
        Martin Cooper added a comment - Does this happen every time, or only sometimes? Is there any way you could capture the request input stream (e.g. using a sniffer) so that we can see the data that's causing the problem? Unfortunately I don't have access to a MacOS X system to test with.
        Hide
        Jesse Costello-Good added a comment -

        yes it happens each and every time I try to upload. I'll attach a file I created with Ethereal (libpcap
        format) ... I hope that is sufficient, I don't know much about sniffing. It shows the attempt to
        upload mapB021121093918.gif.

        Show
        Jesse Costello-Good added a comment - yes it happens each and every time I try to upload. I'll attach a file I created with Ethereal (libpcap format) ... I hope that is sufficient, I don't know much about sniffing. It shows the attempt to upload mapB021121093918.gif.
        Hide
        Jesse Costello-Good added a comment -

        Created an attachment (id=8855)
        package sniff from Ethereal

        Show
        Jesse Costello-Good added a comment - Created an attachment (id=8855) package sniff from Ethereal
        Hide
        David Snyderman added a comment -

        Created an attachment (id=9261)
        Diff of fix for Mac IE using file upload

        Show
        David Snyderman added a comment - Created an attachment (id=9261) Diff of fix for Mac IE using file upload
        Hide
        David Snyderman added a comment -

        Created an attachment (id=9262)
        Code with Mac IE fix in place

        Show
        David Snyderman added a comment - Created an attachment (id=9262) Code with Mac IE fix in place
        Hide
        David Snyderman added a comment -

        It looks to me as if the issue described is because IE on the Mac is sending a
        different file separator character than every other browser.

        I've attached code and diff; I've included logging statements just for
        illustrative purposes.

        But here's the diff:

        71a72,73
        > import org.apache.log4j.*;
        >
        135a138,139
        > static Category logger = Category.getInstance(
        MultipartStream.class.getName() );
        >
        164a169
        > protected static final byte[] MAC_IE_SEPARATOR =

        { 0x0A, 0x43 }

        ;
        391a397
        > logger.warn( "Bytes: " + Byte.toString( marker[0] ) + ", " + Byte.toString(
        marker[1] ) );
        393a400
        > logger.warn( "Stream terminator case..." );
        397a405,410
        > logger.warn( "Field separator case..." );
        > nextChunk = true;
        > }
        > else if (arrayequals(marker, MAC_IE_SEPARATOR, 2))
        > {
        > logger.warn( "Mac IE case..." );
        401a415
        > logger.warn( "Error..." );

        Here's the logger output (I'm assuming that Martin will want to remove the
        logger statements if he chooses to check this in):

        2003-11-17 11:53:17,214 WARN (MultipartStream.java:397) Bytes: 13, 10
        2003-11-17 11:53:17,216 WARN (MultipartStream.java:405) Field separator case...
        2003-11-17 11:54:30,040 WARN (MultipartStream.java:397) Bytes: 10, 67
        2003-11-17 11:54:30,042 WARN (MultipartStream.java:410) Mac IE case...
        2003-11-17 11:54:30,043 WARN (MultipartStream.java:397) Bytes: 10, 67
        2003-11-17 11:54:30,044 WARN (MultipartStream.java:410) Mac IE case...
        2003-11-17 11:54:30,046 WARN (MultipartStream.java:397) Bytes: 13, 10
        2003-11-17 11:54:30,047 WARN (MultipartStream.java:405) Field separator case...
        2003-11-17 11:54:30,049 WARN (MultipartStream.java:397) Bytes: 45, 45
        2003-11-17 11:54:30,050 WARN (MultipartStream.java:400) Stream terminator case...

        Show
        David Snyderman added a comment - It looks to me as if the issue described is because IE on the Mac is sending a different file separator character than every other browser. I've attached code and diff; I've included logging statements just for illustrative purposes. But here's the diff: 71a72,73 > import org.apache.log4j.*; > 135a138,139 > static Category logger = Category.getInstance( MultipartStream.class.getName() ); > 164a169 > protected static final byte[] MAC_IE_SEPARATOR = { 0x0A, 0x43 } ; 391a397 > logger.warn( "Bytes: " + Byte.toString( marker [0] ) + ", " + Byte.toString( marker [1] ) ); 393a400 > logger.warn( "Stream terminator case..." ); 397a405,410 > logger.warn( "Field separator case..." ); > nextChunk = true; > } > else if (arrayequals(marker, MAC_IE_SEPARATOR, 2)) > { > logger.warn( "Mac IE case..." ); 401a415 > logger.warn( "Error..." ); Here's the logger output (I'm assuming that Martin will want to remove the logger statements if he chooses to check this in): 2003-11-17 11:53:17,214 WARN (MultipartStream.java:397) Bytes: 13, 10 2003-11-17 11:53:17,216 WARN (MultipartStream.java:405) Field separator case... 2003-11-17 11:54:30,040 WARN (MultipartStream.java:397) Bytes: 10, 67 2003-11-17 11:54:30,042 WARN (MultipartStream.java:410) Mac IE case... 2003-11-17 11:54:30,043 WARN (MultipartStream.java:397) Bytes: 10, 67 2003-11-17 11:54:30,044 WARN (MultipartStream.java:410) Mac IE case... 2003-11-17 11:54:30,046 WARN (MultipartStream.java:397) Bytes: 13, 10 2003-11-17 11:54:30,047 WARN (MultipartStream.java:405) Field separator case... 2003-11-17 11:54:30,049 WARN (MultipartStream.java:397) Bytes: 45, 45 2003-11-17 11:54:30,050 WARN (MultipartStream.java:400) Stream terminator case...
        Hide
        Martin Cooper added a comment -
            • COM-1077 has been marked as a duplicate of this bug. ***
        Show
        Martin Cooper added a comment - COM-1077 has been marked as a duplicate of this bug. ***
        Hide
        Martin Cooper added a comment -

        OK, I've finally figured out what's going on here, and it's really bizarre. The
        problem is caused by a strange bug in IE 5.23 for Mac. It seems that, when
        writing the boundary (as a separator), the browser terminates the line with
        only an LF character, instead of the CR LF pair - but only sometimes! (When
        writing headers - either the HTTP headers or the part headers - it always
        correctly writes out CR LF.)

        In the Ethereal sniffer output attached to this bug report (thanks for that,
        Jesse), we can see that the boundaries are correct until a binary part is
        uploaded. The boundary following that is incorrect, and the one after that is
        incorrect as well, but after that, it seems to go back to correct boundaries.
        This is a really weird pattern, and I thought it might be a fluke, but it's
        repeated, in exactly the same manner, the next time a binary part is
        encountered. How someone managed to code that one up is beyond me!

        I'm very reluctant to change FileUpload to accommodate this, for a couple of
        reasons. Firstly, it's clearly a bug in Mac IE 5.23, so the fix should be in
        that code. Secondly, hacking FileUpload to work around this bug will complicate
        the code quite a bit, and probably cause a performance problem on all
        platforms.

        I'd like to hear from Mac users about (a) how prevalent IE 5.23 is on Macs, (b)
        how recent it is, and (c) whether or not the problem exists in earlier or later
        versions. Also, it would be good if someone could check that a bug report has
        been entered against Mac IE 5.23.

        Show
        Martin Cooper added a comment - OK, I've finally figured out what's going on here, and it's really bizarre. The problem is caused by a strange bug in IE 5.23 for Mac. It seems that, when writing the boundary (as a separator), the browser terminates the line with only an LF character, instead of the CR LF pair - but only sometimes! (When writing headers - either the HTTP headers or the part headers - it always correctly writes out CR LF.) In the Ethereal sniffer output attached to this bug report (thanks for that, Jesse), we can see that the boundaries are correct until a binary part is uploaded. The boundary following that is incorrect, and the one after that is incorrect as well, but after that, it seems to go back to correct boundaries. This is a really weird pattern, and I thought it might be a fluke, but it's repeated, in exactly the same manner, the next time a binary part is encountered. How someone managed to code that one up is beyond me! I'm very reluctant to change FileUpload to accommodate this, for a couple of reasons. Firstly, it's clearly a bug in Mac IE 5.23, so the fix should be in that code. Secondly, hacking FileUpload to work around this bug will complicate the code quite a bit, and probably cause a performance problem on all platforms. I'd like to hear from Mac users about (a) how prevalent IE 5.23 is on Macs, (b) how recent it is, and (c) whether or not the problem exists in earlier or later versions. Also, it would be good if someone could check that a bug report has been entered against Mac IE 5.23.
        Hide
        Adrian Sutton added a comment -

        For the record, Mac IE is very prevalent, and it's no longer being updated so
        filing a bug there won't do any good. There is no later version than 5.2.3.

        Show
        Adrian Sutton added a comment - For the record, Mac IE is very prevalent, and it's no longer being updated so filing a bug there won't do any good. There is no later version than 5.2.3.
        Hide
        Mark Lowe added a comment -

        I saw this thread and thought I'd give things a test, but as far as I can see I've a file upload working fine
        with MSIE 5.2. Why anybody would be silly enough to use it now there's safari, is another question.

        This app i'm testing with is using the stable struts 1.1 release of struts with TC5. The only problem I'm
        having is with IE mac caching in its own gun slinging way so in my admin form i can see the new image
        when i'm forwarded back to the view (despite a reload to the original action). But its stored in the
        database just fine.

        I'll try and break it but so far seems to be working fine, was the problem on a deployed apache to
        tomcat (jk and all that jazz) or just using built in http server?

        I've just tested on our staging server.

        Apache 2 + jk2 the same app, with msie 5.2 mac. And the same multipart form including an image
        upload worked just fine.

        Apache/2.0.49 (Unix) mod_jk2/2.0.5-dev

        In case it makes any difference both machines i've tested on are osx 10.3 , but i really doubt this is the
        issue.

        Just to make treble sure. I'll test when this app goes live with using jk1 again apache 2 on redhat linux,
        and also on the live version this particular form is served over https so thats another potential factor .
        And in case it makes any difference dev and stage configurations use tc 5.19 while the live deployment
        is new using 5.24.

        Show
        Mark Lowe added a comment - I saw this thread and thought I'd give things a test, but as far as I can see I've a file upload working fine with MSIE 5.2. Why anybody would be silly enough to use it now there's safari, is another question. This app i'm testing with is using the stable struts 1.1 release of struts with TC5. The only problem I'm having is with IE mac caching in its own gun slinging way so in my admin form i can see the new image when i'm forwarded back to the view (despite a reload to the original action). But its stored in the database just fine. I'll try and break it but so far seems to be working fine, was the problem on a deployed apache to tomcat (jk and all that jazz) or just using built in http server? I've just tested on our staging server. Apache 2 + jk2 the same app, with msie 5.2 mac. And the same multipart form including an image upload worked just fine. Apache/2.0.49 (Unix) mod_jk2/2.0.5-dev In case it makes any difference both machines i've tested on are osx 10.3 , but i really doubt this is the issue. Just to make treble sure. I'll test when this app goes live with using jk1 again apache 2 on redhat linux, and also on the live version this particular form is served over https so thats another potential factor . And in case it makes any difference dev and stage configurations use tc 5.19 while the live deployment is new using 5.24.
        Hide
        Matt Bathje added a comment -

        Mark - I have some customers that are getting this error as well, and think I
        found out why you can't duplicate it.

        If the form is submitted using an <html:submit> button, the upload works fine.
        If on the other hand you use an <html:image> button, the error occurs.

        Show
        Matt Bathje added a comment - Mark - I have some customers that are getting this error as well, and think I found out why you can't duplicate it. If the form is submitted using an <html:submit> button, the upload works fine. If on the other hand you use an <html:image> button, the error occurs.
        Hide
        Justin Sampson added a comment -

        We have seen the same problem and submitted a fix in COM-1415 (with junit test).

        Show
        Justin Sampson added a comment - We have seen the same problem and submitted a fix in COM-1415 (with junit test).
        Hide
        Martin Cooper added a comment -
            • This bug has been marked as a duplicate of 30061 ***
        Show
        Martin Cooper added a comment - This bug has been marked as a duplicate of 30061 ***

          People

          • Assignee:
            Unassigned
            Reporter:
            Jesse Costello-Good
          • Votes:
            2 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development