File chunking fails when served from IIS7 to firefox

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
I have written a generic file serving handler in asp.net/vb.net - it has been working great. I recently moved to a windows 7 box and am now debugging under IIS7, and this is where the problems occure.
Whenever I serve a file to either FireFox or Chrome (IE8 works fine) from IIS 7, the download will fail.
<br/>
- In FireFox the error is "[some file name and path].part could not be saved, because the source file could not be read."<br/>
- In Chrome the error is "<span><span style="line-height:15px; font-family:Helvetica,Arial,sans-serif; font-size:13px Error 330 (net::ERR_CONTENT_DECODING_FAILED): Unknown error."<br/>
- In IE8 it works fine
<span><span style="line-height:15px; font-family:Helvetica,Arial,sans-serif; font-size:13px If I run the same code in IIS6, it works fine.<br/>
If I run the same code in the Visual Studio virtual web server, it works fine (on windows 7 or XP).
<span><span style="line-height:15px; font-family:Helvetica,Arial,sans-serif; font-size:13px I am rather concerned about this as our production web server will soon be IIS7; which Im starting to really love, and would hate to revert to IIS6 just because
this wont work in IIS7.
<span><span style="line-height:15px; font-family:Helvetica,Arial,sans-serif; font-size:13px Here is the code Im using..Ive tried a number of different patterns. It seems to always fail on the Flush() line with the error "System.Web.HttpException
= {"The remote host closed the connection. The error code is 0x80070040."}"
<span><span style="line-height:15px; font-family:Helvetica,Arial,sans-serif; font-size:13px One thing I have noticed, if I move the flush statment to the finally clause or remove it all together; firefox will attempt to read the entire file - it appears
to be looping through the entire block of code just fine, until it hits the flush statement. If I remove the flush statment I still get an error and it still tries to read the entire file before asking me to save it.
<span><span style="line-height:15px; font-family:Helvetica,Arial,sans-serif; font-size:13px --Edit: I removed the flush and tested again; firfox thinks it downloaded a zero byte file.
<span><span style="line-height:15px; font-family:Helvetica,Arial,sans-serif; font-size:13px Im assuming I just have some sort of header issue going on here, but Im at a loss at this point as to what that would be.
<span><span style="line-height:15px; font-family:Helvetica,Arial,sans-serif; font-size:13px Any help would be appreciated.
<span><span style="line-height:15px; font-family:Helvetica,Arial,sans-serif; font-size:13px
<div style="background-color:white; color:black
<pre><span style="color:blue Imports System.Web

<span style="color:blue Imports System.Web.Services

<span style="color:blue Imports System.Data.SqlClient

<span style="color:blue Imports System.Configuration.ConfigurationManager



<span style="color:blue Public <span style="color:blue Class FileHandler

<span style="color:blue Implements System.Web.IHttpHandler



<span style="color:blue Sub ProcessRequest(<span style="color:blue ByVal context <span style="color:blue As HttpContext) <span style="color:blue Implements IHttpHandler.ProcessRequest



<span style="color:blue Dim _fid <span style="color:blue As <span style="color:blue String = context.Request.QueryString(<span style="color:#a31515 "fid")

<span style="color:blue If <span style="color:blue Not _fid <span style="color:blue Is <span style="color:blue Nothing <span style="color:blue AndAlso IsNumeric(_fid) <span style="color:blue Then



<span style="color:blue Dim r <span style="color:blue As IDataReader = GetfileByID(_fid)



<span style="color:blue If <span style="color:blue CType(r, SqlDataReader).HasRows <span style="color:blue Then

StreamData(r, context)

<span style="color:blue Else

context.Response.ContentType = <span style="color:#a31515 "text/plain"

context.Response.Write(<span style="color:#a31515 "Failed to retrieve file")

<span style="color:blue End <span style="color:blue If

<span style="color:blue Else

context.Response.ContentType = <span style="color:#a31515 "text/plain"

context.Response.Write(<span style="color:#a31515 "Invalid File ID")

<span style="color:blue End <span style="color:blue If



<span style="color:blue End <span style="color:blue Sub



<span style="color:blue Private <span style="color:blue Sub StreamData(<span style="color:blue ByVal r <span style="color:blue As IDataReader, <span style="color:blue ByVal context <span style="color:blue As HttpContext)

<span style="color:blue If r.Read <span style="color:blue Then

<span style="color:blue Dim dfi <span style="color:blue As <span style="color:blue New BO_DATASET_OUTPUT_FILE

dfi.Size = r.Item(<span style="color:#a31515 "Size")

dfi.ContentType = r.Item(<span style="color:#a31515 "ContentType")

dfi.Name = r.Item(<span style="color:#a31515 "Name")



context.Response.AddHeader(<span style="color:#a31515 "Content-Disposition", <span style="color:#a31515 "attachment;filename=" & dfi.Name & <span style="color:#a31515 ";")

context.Response.AddHeader(<span style="color:#a31515 "Content-Length", dfi.Size.ToString)





<span style="color:blue Dim dataOrdinal <span style="color:blue As <span style="color:blue Integer = r.GetOrdinal(<span style="color:#a31515 "Bytes")

<span style="color:blue If <span style="color:blue Not r(dataOrdinal) <span style="color:blue Is DBNull.Value <span style="color:blue Then

StreamByteArrayInChunks(r, dataOrdinal, context)

<span style="color:blue End <span style="color:blue If

<span style="color:blue End <span style="color:blue If

<span style="color:blue End <span style="color:blue Sub

<span style="color:blue Private <span style="color:blue Sub StreamByteArrayInChunks(<span style="color:blue ByVal r <span style="color:blue As IDataReader, <span style="color:blue ByVal Ordinal <span style="color:blue As <span style="color:blue Integer, <span style="color:blue ByVal context <span style="color:blue As HttpContext)

<span style="color:blue Dim buffer(102400) <span style="color:blue As <span style="color:blue Byte

<span style="color:blue Dim index <span style="color:blue As <span style="color:blue Integer = 0

<span style="color:blue Try

<span style="color:blue While <span style="color:blue True

<span style="color:blue Dim <span style="color:blue count <span style="color:blue As <span style="color:blue Long = r.GetBytes(Ordinal, index, buffer, 0, buffer.Length)

<span style="color:blue If <span style="color:blue count = 0 <span style="color:blue Then

<span style="color:blue Exit <span style="color:blue While

<span style="color:blue Else

index = index + <span style="color:blue count

context.Response.BinaryWrite(buffer)

context.Response.Flush()

<span style="color:blue End <span style="color:blue If

<span style="color:blue End <span style="color:blue While

<span style="color:blue Catch ex <span style="color:blue As Exception

context.Response.Close()

<span style="color:blue Finally

r.Close()

context.Response.Close()

GC.Collect()

<span style="color:blue End <span style="color:blue Try



<span style="color:blue End <span style="color:blue Sub

<span style="color:blue Public <span style="color:blue Function GetfileByID(<span style="color:blue ByVal fid <span style="color:blue As <span style="color:blue Decimal) <span style="color:blue As IDataReader

<span style="color:blue Dim myConnecation <span style="color:blue As SqlConnection = <span style="color:blue New SqlConnection(AppSettings(<span style="color:#a31515 "fileStreamConn"))

myConnecation.Open()



<span style="color:blue Dim cmd <span style="color:blue As SqlCommand = <span style="color:blue New SqlCommand(<span style="color:#a31515 "dbo.SProc_DataSet_Output_File", myConnecation)

cmd.CommandType = CommandType.StoredProcedure

cmd.Parameters.Add(<span style="color:#a31515 "@Action", SqlDbType.<span style="color:blue Decimal).Value = 4

cmd.Parameters.Add(<span style="color:#a31515 "@FileID", SqlDbType.<span style="color:blue Decimal).Value = fid



<span style="color:blue Dim r <span style="color:blue As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)



<span style="color:blue Return r



<span style="color:blue End <span style="color:blue Function

<span style="color:blue ReadOnly <span style="color:blue Property IsReusable() <span style="color:blue As <span style="color:blue Boolean <span style="color:blue Implements IHttpHandler.IsReusable

<span style="color:blue Get

<span style="color:blue Return <span style="color:blue False

<span style="color:blue End <span style="color:blue Get

<span style="color:blue End <span style="color:blue Property



<span style="color:blue End <span style="color:blue Class

[/code]



View the full article
 

Similar threads

Back
Top