Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.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
C# 检测PHP链接导致文件在c中下载#_C#_Php_File_Download_Detect - Fatal编程技术网

C# 检测PHP链接导致文件在c中下载#

C# 检测PHP链接导致文件在c中下载#,c#,php,file,download,detect,C#,Php,File,Download,Detect,我似乎找不到一个有效的答案来解决我的问题,我想知道是否有人能帮上忙。基本上,我的网站上有一个链接,可以下载zip文件: http://***.com/download.php?id=1 如果您在网页上激活此链接,它将弹出另存为对话框,并允许您使用默认名称保存文件ThisIsMyZipFile.zip 我的问题是,在c#下,如果我使用newURI(“http://***.com/download.pgp?id=1”).IsFile它返回false,因此如果不执行webclient Downloa

我似乎找不到一个有效的答案来解决我的问题,我想知道是否有人能帮上忙。基本上,我的网站上有一个链接,可以下载zip文件:

http://***.com/download.php?id=1
如果您在网页上激活此链接,它将弹出另存为对话框,并允许您使用默认名称保存文件
ThisIsMyZipFile.zip

我的问题是,在c#下,如果我使用
newURI(“http://***.com/download.pgp?id=1”).IsFile
它返回
false
,因此如果不执行
webclient DownloadString
并查看前两个字节是否为
PK
,我似乎无法检测到这是一个文件

此外,即使手动下载为字符串,检测
PK
标题并保存文件,我也无法找到我的网站想要使用的默认文件名是
ThisIsMyZipFile.zip,因为我想使用相同的文件名

有人知道解决这两个问题的好方法吗

更新

多亏了Paul和他的回答,我创建了以下函数,它正好满足了我的需要:

/// <summary>
/// Returns the responded HTTP headers of the given URL and if the link refers to the file it returns extra information about it.
/// </summary>
/// <param name="Url">The address.</param>
/// <returns>
/// null if a WebException is thrown
/// otherwise:
/// List of headers:
///     Keep-Alive          - Timeout value (i.e. timeout=2, max=100)
///     Connection          - The type of connection (i.e. Keep-Alive)
///     Transfer-Encoding   - The type of encoding used for the transfer (i.e. chunked)
///     Content-Type        - The type of Content that will be transferred (i.e. application/zip)
///     Date                - The servers date and time
///     Server              - The server that is handling the request (i.e. Apache)
///     AbsoluteUri         - The full Uri of the resulting link that will be followed.
/// The following key will be present if the link refers to a file
///     Filename            - The filename (not path) of the file that will be downloaded if the link if followed.
/// </returns>
public Dictionary<string, string> GetHTTPResponseHeaders(string Url)
{
    WebRequest WebRequestObject = HttpWebRequest.Create(Url);
    WebResponse ResponseObject = null;
    try
    {
        ResponseObject = WebRequestObject.GetResponse();
    }
    catch(WebException ex)
    {
        return null;
    }
    // Add the header inforamtion to the resulting list
    Dictionary<string, string> HeaderList = new Dictionary<string, string>();
    foreach (string HeaderKey in ResponseObject.Headers)
        HeaderList.Add(HeaderKey, ResponseObject.Headers[HeaderKey]);

    // Add the resolved Uri to the resulting list
    HeaderList.Add("AbsoluteUri", ResponseObject.ResponseUri.AbsoluteUri);

    // If this is a zip file then add the download filename specified by the server to the resulting list
    if (ResponseObject.ContentType.ToLower() == "application/zip")
    {
        HeaderList.Add("Filename", ResponseObject.ResponseUri.Segments[ResponseObject.ResponseUri.Segments.Length-1]);
    }

    // We are now finished with our response object
    ResponseObject.Close();

    // Return the resulting list
    return HeaderList;
}
//
///返回给定URL的响应HTTP头,如果链接引用该文件,则返回有关该文件的额外信息。
/// 
///地址。
/// 
///如果引发WebException,则为null
///否则:
///标题列表:
///保持活动-超时值(即超时=2,最大=100)
///连接-连接类型(即保持活动)
///传输编码-用于传输的编码类型(即分块)
///内容类型-将传输的内容类型(即应用程序/zip)
///日期-服务器的日期和时间
///服务器-处理请求的服务器(即Apache)
///AbsoluteUri—将遵循的结果链接的完整Uri。
///如果链接引用文件,则会出现以下键
///Filename-如果遵循链接,将下载的文件的文件名(而不是路径)。
/// 
公共字典GetHTTPResponseHeaders(字符串Url)
{
WebRequestWebRequestObject=HttpWebRequest.Create(Url);
WebResponse ResponseObject=null;
尝试
{
ResponseObject=WebRequestObject.GetResponse();
}
捕获(WebException ex)
{
返回null;
}
//将标题信息添加到结果列表中
字典标题列表=新字典();
foreach(ResponseObject.Headers中的字符串HeaderKey)
添加(HeaderKey,ResponseObject.Headers[HeaderKey]);
//将解析的Uri添加到结果列表中
添加(“AbsoluteUri”,ResponseObject.ResponseUri.AbsoluteUri);
//如果这是zip文件,则将服务器指定的下载文件名添加到结果列表中
if(ResponseObject.ContentType.ToLower()=“应用程序/zip”)
{
添加(“文件名”,ResponseObject.ResponseUri.Segments[ResponseObject.ResponseUri.Segments.Length-1]);
}
//现在,我们已经完成了响应对象
ResponseObject.Close();
//返回结果列表
返回标题列表;
}

Uri.IsFile
对Uri执行静态检查,即查看“scheme”部分(包括冒号的第一位)是否为
文件:
。它不会查看通过请求驻留在URI上的资源而返回的实际内容。(事实上,因为它实际上根本没有尝试联系服务器,所以URI实际上可能指向丢失的资源,而
IsFile
仍然可以工作。)

如果希望查看资源的内容是否属于特定类型,则必须:

  • 检索资源的HTTP头(如果是HTTP或HTTPs资源:即,如果“方案”是
    HTTP
    HTTPs
  • 检索(至少部分)资源并检查它
  • 您当前正在执行2,但是对于HTTP资源(具有HTTP URL),执行1会更干净、更便宜。您可以通过执行HTTP
    HEAD
    请求来实现这一点(与
    GET
    POST
    ,&c相反)。这将返回HTTP头,而不返回资源本身。代码将类似于:

    var request = WebRequest.Create("http://somewhere.overtherainbow.com/?a=b");
    request.Method = "HEAD";
    WebResponse response = request.GetResponse();
    //TODO check status code
    string contentType = response.ContentType;
    response.Close();
    
    内容类型将为您提供一些文件类型的指示,但是许多二进制文件将作为八位字节流返回,因此如果您希望区分不同的二进制文件类型,您可能仍然需要检索和检查资源本身的魔法字节。(不过,内容类型应该足以让您区分二进制文件和网页。)

    因此,完整的解决方案可能是:

  • 发送资源的
    GET
    请求
  • 检查响应状态以确保没有错误
  • 检查content-type头以查看是否有二进制八位字节流
  • 从响应流中读取两个字节,查看文件是否启动“PK”

  • 如果不向该URL发送HTTP请求,则绝对无法检测到给定URL会导致下载文件

    现在来看第二个问题。您可以发送HTTP请求以下载该文件,然后检查将包含文件名的内容处置标头:

    using (var client = new WebClient())
    {
        using (var stream = client.OpenRead("http://*.com/download.php?id=1"))
        {
            var disposition = client.ResponseHeaders["Content-Disposition"];
            if (disposition != null)
            {
                var cd = new ContentDisposition(disposition);
                if (!cd.Inline && !string.IsNullOrEmpty(cd.FileName))
                {
                    using (var outputStream = File.OpenWrite(cd.FileName))
                    {
                        stream.CopyTo(outputStream);
                    }
                }
            }
            else
            {
                // The web server didn't send a Content-Disposition response header
                // so we have absolutely no means of determining the filename
                // you will have to use some default value here if you want to store it
            }
        }
    }
    

    MSDN说,只有当IsFile与URI模式文件匹配时,它才是真的。瞧,谢谢保罗,这正是我所需要的。:-)