Thursday, March 3, 2011

HttpWebRequest AddRange with Long values

HttpWebRequest contains a method called AddRange which is very useful when we want to download a file in segments or want to resume the download from where it was stopped previously. But HttpWebRequest.AddRange has one drawback, the parameters for range of bytes is in integer which means only range upto approximately 2 GB is allowed. So we cannot use this method if we want to use it for downloading files in Range greater than 2 GB. If we try to add value greater than “2147483647”  we will get following exception.

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.

So the solution for this problem is to extend the AddRange method with support for long parameters. HttpWebRequest has a private function AddRange which have three string parameters which we can use with Reflection classes.

Private Function AddRange(ByVal rangeSpecifier As String, ByVal fromValue As String, ByVal toValue As String) As Boolean

So now we can use Reflection and add two method with parameter in Long to allow larger value.

Imports System.Reflection
Imports System.Net
Imports System.Runtime.CompilerServices 

Public Module MyModule
#Region "HttpWebRequest AddRange"

    <Extension()> _
    Public Sub AddRange(ByVal request As HttpWebRequest, ByVal from As Long, ByVal [to] As Long)
        Dim info As MethodInfo = Nothing
        Dim methods() As MethodInfo = GetType(Net.HttpWebRequest).GetMethods(BindingFlags.Instance Or BindingFlags.NonPublic)

        For Each mi As MethodInfo In methods
            If mi.Name = "AddRange" Then
                info = mi
                Exit For
            End If
        Next
        If info IsNot Nothing Then
            Dim parameters(2) As Object
            parameters(0) = "bytes"
            parameters(1) = from.ToString
            parameters(2) = [to].ToString
            info.Invoke(request, parameters)
        End If
    End Sub

    <Extension()> _
    Public Sub AddRange(ByVal request As HttpWebRequest, ByVal from As Long)
        Dim info As MethodInfo = Nothing
        Dim methods() As MethodInfo = GetType(Net.HttpWebRequest).GetMethods(BindingFlags.Instance Or BindingFlags.NonPublic)
        For Each mi As MethodInfo In methods
            If mi.Name = "AddRange" Then
                info = mi
                Exit For
            End If
        Next

        If info IsNot Nothing Then
            Dim parameters(2) As Object
            parameters(0) = "bytes"
            parameters(1) = from.ToString
            parameters(2) = String.Empty
            info.Invoke(request, parameters)
        End If
    End Sub
#End Region
End Module

After adding above code in the project, two new HttpWebRequest.AddRange method will get added with long parameter.

HttpWebRequest.AddRange(byval from as Long)
HttpWebRequest.AddRange(byval from as Long,byval to as Long)

Now you can use this methods as shown in following code

Dim startPosition As Long = Integer.MaxValue
Dim endPosition As Long = startPosition + 1000
Dim request As HttpWebRequest = WebRequest.Create("Url")
request.AddRange(startPosition, endPosition)

No comments:

Post a Comment