一些背景知识: 我试图" port" Windows Phone的Android应用程序,用于调用非开放式Web API。由于API未打开或记录,我使用Fiddler,运行应用程序的Android版本,并窥探它所做的API调用。
我使用Windows.Web.Http.HttpClient作为首选类,因为看起来这将是继续运行的类,而不是System.Net.Http.HttpClient。
这是我用来生成HTTP POST请求的C#代码摘录:
HttpBaseProtocolFilter _httpFilter = new HttpBaseProtocolFilter();
HttpClient _httpClient = new HttpClient(_httpFilter);
_httpClient.DefaultRequestHeaders.AcceptEncoding.Clear();
_httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/xml");
_httpClient.DefaultRequestHeaders.AcceptLanguage.TryParseAdd("en");
_httpClient.DefaultRequestHeaders.Connection.TryParseAdd("Keep-Alive");
_httpClient.DefaultRequestHeaders.Add("message-version", "1");
_httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd("Android|SAMSUNG- SGH-I337|3.3.1");
_httpClient.DefaultRequestHeaders.Cookie.TryParseAdd(cookie); //Some cookie values
Uri uri = new Uri(SOMEURI);
XDocument xd = new XDocument(STUFF_TO_BUILD_XML);
string xd_str = string.Concat(xd.Declaration.ToString(), xd.ToString());
xd_str = xd_str.Replace("\r\n", string.Empty);
xd_str = xd_str.Replace(" ", string.Empty);
HttpRequestMessage req_msg = new HttpRequestMessage(HttpMethod.Post, uri);
HttpStringContent strcnt = new HttpStringContent(xd_str);
req_msg.Content = strcnt;
req_msg.Content.Headers.ContentType = new Windows.Web.Http.Headers.HttpMediaTypeHeaderValue("text/xml; charset=UTF-8");
req_msg.Headers.Host = new Windows.Networking.HostName(SOMEHOSTNAME);
HttpResponseMessage rsp_msg = await _httpClient.SendRequestAsync(req_msg);
这是Fiddler在使用我的代码进行API调用时看到的原始文本:
POST <HTTPS endpoint> HTTP/1.1
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Host: <hostname>
Cookie2: Version=1
Accept: application/xml
message-version: 1
User-Agent: Android|SAMSUNG-SGH-I337|3.3.1
Accept-Language: en
Content-Length: 173
Content-Type: text/xml; charset=UTF-8
Cache-Control: no-cache
Cookie: STR1=VAL1; STR2=VAL2
<MESSAGE_IN_XML>
--Response--
HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1
X-Frame-Options: SAMEORIGIN
Transfer-Encoding: chunked
Date: Fri, 03 Apr 2015 01:18:07 GMT
0
这是Fiddler通过Android应用程序发出请求时看到的原始文本:
POST <HTTPS endpoint> HTTP/1.1
Content-Type: text/xml; charset=UTF-8
Connection: Keep-Alive
accept: application/xml
user-agent: Android|SAMSUNG-SGH-I337|3.4
message-version: 1
Accept-Language: en
Content-Length: 173
Host: <hostname>
Cookie: STR1=VAL1; STR2=VAL2
Cookie2: $Version=1
<MESSAGE_IN_XML>
--response--
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1
X-Frame-Options: SAMEORIGIN
Content-Type: application/xml;charset=utf-8
Date: Fri, 03 Apr 2015 01:08:22 GMT
Content-Length: 364
<MESSAGE_IN_XML>
从Fiddler的输出看,我看到的唯一区别是标题,Accept-Encoding和Cache-Control条目。有没有办法不发送它们?或者我在这里遗漏了什么?
答案 0 :(得分:0)
您应该发送授权标题。
示例:Authorization: Basic àaaaaaaa
这将解决未经授权的问题。
说明:
我们有多种方法可以保护向公众提供的服务。最常用的方法是通过授权标头将凭证从客户端应用程序传递到目标应用程序。
客户端将授权标头添加到请求中。在C#中,我们通常使用AuthenticationHeaderValue
样品可以在这里找到。
答案 1 :(得分:0)
我同意Saravanan的分析,问题“似乎”与请求的授权有关,但是,你问的是如何禁用一些标题(我不打算判断是否这个没有关于你正在做什么的更多背景是“正确的”,所以......
你可以通过使用继承创建自己的版本来“捏造”HttpClient类,因为我无法在System.Net.Http.HttpClient本身中看到任何代码(即使在.NET参考源中,奇怪)我必须使用一些技巧创建我自己的版本(实例化基类对象,然后使用基于密封的HttpRequestHeaders类创建的第二个自定义类来分配值)。
将此类添加到项目中,然后您将要使用MyHttpClient替换代码中的HttpClient引用...以下是可用于删除这些头的类(Accept-Encoding和Cache-Control),我已经在Fiddler中进行了测试,仔细检查它的工作原理:
public class MyHttpClient : HttpClient
{
public MyHttpClient(HttpClientHandler handler) : base(handler) {
DefaultRequestHeaders = new MyHttpRequestHeaders();
}
//
// Summary:
// Gets or Sets the headers which should be sent with each request.
//
// Returns:
// Returns The headers which should
// be sent with each request.
public new MyHttpRequestHeaders DefaultRequestHeaders { get; set; }
}
public class MyHttpRequestHeaders : HttpHeaders
{
public MyHttpRequestHeaders()
{
HttpClient client = new HttpClient();
this.Accept = client.DefaultRequestHeaders.Accept;
this.AcceptCharset = client.DefaultRequestHeaders.AcceptCharset;
this.AcceptLanguage = client.DefaultRequestHeaders.AcceptLanguage;
this.Authorization = client.DefaultRequestHeaders.Authorization;
this.Connection = client.DefaultRequestHeaders.Connection;
this.ConnectionClose = client.DefaultRequestHeaders.ConnectionClose;
this.Date = client.DefaultRequestHeaders.Date;
this.Expect = client.DefaultRequestHeaders.Expect;
this.ExpectContinue = client.DefaultRequestHeaders.ExpectContinue;
this.From = client.DefaultRequestHeaders.From;
this.Host = client.DefaultRequestHeaders.Host;
this.IfMatch = client.DefaultRequestHeaders.IfMatch;
this.IfModifiedSince = client.DefaultRequestHeaders.IfModifiedSince;
this.IfNoneMatch = client.DefaultRequestHeaders.IfNoneMatch;
this.IfRange = client.DefaultRequestHeaders.IfRange;
this.IfUnmodifiedSince = client.DefaultRequestHeaders.IfUnmodifiedSince;
this.MaxForwards = client.DefaultRequestHeaders.MaxForwards;
this.Pragma = client.DefaultRequestHeaders.Pragma;
this.ProxyAuthorization = client.DefaultRequestHeaders.ProxyAuthorization;
this.Range = client.DefaultRequestHeaders.Range;
this.Referrer = client.DefaultRequestHeaders.Referrer;
this.TE = client.DefaultRequestHeaders.TE;
this.Trailer = client.DefaultRequestHeaders.Trailer;
this.TransferEncoding = client.DefaultRequestHeaders.TransferEncoding;
this.TransferEncodingChunked = client.DefaultRequestHeaders.TransferEncodingChunked;
this.Upgrade = client.DefaultRequestHeaders.Upgrade;
this.UserAgent = client.DefaultRequestHeaders.UserAgent;
this.Via = client.DefaultRequestHeaders.Via;
this.Warning = client.DefaultRequestHeaders.Warning;
}
// Summary:
// Gets the value of the Accept header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the Accept header for an HTTP request.
public HttpHeaderValueCollection<MediaTypeWithQualityHeaderValue> Accept { get; set; }
//
// Summary:
// Gets the value of the Accept-Charset header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the Accept-Charset header for an HTTP request.
public HttpHeaderValueCollection<StringWithQualityHeaderValue> AcceptCharset { get; set; }
//
// Summary:
// Gets the value of the Accept-Language header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the Accept-Language header for an HTTP request.
public HttpHeaderValueCollection<StringWithQualityHeaderValue> AcceptLanguage { get; set; }
//
// Summary:
// Gets or sets the value of the Authorization header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.AuthenticationHeaderValue.The value of the
// Authorization header for an HTTP request.
public AuthenticationHeaderValue Authorization { get; set; }
//
// Summary:
// Gets the value of the Connection header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the Connection header for an HTTP request.
public HttpHeaderValueCollection<string> Connection { get; set; }
//
// Summary:
// Gets or sets a value that indicates if the Connection header for an HTTP
// request contains Close.
//
// Returns:
// Returns System.Boolean.true if the Connection header contains Close, otherwise
// false.
public bool? ConnectionClose { get; set; }
//
// Summary:
// Gets or sets the value of the Date header for an HTTP request.
//
// Returns:
// Returns System.DateTimeOffset.The value of the Date header for an HTTP request.
public DateTimeOffset? Date { get; set; }
//
// Summary:
// Gets the value of the Expect header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the Expect header for an HTTP request.
public HttpHeaderValueCollection<NameValueWithParametersHeaderValue> Expect { get; set; }
//
// Summary:
// Gets or sets a value that indicates if the Expect header for an HTTP request
// contains Continue.
//
// Returns:
// Returns System.Boolean.true if the Expect header contains Continue, otherwise
// false.
public bool? ExpectContinue { get; set; }
//
// Summary:
// Gets or sets the value of the From header for an HTTP request.
//
// Returns:
// Returns System.String.The value of the From header for an HTTP request.
public string From { get; set; }
//
// Summary:
// Gets or sets the value of the Host header for an HTTP request.
//
// Returns:
// Returns System.String.The value of the Host header for an HTTP request.
public string Host { get; set; }
//
// Summary:
// Gets the value of the If-Match header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the If-Match header for an HTTP request.
public HttpHeaderValueCollection<EntityTagHeaderValue> IfMatch { get; set; }
//
// Summary:
// Gets or sets the value of the If-Modified-Since header for an HTTP request.
//
// Returns:
// Returns System.DateTimeOffset.The value of the If-Modified-Since header for
// an HTTP request.
public DateTimeOffset? IfModifiedSince { get; set; }
//
// Summary:
// Gets the value of the If-None-Match header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.Gets the value
// of the If-None-Match header for an HTTP request.
public HttpHeaderValueCollection<EntityTagHeaderValue> IfNoneMatch { get; set; }
//
// Summary:
// Gets or sets the value of the If-Range header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.RangeConditionHeaderValue.The value of the
// If-Range header for an HTTP request.
public RangeConditionHeaderValue IfRange { get; set; }
//
// Summary:
// Gets or sets the value of the If-Unmodified-Since header for an HTTP request.
//
// Returns:
// Returns System.DateTimeOffset.The value of the If-Unmodified-Since header
// for an HTTP request.
public DateTimeOffset? IfUnmodifiedSince { get; set; }
//
// Summary:
// Gets or sets the value of the Max-Forwards header for an HTTP request.
//
// Returns:
// Returns System.Int32.The value of the Max-Forwards header for an HTTP request.
public int? MaxForwards { get; set; }
//
// Summary:
// Gets the value of the Pragma header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the Pragma header for an HTTP request.
public HttpHeaderValueCollection<NameValueHeaderValue> Pragma { get; set; }
//
// Summary:
// Gets or sets the value of the Proxy-Authorization header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.AuthenticationHeaderValue.The value of the
// Proxy-Authorization header for an HTTP request.
public AuthenticationHeaderValue ProxyAuthorization { get; set; }
//
// Summary:
// Gets or sets the value of the Range header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.RangeHeaderValue.The value of the Range header
// for an HTTP request.
public RangeHeaderValue Range { get; set; }
//
// Summary:
// Gets or sets the value of the Referer header for an HTTP request.
//
// Returns:
// Returns System.Uri.The value of the Referer header for an HTTP request.
public Uri Referrer { get; set; }
//
// Summary:
// Gets the value of the TE header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the TE header for an HTTP request.
public HttpHeaderValueCollection<TransferCodingWithQualityHeaderValue> TE { get; set; }
//
// Summary:
// Gets the value of the Trailer header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the Trailer header for an HTTP request.
public HttpHeaderValueCollection<string> Trailer { get; set; }
//
// Summary:
// Gets the value of the Transfer-Encoding header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the Transfer-Encoding header for an HTTP request.
public HttpHeaderValueCollection<TransferCodingHeaderValue> TransferEncoding { get; set; }
//
// Summary:
// Gets or sets a value that indicates if the Transfer-Encoding header for an
// HTTP request contains chunked.
//
// Returns:
// Returns System.Boolean.true if the Transfer-Encoding header contains chunked,
// otherwise false.
public bool? TransferEncodingChunked { get; set; }
//
// Summary:
// Gets the value of the Upgrade header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the Upgrade header for an HTTP request.
public HttpHeaderValueCollection<ProductHeaderValue> Upgrade { get; set; }
//
// Summary:
// Gets the value of the User-Agent header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the User-Agent header for an HTTP request.
public HttpHeaderValueCollection<ProductInfoHeaderValue> UserAgent { get; set; }
//
// Summary:
// Gets the value of the Via header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the Via header for an HTTP request.
public HttpHeaderValueCollection<ViaHeaderValue> Via { get; set; }
//
// Summary:
// Gets the value of the Warning header for an HTTP request.
//
// Returns:
// Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of
// the Warning header for an HTTP request.
public HttpHeaderValueCollection<WarningHeaderValue> Warning { get; set; }
}