Why is Request.Files.Count sometimes 0 using HTML5 uploader? - asp.net

We're using plupload for users to upload files to our VPS.
Here is the plupload code:
var uploader = new plupload.Uploader({
browse_button: 'fileSelectorLink',
container: 'uploadContainer',
drop_element: 'uploadbox',
url: '/UploadHandler.ashx',
unique_names: true,
multi_selection: false,
flash_swf_url: '/scripts/plupload/js/Moxie.swf',
silverlight_xap_url: '/scripts/plupload/js/Moxie.xap'
});
He is the code for processing the request:
Public Sub ProcessRequest(context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim runtime As String = If(context.Request("runtime") IsNot Nothing, context.Request("runtime"), "Unknown")
If context.Request IsNot Nothing Then
If context.Request.Files.Count > 0 Then
Dim fileUpload As HttpPostedFile = context.Request.Files(0)
...
Else
' Throw an exception
End If
End Sub
Occasionally (about 2% of the time) the exception will get thrown. Here is an example of request that threw an error:
Runtime: html5
Request.ContentType: multipart/form-data; boundary=----WebKitFormBoundaryo7JAtlhKsg8xDcQT
Request.ContentLength: 3758089
Request.ContentEncoding: System.Text.SBCSCodePageEncoding
Request.TotalBytes: 3179067
The errors seem to happen across different browsers and OSs (even modern browsers), so that doesn't seem to be the issue. Plupload should fall back to other versions if browser doesn't handle async file uploads. I thought the ContentEncoding seemed odd, but it seems to always say that (maybe plupload works like that?). The only thing that jumped out at me is that the ContentLength and TotalBytes were different, but in my local testing they were the same. Could that be a problem?
Been stuck on this issue for a few days and haven't had any good leads.

The failures could be occurring when users abort the upload (usually indicated by "The remote host closed the connection." exceptions), are encountering network latency, perhaps from HTTP timeouts, maybe even an issue with the Plupload code. My apologies for not being specific with the reason, however I believe I can make up for it by providing a solution that could limit issues encountered by users on your site.
Plupload contains a setting that will retry the upload upon encountering a HTTP error response. Use the max_retries setting so that in an instance where there is a "network hiccup", another attempt (or few) is/are done to retry the upload. Of course you'll still see the exceptions, but this may prevent the users from having to click the upload button again.
Your code would then become:
var uploader = new plupload.Uploader({
browse_button: 'fileSelectorLink',
max_retries: 2,
container: 'uploadContainer',
drop_element: 'uploadbox',
url: '/UploadHandler.ashx',
unique_names: true,
multi_selection: false,
flash_swf_url: '/scripts/plupload/js/Moxie.swf',
silverlight_xap_url: '/scripts/plupload/js/Moxie.xap'
});
Additionally, you can use a binary stream instead of multipart to post the file, which may alleviate issues with older browsers. You control this with the multipart setting.

Related

HttpWebRequest received error 406 and Fiddler seems to have confused things

I am using the following code....
Dim myHttpWebRequest As HttpWebRequest = CType(WebRequest.Create(PostingUrl), HttpWebRequest)
myHttpWebRequest.Method = "POST"
myHttpWebRequest.Headers.Add("Authorization", "Bearer " & RSettings.access_token)
myHttpWebRequest.Headers.Add("Accept-Version", "2")
myHttpWebRequest.ContentType = "application/json; charset=UTF-8"
myHttpWebRequest.Accept = "application/json"
' myHttpWebRequest.Proxy = Nothing ' ** SEE NOTES ON THIS LINE **
Dim Byt As Byte() = Encoding.UTF8.GetBytes(DataString)
Using stream = myHttpWebRequest.GetRequestStream()
stream.Write(Byt, 0, Byt.Length)
End Using
Using myHttpWebResponse As HttpWebResponse = CType(myHttpWebRequest.GetResponse(), HttpWebResponse)
Using srRead As New StreamReader(myHttpWebResponse.GetResponseStream())
ListingResponse = srRead.ReadToEnd()
End Using
End Using
Where:
PostingUrl is "https://reverb.com/api/listings"
RSettings.access_token is (obviously) my access token for this API
DataString is a JSON string posting the data to the Reverb API
If I run my code from Visual Studio (localhost) it returns
The remote server returned an error: (406) Not Acceptable.
Trying to figure out why, I opened Fiddler hoping I could inspect content types and figure out the problem, but the response error changed to:
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
(I'm guessing from this error that I also have an issue with my Auth key, but that's a separate subject I think.)
After a bit of Googling and S/O pages I found two suggestions:
Tools > Fiddler Options > HTTPS and uncheck "Capture HTTPS CONNECTs"
Add the commented out line: myHttpWebRequest.Proxy = Nothing
If I make any of those changes, I get back to my Error 406 that I get without Fiddler running.
However, if I add myHttpWebRequest.Proxy = Nothing line added, I can no longer see the Tunnel to http://reverb.com:443 Log entry in Fiddler, there's no record of a request to Reverb.com so I can't inspect anything.
I'm now very confused about what I'm doing, and I guess haven't actually made any progress at all!
I still have error 406 and don't seem to be able to inspect the headers/content type issues with Fiddler as I had hoped (please explain how if I am wrong!)
Even if I do correct the 406, I think I have an authentication error.
By the way... all this is an attempt to recreate the cURL example on the Rever docs page here:
https://dev.reverb.com/docs/create-a-listing
I have also been discussing this issue here:
https://dev.reverb.com/v1.0/discuss/57bb2ca0aa8f760e004588cf
Argh... well, my confusing over Fiddler still stands but the 406 error was caused by this:
myHttpWebRequest.Headers.Add("Accept-Version", "2")
Should have been
myHttpWebRequest.Headers.Add("Accept-Version", "2.0")
How simple!!

Request.Form between HTTP and HTTPS pages in ASP.NET

I have a strange situation and google isn't helping me out. I have an admin site which is in simple HTTP who posts data to a different site running under HTTPS. The HTTP admin site (which I don't have direct access to) is sending the info via basic POST, and I'm trying to capture the Request.Form values in the HTTPS site. It works perfectly well in dev, due to the fact that the receiving site isn't running under SSL, but in prod, I have the Request.Form as empty. Someone could enlighten me? The basic HTTPS request code is below:
Dim nvm As NameValueCollection = Request.Form
Dim _idInscricao As String
Dim _Origem As String
litMensagem.Text = "Wait..."
If nvm.Keys.Count = 0 Then
litMensagem.Text = "Error recovering data. No keys found."
Exit Sub
End If
For Each _Key As String In nvm.Keys
If _Key.ToLower.EndsWith("idinscricao") Then
_idInscricao = nvm(_Key)
End If
If _Key.ToLower.EndsWith("origem") Then
_Origem = nvm(_Key)
End If
Next
If _idInscricao Is Nothing OrElse String.IsNullOrEmpty(_idInscricao) _
OrElse _Origem Is Nothing OrElse String.IsNullOrEmpty(_Origem) Then
litMensagem.Text = "Error recovering data."
Exit Sub
End If
I found this question because I was having the same problem, and I need to thank dana for the fiddler recommendation.
Using Fiddler, I found out what was going on. My page was on HTTPS, and the form that I was posting posted to HTTP. I couldn't figure out why my form structure on the posted page was empty.
Turns out the server couldn't find the http version of the file and did an automatic redirect to the https version, doing a GET with my form variables. They aren't available in the form scope with a GET. (FWIW, I'm using CFML.)
Once I changed the form action to post to HTTPS, everything worked like a charm.
-jason

Response.WriteFile function fails and gives 504 gateway time-out

Environment:
-SharePoint 2010 foundation
-Claim based authentication
-Execution time out in web.config is set to 3600
Overview:
We have an excel export functionality where we connect to AD and SQL databases to fetch Users and their related data for a perticular Organization Unit (OU)in Active Directory.
We have on OU in AD which has got around 1400 users in it. We are using Open and Closed xml to generate excel file which works fine and takes about 11-14 minutes to generate a file on the server on following path
C:\inetpub\wwwroot\wss\VirtualDirectories\VirtualDirectyrName\Excel\FileName.xlsx
Immediately after generating a file we have following piece of code which would read file from server and dump it on output steam and presents a file ope-save as dialog box in browser to end user.
Problem Description:
When an Organization has less number of users and it does not take more than 5-6 minteus to generate the file on server, following piece of code successfully downloads the file on browser. But when for above mentioned OU where we have 1400 users the reponse.writefile function fails and in browse we get to see 'Browse can not display this web page' (when fiddler was on we found it gives - http 504 error). Surpricingly if we perform this export from the server itself (i.e browse the web site on server) it downloads without issue.
protected void lnkbtnDownloadFile_Click(object sender, EventArgs e)
{
String fileName = #"C:\inetpub\wwwroot\wss\VirtualDirectories\VirtualDirectyrName\Excel\540KBFileWhichFails.xlsx";
//File size is hardly ~500 KB
//Wait for around 12 minutes, to mimic a scenario of file generation which takes time on staging and prod. environment.
System.Threading.Thread.Sleep(720000);
try
{
if (fileName != "")
{
var file = new FileInfo(fileName);
if (file.Exists)
{
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
Response.AddHeader("Content-Length", file.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(file.FullName);
Response.End();
}
else
Response.Write("This file does not exist.");
}
}
catch (Exception ex)
{
//This would usually give thread aboart exception but thats expected.
}
}
we dont see any error in ULS logs, event logs specific to this behavior.
Please note , response.TransmitFile also gives same behaviour.
any idea ?
What I suspect here is that you have felt on session lock. What I mean is that the download and the generation and all this calls made using the session, and session locks everything until finish.
To solve this issue do two thinks.
When you generate this file, generate it ether with thread ether with handle with out session needed
Download this file from a handler (that not use session) and not from the page post back.
For example you make a handler, eg download.ashx and you make a link to your page as download.ashx?thisfileId=7723423&SecurityID=82jkj1288123 Inside your handler you read this parameters and you send the file. But if you make this on the page then a way is to disable the session for this page if you not use session, for example you set EnableSessionState="false" on the first line declarations.
Some similar questions and session relative answer.
call aspx page to return an image randomly slow
Replacing ASP.Net's session entirely
How to deliver big files in ASP.NET Response?
I figured out the issue, It was an issue with the Idle time out issue in the Hardware load balancer we where using. Default value in load balancer was 0 which meant 11 minutes and my file generation was taking longer than that which caused this issue. Increasing load balancer idle time out issue seems to be solutions.

401 Unauthorised errors when attempting to download ASP page to file

Issue
Msxml2.ServerXMLHTTP keeps returning 401 - Unauthorised errors each time we attempt to read the contents of a file (ASP) from a web server.
Source server is running IIS6, using NTLM integrated login.
This process has been used successfully before, but only in as far as extracting XML files from external websites, not internal ones.
The proxy settings in the registry of the server on which the script is run has also been updated to bypass the website in question, but to no avail.
All paths identified in the VBScript have been checked and tested, and are correct.
User running the script has correct read/write permissions for all locations referenced in the script.
Solution needed
To identify the cause of the HTTP 401 Unauthorised messages, so that the script will work as intended.
Description
Our organisation operates an intranet, where the content is replicated to servers at each of our remote sites. This ensures these sites have continued fast access to important information, documentation and data, even in the event of losing connectivity.
We are in the middle of improving the listing and management of Forms (those pesky pieces of paper that have to be filled in for specific tasks). This involves establising a database of all our forms.
However, as the organisation hasn't been smart enough to invest in MSSQL Server instances at each site, replication of the database and accessing it from the local SQL server isn't an option.
To work around this, I have constructed a series of views (ASP pages) which display the required data. I then intend to use Msxml2.ServerXMLHTTP by VBScript, so I can read the resulting pages and save the output to a static file back on the server.
From there, the existing replication process can stream these files out to the site - with users having no idea that they're looking at a static page that just happened to be generated from database output.
Code
' Forms - Static Page Generator
' Implimented 2011-02-15 by Michael Harris
' Purpose: To download the contents of a page, and save that page to a static file.
' Target category: 1 (Contracts)
' Target Page:
' http://sharename.fpc.wa.gov.au/corporate/forms/generator/index.asp
' Target path: \\servername\sharename\corporate\forms\index.asp
' Resulting URL: http://sharename.fpc.wa.gov.au/corporate/forms/index.asp
' Remove read only
' Remove read only flag on file if present to allow editing
' If file has been set to read only by automated process, turn off read only
Const READ_ONLY = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile("\\server\sharename\corporate\forms\index.asp")
If objFile.Attributes AND READ_ONLY Then
objFile.Attributes = objFile.Attributes XOR READ_ONLY
End If
Dim webObj, strURL
Set webObj = CreateObject("Msxml2.ServerXMLHTTP")
strURL = "http://sharename.fpc.wa.gov.au/corporate/forms/generator/index.asp"
webObj.Open "GET", strURL
webObj.send
If webObj.Status=200 Then
Set objFso = CreateObject("Scripting.FileSystemObject")
Set txtFile = objFso.OpenTextFile("file:\\servername.fpc.wa.gov.au\sharename\corporate\forms\index.asp", 2, True)
txtFile.WriteLine webObj.responseText
txtFile.close
ElseIf webObj.Status >= 400 And webObj.Status <= 599 Then
MsgBox "Error Occurred : " & webObj.Status & " - " & webObj.statusText
Else
MsgBox webObj.ResponseText
End If
Replace your line:
webObj.Open "GET", strURL
With:
webObj.Open "GET", strURL, False, "username", "password"
In most cases 401 Unauthorized means you haven't supplied credentials. Also you should specifiy False to indicate you don't want async mode.
It sounds like the O.P. got this working with the correct proxy settings in the registry (http://support.microsoft.com/kb/291008 explains why proxy configuration will fix this). Newer versions of ServerXMLHTTP have a setProxy method that can be used to set the necessary proxy configuration in your code instead.
In the O.P. code above, after webObj is created, the following line of code would set up the proxy correctly:
webObj.setProxy 2, "0.0.0.0:80", "*.fpc.wa.gov.au"
ServerXMLHTTP will pass on the credentials of the user running the code if it is configured with a proxy, and if the target URL bypasses that proxy. Since you are bypassing the proxy anyway, you can make it a dummy value "0.0.0.0:80", and make sure your target url is covered by what you specify in the bypass list "*.fpc.wa.gov.au"
I would first test if you can reach your url through a normal browser on the same server X you run your code on (A). I would try then reach the url from another PC. One never used to reach that url but in the same network as server X (B).
If B works but A doesn't I would suspect that for some reason your source server (i.e. that one that serves the url) blocks server X for some reason. Check the security settings of II6 and of NTLM.
If both A and B don't work, there is something wrong more in general with your source server (i.e. it blocks everything or NTML doesn't allow you in).
If A works (B doesn't matter then), the problem has to be somewhere in your code. In that case, I would recommend fiddler. This tool can give you the HTTP requests of both your browser and your code in realtime. You can then compare both. That should give you at least a very strong hint about (if not immediately give you) the solution.

Getting 2032 error (On only 1 machine)

I built an AIR app a while ago. One of the users today got a new machine (XP) and keeps getting a 2032 error when the app tries to send/receive data via HTTPService I verified that this page works when accessed within a web browser. It also works on AIR apps on other machines. The page and the AIR app haven't been changed for months, the only thing that has changed is this particular users computer. I recompiled to get a more specific error and this is what I got:
(mx.messaging.messages::ErrorMessage)#0
body = ""
clientId = "DirectHTTPChannel0"
correlationId = "B38588EC-AEA0-84F0-F5B2-F6B6AB6C3456"
destination = ""
extendedData = (null)
faultCode = "Server.Error.Request"
faultDetail = "Error: [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2032" errorID=2032]. URL: https://www.example.com/mypage.php"
faultString = "HTTP request error"
headers = (Object)#1
DSStatusCode = 0
messageId = "2BC38D14-63DD-345E-50DD-F6B6AEE75438"
rootCause = (flash.events::IOErrorEvent)#2
bubbles = false
cancelable = false
currentTarget = (flash.net::URLLoader)#3
bytesLoaded = 0
bytesTotal = 0
data = ""
dataFormat = "text"
errorID = 2032
eventPhase = 2
target = (flash.net::URLLoader)#3
text = "Error #2032"
type = "ioError"
timestamp = 0
timeToLive = 0
As I am writing this I had the user restart and relaunch the application, it is now working so I am not too worried about it, but I am still curious what could have happened if anyone has any ideas?
Update
Today (next day) It is happening again and restart isn't even fixing it today. It has to be something on her machine interfering causing the problem because I can run the program on any other machine just fine with no problem. Not sure what it could be or how to troubleshoot that?
Did the server hiccup just then, i.e. downtime and/or cosmic ray? Cross reference the user access time with the apache access/error.log on the server. Did crossdomain.xml change anyplace that your program references?
I had somewhat the same problem here but with a Flash (Web - Flex 4.1 SDK) application.
after trying out a huge assortment of solutions we narrowed we finally came up with one that works pretty reliably for all systems, including newly installed machines.
A. add global event listeners at the root (or stage) of the application, on flex preinitialize stage.
IOErrorEvent.IO_ERROR
IOErrorEvent.NETWORK_ERROR
HTTPStatusEvent.HTTP_STATUS
ErrorEvent.ERROR
SecurityErrorEvent.SECURITY_ERROR
if an error is cought - event.preventDefault();
B. add event listeners on every loader used in the App for the following errors:
IOErrorEvent.IO_ERROR
SecurityErrorEvent.SECURITY_ERROR
HTTPStatusEvent.HTTP_STATUS
*to attempt recovery, like falling back to an external interface call...
C. place all the SWZ files from the bin-release folder together with the SWF file in the same path on the server you use to deliver your App.
in my case these are the files needed:
sparkskins_4.5.1.21328.swz
spark_4.5.1.21328.swz
textLayout_2.0.0.232.swz
rpc_4.5.1.21328.swz
osmf_1.0.0.16316.swz
framework_4.5.1.21328.swz
* to discover this i used Chrome developer console to see which errors occur on the page and discovered a chain of 404s when the app tries to download these files.
D. have a properly configured crossdomain.xml policy file which includes the allow http request xml tag.
<allow-http-request-headers-from domain="*" headers="*"/>
replace the * as needed in your particular case.
Cheers

Resources