加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用HttpClient异步NancyFX – fbcdn的GetAsync返回403 fo

发布时间:2020-12-15 07:46:14 所属栏目:百科 来源:网络整理
导读:注意:我已经改变了这个问题,试图让它更多地指出问题所在.以下评论不再反映这一问题. 我想从fbcdn获取这个图像: https://scontent.xx.fbcdn.net/v/t1.0-1/c15.0.50.50/p50x50/10354686_10150004552801856_220367501106153455_n.jpg?oh=6c801f82cd5a32fd6e5a
注意:我已经改变了这个问题,试图让它更多地指出问题所在.以下评论不再反映这一问题.

我想从fbcdn获取这个图像:

https://scontent.xx.fbcdn.net/v/t1.0-1/c15.0.50.50/p50x50/10354686_10150004552801856_220367501106153455_n.jpg?oh=6c801f82cd5a32fd6e5a4258ce00a314&oe=589AAD2F

浏览器得到它就好了.这是我的代码:

public class ReverseProxyController : NancyModule
{
    public ReverseProxyController()
    {
        Get["/",true] = async (parameters,ct) =>
        {
            var result = await GetResult(parameters,ct);
            return result;
        };
    }

    private async Task<Response> GetResult(dynamic parameters,CancellationToken ct)
    {
        var client = new HttpClient();
        string url = Request.Query["url"].Value.ToString();
        if (url == null) return null;

        client.DefaultRequestHeaders.Add("Access-Control-Allow-Origin","*");
        client.DefaultRequestHeaders.Add("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/54.0.2840.71 Safari/537.36");
        client.DefaultRequestHeaders.Add("Upgrade-Insecure-Requests","1");
        client.DefaultRequestHeaders.Add("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        client.DefaultRequestHeaders.Add("Accept-Encoding","gzip,deflate,sdch,br");
        client.DefaultRequestHeaders.Add("Accept-Language","en-US,en;q=0.8,ru;q=0.6");
        var response = await client.GetAsync(url,ct);

        ct.ThrowIfCancellationRequested();


        switch (response.StatusCode)
        {
            case HttpStatusCode.OK:
                var stream = await response.Content.ReadAsStreamAsync();

                return Response.FromStream(stream,response.Content.Headers.ContentType != null
                    ? response.Content.Headers.ContentType.ToString()
                    : "application/octet-stream");

            default:
                return Response.AsText("nError " + response.StatusCode);
        }
    }
}

我每次都得到403 Forbidden响应.我认为添加标题会使它工作但不会去.

此代码适用于其他主机上的其他图像,如下所示:

https://s-media-cache-ak0.pinimg.com/564x/ff/f0/c9/fff0c988a4516659d4009f60e0694cb6.jpg

解决方法

问题出在Nancy请求的URL Retrieval中,而不是使用HttpClient获取数据.

我假设您正在向南希发送请求,例如:

http://localhost/?url= …

因此对于Facebook,它将是:

http://localhost/?url=https://scontent.xx.fbcdn.net/v/t1.0-1/c15.0.50.50/p50x50/10354686_10150004552801856_220367501106153455_n.jpg?oh=6c801f82cd5a32fd6e5a4258ce00a314&oe=589AAD2F

但对于这个url字符串url = Request.Query [“url”].Value.ToString();是不完整的并且缺少最后一部分(& oe = 589AAD2F),因此服务器响应Forbidden.

以下是演示此问题的简单更改:

private async Task<Response> GetResult(dynamic parameters,CancellationToken ct)
{
    var client = new HttpClient();
    var req = Request.Url.ToString();
    var queryStart = req.IndexOf("url=");
    if (queryStart == -1)
        return Nancy.HttpStatusCode.BadRequest;

    var url = req.Substring(queryStart + 4);
    if (string.IsNullOrEmpty(url))
        return Nancy.HttpStatusCode.BadRequest;

    client.DefaultRequestHeaders.Add("Access-Control-Allow-Origin","*");
    client.DefaultRequestHeaders.Add("User-Agent",like Gecko) Chrome/54.0.2840.71 Safari/537.36");
    client.DefaultRequestHeaders.Add("Upgrade-Insecure-Requests","1");
    client.DefaultRequestHeaders.Add("Accept",*/*;q=0.8");
    client.DefaultRequestHeaders.Add("Accept-Encoding",br");
    client.DefaultRequestHeaders.Add("Accept-Language",ru;q=0.6");
    var response = await client.GetAsync(url,ct);

    ct.ThrowIfCancellationRequested();


    switch (response.StatusCode)
    {
        case System.Net.HttpStatusCode.OK:
            var stream = await response.Content.ReadAsStreamAsync();

            return Response.FromStream(stream,response.Content.Headers.ContentType != null
                ? response.Content.Headers.ContentType.ToString()
                : "application/octet-stream");

        default:
            return Response.AsText("nError " + response.StatusCode);
    }
}

我们实际上可以在发送之前对URL进行编码,Nancy将自动为我们解码URL,因此无需更改任何服务器端.

这是使用HttpUtility.UrlEncode生成的链接示例

https://scontent.xx.fbcdn.net/v/t1.0-1/c15.0.50.50/p50x50/10354686_10150004552801856_220367501106153455_n.jpg?oh=6c801f82cd5a32fd6e5a4258ce00a314&oe=589AAD2F

结果:

https://scontent.xx.fbcdn.net/v/t1.0-1/c15.0.50.50/p50x50/10354686_10150004552801856_220367501106153455_n.jpg?oh=6c801f82cd5a32fd6e5a4258ce00a314u0026oe=589AAD2F

并且对此特定链接的实际请求将是:

http://localhost:9876/?url=https%3a%2f%2fscontent.xx.fbcdn.net%2fv%2ft1.0-1%2fc15.0.50.50%2fp50x50%2f10354686_10150004552801856_220367501106153455_n.jpg%3foh%3d6c801f82cd5a32fd6e5a4258ce00a314%26oe%3d589AAD2F

替代解决方案

在这种情况下我个人更喜欢POST而不是GET,所以这里是:

public class ReverseProxyController : NancyModule
{
    class ProxyRequest
    {
        public string Url { get; set; }
    }

    public ReverseProxyController()
    {
        Post["/",CancellationToken ct)
    {
        var pReq = this.Bind<ProxyRequest>();
        var url = pReq.Url;
        if (string.IsNullOrEmpty(url))
            return null;

        var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Access-Control-Allow-Origin",ct);

        ct.ThrowIfCancellationRequested();


        switch (response.StatusCode)
        {
            case System.Net.HttpStatusCode.OK:
                var stream = await response.Content.ReadAsStreamAsync();

                return Response.FromStream(stream,response.Content.Headers.ContentType != null
                    ? response.Content.Headers.ContentType.ToString()
                    : "application/octet-stream");

            default:
                return Response.AsText("nError " + response.StatusCode);
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读