• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Large File Uploads [was Re: Large volume file upload design question ]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Large File Uploads [was Re: Large volume file upload design question ]


  • Subject: Re: Large File Uploads [was Re: Large volume file upload design question ]
  • From: Jonathan Rochkind <email@hidden>
  • Date: Mon, 21 Jul 2003 12:33:37 -0500

At 05:53 PM 7/21/2003 +0100, Jonathan Fleming wrote:
Calling All Guru's

How can I... or can I even, link a long upload in with a LongRequestPage (I've never used this feature, so ecuse me if it does not do what I am thinking).

The basic problem here is that if you DON'T have concurrent request handling turned on, you are going to run against that problem. Becuase, since your app isn't handling multiple requests concurrently, the file upload (comprimising one request) will block all other requests, whether from that session or another session, until is complete. This is indeed obviously a problem.


One solution, naturally, would be to turn concurrent request handling on. Another, that I plan to work on when I get the chance, would be to have your form be of a direct action type, rather than a component action type, but use a custom request handling for handling the direct action-like action. The custom request handler would be very much like the direct action handler, but would NOT block, regardless of whether concurrent request handling was enabled. It would effectively ignore the concurrent request handling setting. Obviously, you'd need to be quite careful what you do in this action, since the app might not be expecting concurrent requests, but will get them to some degree.

Once you've solved this problem, you still have another problem, on the browser end. If the form-submit is targetted to your ordinary main frame, the BROWSER isn't going to want to display anything there (like a progress bar, that you are trying to provide with WOLongResponse page!) until the form submit is finished. You'd need to do something tricky with frames and/or seperate browser windows to get the browser to display a progress bar type thing while the form upload is in progress. [And this won't neccesarily work with all browsers---it relies on the browser itself to be multi-threaded, but I think all realistic browsers will perform properly].

I plan on getting this all together to work like this when I have time, some time in the next month or two. It's definitely rather tricky, but I think it's do-able.

1) First, if possible, I'd like to get the size of the file from the input Stream before anything begins to get uploaded. How is it done or can't it be done?

Well, you can't get it from the inputStream, but you can get it from the WOMultipartIterator object. However, accessing the WOMultipartIterator object is somewhat dangerous if you are using a component action, rather than a direct action. [And using a direct action is a lot more work, but do-able. See the example in the file upload examples in 5.2.] But see currentRequest().multipartIterator().contentLengthRemaining(). Again, I wouldn't try this in a component action.


Alternately, it may be possible to examine the WORequest headers directly for the content-length header. Not sure if WO will give this to you this way or not. But that's the header WOMultipartIterator is using anyhow.

In either case, this is just kind of an estimate, and will be dificult to use effectively if you have more than one file in the form-submit, or some huge amount of non-file data in the form-submit. It's dificult or impossible to do anything about this, it's a HTTP issue, not a WO issue. The info you want just ain't in the HTTP request in any way but this.


2) Armed with that info I'm hoping to tell the LongRequestReponse page to kick in if the data is more than a particular length or simply attach it's process to the length full stop.

Well, see the various caveats above about using the WOLongResponsePage with an upload AT ALL. But with or without the WOLongResponse page, you can certainly tell if the upload is Too Big. The problem then becomes... how do I cancel the upload? It's tricky. An Apple Engineer told me that there is no good way to get WO to close an incoming HTTP request connection before it's fully complete. Which is what would be required here. However, there may be various BAD ways which would work, if you catch the proper exception. Not sure what will happen if you simply return from yoru (direct) action method before you've fully read the InputStream. It won't be pretty, but you may be able to get it to work. The problem is, not only do you need to get WO to stop handling the request, you need to get the BROWSER to realize that the server has closed the connection, and stop trying to upload the gigantic file. But even harder than this, you'd need to get the BROWSER to do more than display an error page "server has closed connection", you want the browser to display a nice URL of your own devising that's all pretty and explains what's going on.


It's going to be tricky.


middle of a process. Whereas doing a straight upload, if the user wants out, they just press stop and that's exactly what happens everything stops. I imagine your instance hangs as I have not yet tested in deployment, but in development all functions of the browser hang and the app has to be rebuilt to get it going again... worrying to say the least. I need to overcome this problem badly. Who can help.

Well... if the user presses the "stop" button their browser, it should NOT cause any particular problems for your WO application. It _will_ cause an exception to be thrown from the takeValuesForRequest method (at least in a component action---haven't investigated where/if the exception is thrown in a direct action method). What type of exception? I'm not sure---it may even depend on browser type. I've noticed the following exceptions thrown from component takeValuesFromRequest, all of which MAY be caused by a browser-stop button, I'm not sure.


1) An NSForwardException wrapping an IOException whose message is set to "Error in file transfer."
2) A RuntimeException (base class, not an NSForwardException) whose message is set to "Error writing to output stream: java.io.FileOutputStream."


Maybe a couple others too.

You _could_ catch this exception to be aware of this condition. But what are the consequences of this exception being thrown, if you don't catch it? Well, WO will instantiate a WOExceptionPage to report it, but the user will never see it, because they've pressed the stop button, the browser is no longer paying attention to anything the server may wish to return. So it doens't really matter if you don't catch it.


3) Once finished I want to return to the upload form (how do you get the stream to inform you that it has finished its processing so you can tell the LongResponse page this?)

Not sure what you mean exactly, but I think my earlier comments outline some of the dificulties with this sort of thing.


Good luck. It's a challenge. Like I said, I plan on attacking this myself when I have time, and would be interested in any useful code you come up. I will also share my code once I have time to deal with it.

--Jonathan
_______________________________________________
webobjects-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/webobjects-dev
Do not post admin requests to the list. They will be ignored.

  • Prev by Date: Large File Uploads [was Re: Large volume file upload design question ]
  • Next by Date: Nested Editing Contexts
  • Previous by thread: Large File Uploads [was Re: Large volume file upload design question ]
  • Next by thread: Nested Editing Contexts
  • Index(es):
    • Date
    • Thread