Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检测.NET HttpHandler中的字节范围请求_.net_Http_Httphandler - Fatal编程技术网

检测.NET HttpHandler中的字节范围请求

检测.NET HttpHandler中的字节范围请求,.net,http,httphandler,.net,Http,Httphandler,我有一个HttpHandler,它将对传入的请求进行一些检查,并在某些情况下执行一些功能。需要检查的条件之一是该请求是否为。这是如何实现的?您需要在请求对象中查找一个范围头,该对象是传递给处理请求方法的HttpContext的一部分。HttpRequest类中没有Range属性,因此您必须查看标题。如果存在范围,则其形式如下: 范围:字节=- 其中和是整数。例如,如果有人希望从文件中间得到64K: 范围:字节=32768-98304 您必须将文本解析为数字并进行相应处理。请注意,范围标题语法还允

我有一个HttpHandler,它将对传入的请求进行一些检查,并在某些情况下执行一些功能。需要检查的条件之一是该请求是否为。这是如何实现的?

您需要在
请求
对象中查找一个
范围
头,该对象是传递给
处理请求
方法的
HttpContext
的一部分。
HttpRequest
类中没有
Range
属性,因此您必须查看
标题。如果存在
范围
,则其形式如下:

范围:字节=-

其中
是整数。例如,如果有人希望从文件中间得到64K:

范围:字节=32768-98304


您必须将文本解析为数字并进行相应处理。

请注意,范围标题语法还允许“0-500、100-1500”(多个范围)和“-500”(最后500字节)之类的内容。请参见RFC 2616了解血淋淋的详细信息,此处无法引用。

基于@brent keller评论中链接到上面的博文,该博文反过来引用了a-I提出的以下编辑。它通过FDM(可用)进行测试。目前还不支持多范围请求。不需要
Web.config
条目

CodePlex的原始方法包含一个错误,
接受范围
头的值应仅为
字节
,而不是要返回的字节范围。属于
内容范围
标题的。下载仍然有效,但如果你犯了这个错误,你将无法获得

为了简洁易读,对这个修改过的版本进行了重构。它还有一个优点,即返回的文件不一定与实际的URL绑定,事实上,可以直接从浏览器调用处理程序,如果需要,还可以使用查询字符串参数。这将启用动态文件/数据创建和响应

希望有人能用它做些好事

HTTP处理程序

Public Class Upload
  Implements IHttpHandler

  Public Sub ProcessRequest(Context As HttpContext) Implements IHttpHandler.ProcessRequest
    Dim oFile As FileInfo

    oFile = New FileInfo(Context.Server.MapPath("~/0HCJ0LE.zip"))

    Me.UploadRange(Context, oFile)
  End Sub



  Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
    Get
      Return False
    End Get
  End Property



  Private Sub UploadRange(Context As HttpContext, File As FileInfo)
    Dim oResponse As Response
    Dim oRequest As Request

    Dim _
      nOffset,
      nLength As Long

    Using oReader As New StreamReader(File.FullName)
      Context.Response.AddHeader("Accept-Ranges", "bytes")

      oResponse = New Response(oReader)
      oRequest = New Request(oResponse, Context)

      If oRequest.HasRange Then
        If oRequest.IsMultiRange Then
          ' At the moment we only support single ranges.'
          '         * Multiple range support requires some more work'
          '         * to comply with the specifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2'
          '         *'
          '         * Multirange content must be sent with multipart/byteranges mediatype,'
          '         * (mediatype = mimetype)'
          '         * as well as a boundary header to indicate the various chunks of data.'
          ' '        
          ' (?) Shoud this be issued here, or should the first'
          ' range be used? Or should the header be ignored and'
          ' we output the whole content?'
          Me.ThrowBadRange(Context, oResponse)
        Else
          If oRequest.IsBadRange Then
            Me.ThrowBadRange(Context, oResponse)
          Else
            Context.Response.StatusCode = 206

            oResponse.Start = oRequest.Start
            oResponse.End = oRequest.End

            nOffset = oReader.BaseStream.Seek(oResponse.Start, SeekOrigin.Begin)
            nLength = oResponse.End - oResponse.Start + 1
          End If
        End If
      Else
        nOffset = 0
        nLength = oResponse.Size
      End If
    End Using

    Context.Response.ContentType = MediaTypeNames.Application.Zip
    Context.Response.AddHeader("Content-Disposition", $"attachment; filename={File.Name}")
    Context.Response.AddHeader("Content-Length", nLength)
    Context.Response.AddHeader(oResponse.HeaderName, oResponse.HeaderValue)
    Context.Response.WriteFile(File.FullName, nOffset, nLength)
    Context.Response.End()
  End Sub



  Private Sub ThrowBadRange(Context As HttpContext, Response As Response)
    Context.Response.AddHeader(Response.HeaderName, Response.HeaderValue)
    Throw New HttpException(416, "Requested range not satisfiable")
  End Sub
End Class
范围请求

Friend NotInheritable Class Request
  Public Sub New(Response As Response, Context As HttpContext)
    Me.Response = Response
    Me.Context = Context
  End Sub



  Public ReadOnly Property Start As Long
    Get
      If Me.Range(0) = String.Empty Then
        Start = Me.Response.Size - Me.Range(1)
      Else
        Start = Me.Range(0)
      End If
    End Get
  End Property



  Public ReadOnly Property [End] As Long
    Get
      If Me.Range(0) = String.Empty Then
        [End] = Me.Response.End
      Else
        If Long.TryParse(Me.Range(1), 0) Then
          [End] = Me.Range(1)
        Else
          [End] = Me.Response.Size
        End If
      End If

      [End] = Math.Min(Me.Response.End, [End])
    End Get
  End Property



  Public ReadOnly Property HasRange As Boolean
    Get
      Return String.IsNullOrEmpty(Me.Context.Request.ServerVariables(HTTP_RANGE)) = False
    End Get
  End Property



  Public ReadOnly Property IsMultiRange As Boolean
    Get
      Return Me.Context.Request.ServerVariables(HTTP_RANGE).Contains(",")
    End Get
  End Property



  Public ReadOnly Property IsBadRange As Boolean
    Get
      Return Me.Start > Me.End OrElse Me.Start > Me.Response.Size - 1 OrElse Me.End >= Me.Response.Size
    End Get
  End Property



  Private ReadOnly Property Range As List(Of String)
    Get
      Return Me.Context.Request.ServerVariables(HTTP_RANGE).Split("=")(1).Split("-").ToList
    End Get
  End Property



  Private ReadOnly Response As Response
  Private ReadOnly Context As HttpContext

  Private Const HTTP_RANGE As String = "HTTP_RANGE"
End Class
范围响应

Friend NotInheritable Class Response
  Public Sub New(Reader As StreamReader)
    _Size = Reader.BaseStream.Length
    Me.End = Me.Size - 1
  End Sub



  Public Property Start As Long
  Public Property [End] As Long
  Public ReadOnly Property Size As Long



  Public ReadOnly Property HeaderName As String
    Get
      Return "Content-Range"
    End Get
  End Property



  Public ReadOnly Property HeaderValue() As String
    Get
      Return $"bytes {Me.Start}-{Me.End}/{Me.Size}"
    End Get
  End Property
End Class

回答得好。为了子孙后代的利益,一点示例代码就好了。一旦我实现了它,我希望您不介意我将它注入到您的答案中。@Larsenal:我没有提供示例代码,因为我没有任何示例代码。我记得几年前就开始使用它了,但代码早已不存在了。希望我的简短描述足以让你开始。我不介意你在我的answer.FWIW中插入代码,这让我找到了下面的帖子,其中的代码展示了如何处理远程请求: