【问题标题】:powershell HttpListener http file serverpowershell HttpListener http文件服务器
【发布时间】:2017-08-23 12:41:55
【问题描述】:

我正在尝试创建一个基本的 Powershell 脚本来通过 http 共享文件,我从互联网上找到的一些示例中复制了代码。 我的代码或多或少是这样的:

$listener = New-Object Net.HttpListener
$listener.Prefixes.Add("http://+:8000/")
$listener.Start()

$response.Headers.Add("Content-Type","text/plain")
$buffer = [Text.Encoding]::UTF8.GetBytes((GC (Join-Path $Pwd ($context.Request).RawUrl)))
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.Close()
$Context.Response.Close()
$listener.Stop()

我能够获取该文件,但它没有下载为二进制文件,例如当我尝试下载 Zip 文件时,新/下载的文件比原始文件大。我猜这已经转换成ascii了。 如何保留原始文件格式?

我想我应该替换以下几行,但哪些是正确的,可以让我以二进制格式获取文件?

$response.Headers.Add("Content-Type","text/plain")
$buffer = [Text.Encoding]::UTF8.GetBytes((GC (Join-Path $Pwd ($context.Request).RawUrl)))

我只有一个有一个基本的 http 文件服务器来允许我获取一些 'zip'、'iso' 文件..

提前致谢。

【问题讨论】:

  • 我认为这是因为如果响应标头中的内容类型:您将其设置为 text/plain。要使用二进制表示,请将其设置为 application/octet-stream

标签: .net file powershell http httplistener


【解决方案1】:

您不应该使用GC 来读取文件内容。 GC(Get-Content) 用于读取带有指定编码选项的文本文件。

使用FileStream 或其他读取二进制文件内容的人。

【讨论】:

  • 替换 $HRes.Headers.Add("Content-Type","text/plain") $Buf = [Text.Encoding]::UTF8.GetBytes((GC -Encoding Unknown (加入路径 $Pwd ($HC.Request).RawUrl))) 通过这一行? $Buf = [System.IO.File]::ReadAllBytes((Join-Path $Pwd ($HC.Request).RawUrl) )
  • 从版本 6 开始,您可以使用 GC 和 -AsByteStream
  • 或者你可以使用[System.IO.File]::OpenRead
【解决方案2】:

好的,这对于一个答案来说太过分了,但是提问者没有发布可用的代码,我不知道如何使用 HttpListener 制作 PowerShell 文件服务器。因此,下面是使用 HttpListener 制作工作的 Powershell 文件服务器的示例代码。最终,原始问题的答案是ContentType="application/octet-stream"。这会将通用二进制数据传递给请求者。

$VerbosePreference="Continue"
Clear-Host
$Continue=$true
$Listener=[System.Net.HttpListener]::new()
$Listener.Prefixes.Add("http://+:80/")
$Listener.Start()
while ($Continue) {
  $Context=$Listener.GetContext()
  Write-Verbose $Context.Request.RawUrl
  if ($Context.Request.QueryString.HasKeys()) {
    $Continue=$false
    $Context.Request.QueryString.Keys | ForEach-Object { "$_ = $($Context.Request.QueryString.GetValues("$_"))" }
  }
  else {
    if ($Context.Request.Url.Segments.Count -eq 1) {
      $Content=[System.Text.Encoding]::UTF8.GetBytes("<html><body>Hello World</body></html>")
      $Context.Response.ContentType="text/html"
      $Context.Response.ContentEncoding=[System.Text.Encoding]::UTF8
      $Context.Response.ContentLength64=$Content.Length
      $Context.Response.KeepAlive=$false
      $Context.Response.StatusCode=200
      $Context.Response.StatusDescription="OK"
      $Context.Response.OutputStream.Write($Content, 0, $Content.Length)
      $Context.Response.OutputStream.Close()
      $Context.Response.Close()
    }
    else {
      if ($Context.Request.Url.LocalPath.EndsWith(".zip")) { $Context.Response.ContentType="application/octet-stream" }
      else { $Context.Response.ContentType="text/plain" }
      if (Test-Path -Path ("C:"+$Context.Request.Url.LocalPath.Replace("/","\"))) {
        $Content=Get-Content -Encoding Byte -Path ("C:"+$Context.Request.Url.LocalPath.Replace("/","\"))
        $Context.Response.ContentEncoding=[System.Text.Encoding]::Default
        $Context.Response.ContentLength64=$Content.Length
        $Context.Response.KeepAlive=$false
        $Context.Response.StatusCode=200
        $Context.Response.StatusDescription="OK"
        $Context.Response.OutputStream.Write($Content, 0, $Content.Length)
        $Context.Response.OutputStream.Close()
        $Context.Response.Close()
      }
      else {
        Write-Warning "File not found."
        $Content=[System.Text.Encoding]::UTF8.GetBytes("<html><body>File not found.</body></html>")
        $Context.Response.ContentType="text/html"
        $Context.Response.ContentEncoding=[System.Text.Encoding]::UTF8
        $Context.Response.ContentLength64=$Content.Length
        $Context.Response.KeepAlive=$false
        $Context.Response.StatusCode=404
        $Context.Response.StatusDescription="File not found"
        $Context.Response.OutputStream.Write($Content, 0, $Content.Length)
        $Context.Response.OutputStream.Close()
        $Context.Response.Close()
      }
    }
  }
}
$Listener.Stop()

#http://localhost/
#http://localhost/temp/filename.zip
#http://localhost/temp/filename.txt.log
#http://localhost/?x=y  # This (or something like it) will make the listener quit.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多