I can provide a website for development and testing. I could even be talked into hosting a source control system of some type if there was enough interest. Regards, Doug Wilson Fridge Productions
To Rasmus, I looked into asynch httphandlers, but it would seem that these are for when your custom processing needs to do asynch work. ASP.NET just calls you once, then you call ASP.NET back when you are done with your processing. From what I have found in
many, many web searches for docs, the first thing that happens when a request (posted file) comes in is that IIS mapping determines that it should go to the ASP.NET dll, and then IIS "forwards" the request to whatever BeginRequest handler is currently associated
(built-in or your custom handler). But, if I understand this process correctly, by the time BeginRequest has been called, IIS has *already* received (and buffered) the *entire* request in memory, so even though a custom BeginRequest handler could read the
request in, say, 8000 byte chunks and save it to a temp file, the stream that it is reading is *already* completely loaded into IIS memory, so it wouldn't help. However, as you point out, AspUpload.Net claims that their GigUpload technology keeps server memory
load really low (from their docs, it looks like the "chunksize" is all that is kept in memory). So either they are only being *partially* truthful in their marketing (ASP.NET only uses, say, 8k, but IIS uses the full file size), or I am missing something.
I know that the interception of an incoming request "as it comes in" can be done in an ISAPI extension or ISAPI filter, but everything that I have read states that by the time *any* ASP.NET code sees the request, IIS has already received the *entire* request.
Any Microsoft folks want to clarify this for me? Given all that, I really don't know how AspUpload.Net does it without using a client side control or a real (unmanaged) custom ISAPI filter. There is one other way to make this work. If you can count on the
browser being Internet Explorer, you can use an ADO objects (the XMLHttp and Stream objects) along with client-side javascript to post the upload in small chunks. The problem with this is that the security settings for Internet Explorer have to be relaxed
to allow reading of local files, and I'm pretty sure that most people won't want to do this... J B. Podolak
I too am working on this problem for an application and here's my thoughts so far: In the Application_BeginRequest event handler you do have control before the entire stream is buffered into memory. Just set a breakpoint in that method somewhere and you'll
see that it fires immediately upon clicking your submit button. So that means that there is the ability to do some pre-processing on the request before the upload begins a-la ABC Upload. What the pre-processing is that we need to do is a mystery.... Here's
what I have done: I've trapped the request for the upload in Application_BeginRequest and cached it in the Cache object. I then launch a popup window which reads the cached Request object to try and access the Request.TotalBytes property to get the length
of the input stream. The problem is that the input stream is so busy doing the upload that it never responds to the line of code trying to get the TotalBytes property. I know this because if I hit the Stop button on the main browser window (the one doing the
upload) my popup immediately displays the amount of bytes uploaded to that point. I feel so close, yet I think my approach may be too simplistic.... Jay
To J B. Podolak and ITJ Sounds like async handlers are out of the question. Too bad - they looked promising :-). Regarding IIS buffering the request: My experience is, that it is possible to intercept the event before the buffering occurs - as ITJ points out.
However, as soon as a reference to the request stream is made, the *entire* request is read into memory, as J.B. points out. I think we need to override the method supplying the request to HttpContext. I am not sure how to do this. However, one approach would
be to implement your own hosting scenario. Look for System.Web.Hosting in the documentation, and it states, that you are able to host your own virtual address, thus CIRCUMVENTING IIS. Basically it requires you to implement the SimpleWorkerRequest interface,
which apparently will be responsible for serving the HttpContext object. To me, this sounds like good news. However, I haven't been down that road yet, and are reluctant to go there, because it doesn't seem to be what abcupload.net is doing. However, after
my exams (18/12), I'll probably try this. I can only support your request for a microsoft developer to look at this. In my opinion, we need an optimal solution to this problem, as the current upload method clearly has shortcomings or even a memory leak, as
indicated by the 4. post in this thread: http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=95255
I've been doing some more digging in System.Web.Hosting assisted by the ms opensource Cassini web server documentation I really believe we could get somewhere by giving this a shot. It is the backdoor into the top of the http request pipeline that we need.
When IIS receives a request for an aspx resource, it instantiates a HttpRuntime object, and calls ProcessRequest(HttpWorkerRequest hwr) The HttpRuntime object is TOP of the http pipeline, as shown here: http://msdn.microsoft.com/msdnmag/issues/02/09/HTTPPipelines/default.aspx
The hwr argument passed to the HttpRuntime object is the toolbox that we want to alter. Inside HttpWorkerRequest are all the methods that HttpRuntime uses when it wants the request processed. HttpWorkerRequest is an abstract class, so we can implement our
own version, and override the methods responsible for reading the request. There is even a class called SimpleWorkerRequest, which is already implementing HttpWorkerRequest. So in fact we only need to implement our own SimpleWorkerRequest. By creating our
own hosting environment, we do the job of IIS: We pass an instance of our SimpleWorkerRequest-derived class to HttpRuntime.ProcessRequest, to make it the new toolbox that HttpRuntime must use, when it wants the request processed. How to setup a separate hosting
environment? This articles explains how - and apparently, it seams quite possible: http://www.iunknown.com/Weblog/HostingASP.NETinaWinForms.html However, I find it slightly annoying that we have to go so far to theoretically have a chance of achieving the
goal. I've found indications in MSDN about a possibility of changing the HttpWorkerRequest object, even without creating your own hosting environment, and I'll be looking at that next. Hmm...once again my exam preparation was cancelled in favour of .net. Terrible.
Only 4 days left. I'll be seeing you guys on the other side of the exams.
Please, could some asp.net team people comment on these ideas? This nut is not nearly cracked, and I really could use a pointer in the right direction. Kind regards, Rasmus
We'll get this together! :-) I am now more certain that I am onto the right track: First of all, don't bother setting up your own hosting environment just to get to HttpWorkerRequest. As I indicated in my last post, it really is quite possible to get the HttpWorkerRequest
directly from the current request, though I'm still working on how :-). This is the plan: 1. Intercept request with a HttpModule, setup the BeginRequest event handler 2. In the BeginRequest event, get access to the HttpWorkerRequest object - somehow :-( 3.
Call the appropriate methods of hwr object, such as ReadEntityBody(byte[] buffer, int size) in a while loop with an appropriate sized buffer, and store the request chunks somewhere (not in memory) between loops, untill full request has been read. 4. Extract
just the file data from the saved request. 5. Somehow indicate to the rest of the processing pipeline, that the request has already been read, so no more calls to ReadEntityBody and methods alike are made. (yes, very abstract :-)). The reason why I am more
sure now, is after a conversation with abcupload.net support, and some more testing. It seems that abcupload.net is NOT able to do its division of the upload without a httpmodule! I know I've indicated something to the contrary earlier - however, I've also
speculated that something was wrong about them only using the httpmodule for progress indication. Generally, I believe I had misunderstood the functionality of abcupload.net...sorry about that :-) However, with help from the support team, it has now become
clear, that abcupload.net DOES rely on a httpmodule for BOTH gigupload technology and progress indication! So that opens up for the intuitively approach stated above, and gives some assurance of this being a possible solution. Still quite a few puzzles are
left unsolved. So once again: asp.net team people, please tell how I can get the HttpWorkerRequest from HttpApplication? - I know it must be possible somehow. This is really the most essential need. Regards, Rasmus
Rasmus (ups101): Here's how to get at the HttpWorkerRequest from within a BeginRequest handler (I found it in another thread): private void OnBeginRequest(object src, EventArgs e) { HttpApplication app = (HttpApplication)src; HttpWorkerRequest workerRequest
= (HttpWorkerRequest)app.Context.GetType() .GetProperty("WorkerRequest", (BindingFlags)36) .GetValue(app.Context, null); } Also of interest, here's what I found on "ending a request" in an HttpModule: The HttpApplication object exposes the CompleteRequest
method. If an HTTP module's event handler calls HttpApplication.CompleteRequest, normal pipeline processing is interrupted after the current event completes (including the processing of any other registered event handlers). A module that terminates the normal
processing of a message is expected to generate an appropriate HTTP response message. Given the above, along with ReadEntityBody() maybe we can make this work correctly... Please post your results! J B. Podolak
J.B. Podolak Beautiful! I think you're right; this should be possible now. I'll post results in a few days...just one more exam to go wednesday. BTW: I believe (BindingFlags)36 can be replaced by BindingFlags.NonPublic | BindingFlags.Instance IL looks the same...
Kind regards, Rasmus
Cyberfloatie
Member
102 Points
29 Posts
Re: Somebody must know the answer, please help: HttpHandler or HttpModule for file upload, large ...
Dec 05, 2002 02:26 PM|LINK
J B. Podolak
Member
30 Points
6 Posts
Re: Somebody must know the answer, please help: HttpHandler or HttpModule for file upload, large ...
Dec 05, 2002 03:24 PM|LINK
ltj2489
Member
5 Points
1 Post
Re: Somebody must know the answer, please help: HttpHandler or HttpModule for file upload, large ...
Dec 05, 2002 07:09 PM|LINK
ups101
Member
205 Points
41 Posts
Re: Somebody must know the answer, please help: HttpHandler or HttpModule for file upload, large ...
Dec 05, 2002 08:27 PM|LINK
ups101
Member
205 Points
41 Posts
Re: Somebody must know the answer, please help: HttpHandler or HttpModule for file upload, large ...
Dec 05, 2002 11:24 PM|LINK
ups101
Member
205 Points
41 Posts
Re: Somebody must know the answer, please help: HttpHandler or HttpModule for file upload, large ...
Dec 12, 2002 08:48 PM|LINK
Cyberfloatie
Member
102 Points
29 Posts
Re: Somebody must know the answer, please help: HttpHandler or HttpModule for file upload, large ...
Dec 13, 2002 01:37 PM|LINK
ups101
Member
205 Points
41 Posts
Re: HttpHandler or HttpModule for file upload, large files, progress indicator?
Dec 13, 2002 09:30 PM|LINK
J B. Podolak
Member
30 Points
6 Posts
Re: HttpHandler or HttpModule for file upload, large files, progress indicator?
Dec 16, 2002 06:34 PM|LINK
ups101
Member
205 Points
41 Posts
Re: HttpHandler or HttpModule for file upload, large files, progress indicator?
Dec 16, 2002 09:17 PM|LINK