Answered by:
How to use AuthenticationHeaderValue class ?

Question
-
Follow is the code for desktop:
httpRequest = WebRequest.Create(rUrl); httpRequest.Method = "POST"; string auth = "signature_method=\"HMAC-SHA1\",timestamp=\"1333929600000\",nonce=\"1333929600000\",signature=\"d8exTxj2Cin%2FY%2Bix75OCeQMFT%2Bc%3D\""; httpRequest.Headers.Add("Authorization", auth);
I try to do the same in the Metrol, like follows:
auth = "signature_method=\"HMAC-SHA1\",timestamp=\"1333929600000\",nonce=\"1333929600000\",signature=\"d8exTxj2Cin%2FY%2Bix75OCeQMFT%2Bc%3D\""; HttpClient client = new HttpClient(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url); request.Headers.Authorization = AuthenticationHeaderValue.Parse("Authorization " + auth);
But the server always gives me authorize failure.
How to reslove the problem ?
Ray_ni
Monday, April 9, 2012 3:13 AM
Answers
-
Hi Ray,
try
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization",auth); var result = await client.PostAsync(uri,content);
Thanks! Damon.Tian
- Marked as answer by NMG1852951 Wednesday, April 11, 2012 2:00 AM
Monday, April 9, 2012 5:26 AM -
Well, I get what I want with follow class:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Http; using System.Threading.Tasks; using Windows.Networking; using Windows.Networking.Sockets; using Windows.Storage.Streams; namespace Metrol { class SimpleHttps { // default port for HTTPS protocal private const int SERVER_PORT = 443; private HttpMethod _method = HttpMethod.Post; /// <summary> /// Get or set the http action /// </summary> public HttpMethod Method { get { return _method; } set { _method = value; } } private Dictionary<string, string> _headers; /// <summary> /// Get http headers /// </summary> public Dictionary<string, string> Headers { get { return _headers; } } private string _serverUrl; /// <summary> /// Get or set server url /// </summary> public string Server { get { return _serverUrl; } set { if (!value.StartsWith("https://")) throw new Exception(value + "is not a HTTPS server"); _serverUrl = value; } } private string _content; /// <summary> /// Get or set conent which would be send to server /// </summary> public string Content { get { return _content; } set { _content = value; } } private SimpleHttps _response; /// <summary> /// Get the response from server /// </summary> public SimpleHttps Response { get { return _response; } } private SimpleHttps _request; /// <summary> /// Get the resquest to server /// </summary> public SimpleHttps Request { get { return _request; } } private int _stateCode = 0; /// <summary> /// Get the state code for response /// <br /> only avaible when this instance is response /// </summary> public int StateCode { get { return _stateCode; } } /// <summary> /// construct /// </summary> public SimpleHttps() { _headers = new Dictionary<string, string>(); } /// <summary> /// use when get the response /// </summary> /// <param name="request"></param> private SimpleHttps(SimpleHttps request) { _request = request; _headers = new Dictionary<string, string>(); } /// <summary> /// send request and get the response /// </summary> /// <returns></returns> public async Task<SimpleHttps> DoWorkAsync() { if (_serverUrl != null) { int index = _serverUrl.IndexOf('/', 8); if(index >0) { string host = _serverUrl.Substring(8, index - 8); string location = _serverUrl.Substring(index); //prepear the http headers StringBuilder data = new StringBuilder(); data.AppendFormat("{0} {1} HTTP/1.1\r\n", _method.Method, location); data.AppendFormat("Host: {0}\r\n", host); data.Append("Connection: Keep-Alive\r\n"); data.Append("Expect: 100-continue\r\n"); foreach (KeyValuePair<string, string> pair in _headers) { data.AppendFormat("{0}: {1}\r\n", pair.Key, pair.Value); } data.AppendFormat("Content-Length: {0}\r\n\r\n{1}", Encoding.UTF8.GetByteCount(_content), _content); //connect to server StreamSocket socket = new StreamSocket(); await socket.ConnectAsync(new HostName(host), SERVER_PORT.ToString(), SocketProtectionLevel.SslAllowNullEncryption); DataWriter writer = new DataWriter(socket.OutputStream); DataReader reader = new DataReader(socket.InputStream); reader.InputStreamOptions = InputStreamOptions.Partial; //write http headers and content string temp = data.ToString(); writer.WriteString(temp); await writer.StoreAsync(); // new the response _response = new SimpleHttps(this); //read the replay await _response.ReadHeadersAsync(reader); //read content await _response.ReadContentAsync(reader); return _response; } } return null; } /// <summary> /// reader header include stata code and http headers /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task ReadHeadersAsync(DataReader reader) { // read "HTTP/1.1 XXX" string stateCode = await reader.ReadMyString(12); _stateCode = int.Parse(stateCode.Substring(9, 3)); switch (_stateCode) { case 100: // read " Continue\r\n\r\n" await reader.ReadMyString(13); await ReadHeadersAsync(reader); break; case 200: // read " OK\r\n" await reader.ReadMyString(5); await ReadHttpHeadersAsync(reader); break; default: // just support 100 and 200 // because this class is simple as its name break; } } /// <summary> /// read http headers /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task ReadHttpHeadersAsync(DataReader reader) { string key, value; while (true) { key = await ReadKeyAsync(reader); if (key == null)//head is over break; value = await ReadValueAsync(reader); _headers.Add(key.Trim(), value.Trim()); } } /// <summary> /// read key in one httpHeader /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task<string> ReadKeyAsync(DataReader reader) { StringBuilder key = new StringBuilder(); byte oneByte = await reader.ReadMyByte(); // head is over if (oneByte == '\r') { oneByte = await reader.ReadMyByte(); if (oneByte == '\n') return null; } // read until meet the ":" while (oneByte != ':') { key.Append((char)oneByte); oneByte = await reader.ReadMyByte(); } return key.ToString(); } /// <summary> /// read value in one HttpHeader /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task<string> ReadValueAsync(DataReader reader) { StringBuilder value = new StringBuilder(); byte oneByte = await reader.ReadMyByte(); // read until meet the "\r\n" while (true) { if (oneByte == '\r') { oneByte = await reader.ReadMyByte(); if (oneByte == '\n') break; } value.Append((char)oneByte); oneByte = await reader.ReadMyByte(); } return value.ToString(); } /// <summary> /// read the content /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task ReadContentAsync(DataReader reader) { if (_headers.ContainsKey("Transfer-Encoding")) { if (_headers["Transfer-Encoding"].ToLower().Equals("chunked")) { StringBuilder content = new StringBuilder(); uint length = await ReadIntAsync(reader); while (length > 0) { content.Append(await reader.ReadMyString(length)); // read "\r\n" reader.ReadMyString(2); // read next length length = await ReadIntAsync(reader); } _content = content.ToString(); return; } } if (_headers.ContainsKey("Content-Length")) { uint length = Convert.ToUInt32(_headers["Content-Length"]); _content = await reader.ReadMyString(length); } } /// <summary> /// read an int /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task<uint> ReadIntAsync(DataReader reader) { string value = ""; byte oneByte = await reader.ReadMyByte(); while(oneByte != '\r') { value += (char)oneByte; oneByte = await reader.ReadMyByte(); } oneByte = await reader.ReadMyByte(); return Convert.ToUInt32(value,16); } } /// <summary> /// extends the DataReader to speed the small data read /// </summary> static class DataReaderExtension { public static async Task<string> ReadMyString(this DataReader reader, uint length) { while (length > reader.UnconsumedBufferLength) { await reader.LoadAsync(1024); } return reader.ReadString(length); } public static async Task<byte> ReadMyByte(this DataReader reader) { while (reader.UnconsumedBufferLength == 0) { await reader.LoadAsync(1024); } return reader.ReadByte(); } public static async Task<byte[]> ReadMyBytes(this DataReader reader, uint length) { while (length > reader.UnconsumedBufferLength) { await reader.LoadAsync(1024); } byte[] buffer = new byte[length]; reader.ReadBytes(buffer); return buffer; } } }
Ray_ni
- Marked as answer by NMG1852951 Wednesday, April 11, 2012 2:00 AM
Wednesday, April 11, 2012 1:54 AM
All replies
-
Hi Ray,
try
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization",auth); var result = await client.PostAsync(uri,content);
Thanks! Damon.Tian
- Marked as answer by NMG1852951 Wednesday, April 11, 2012 2:00 AM
Monday, April 9, 2012 5:26 AM -
Thanks for your help !
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization",auth); var result = await client.PostAsync(uri,content);
But it does not work.
There is a possible issue which trouble me: the HttpClient class does not support HTTPS website, but the website I want to access is an HTTPS one.
May someone can tell me something about it ?
Ray_ni
Monday, April 9, 2012 7:44 AM -
Well, HttpClient class may be support HTTPS, because I can use it to get access token from https://login.live.com/accesstoken.srf
var urlEncodedSid = WebUtility.UrlEncode(String.Format("{0}", this.sid)); var urlEncodedSecret = WebUtility.UrlEncode(this.secret); var body = String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com", urlEncodedSid, urlEncodedSecret); var client = new HttpClient(); StringContent content = new StringContent(body); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded"); var response = await client.PostAsync("https://login.live.com/accesstoken.srf", content); string result = await response.Content.ReadAsStringAsync();
But MS worker told me HttpClient does not supports HTTPS in a letter.Ray_ni
Monday, April 9, 2012 8:00 AM -
Another Problem, Why I can not add "Authorization" header with HttpContent.Headers.Add(string, string) API ?
It throws an exception : InvalidOperationException "Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects."
Ray_ni
- Edited by NMG1852951 Monday, April 9, 2012 8:06 AM
Monday, April 9, 2012 8:06 AM -
Well, I get what I want with follow class:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Http; using System.Threading.Tasks; using Windows.Networking; using Windows.Networking.Sockets; using Windows.Storage.Streams; namespace Metrol { class SimpleHttps { // default port for HTTPS protocal private const int SERVER_PORT = 443; private HttpMethod _method = HttpMethod.Post; /// <summary> /// Get or set the http action /// </summary> public HttpMethod Method { get { return _method; } set { _method = value; } } private Dictionary<string, string> _headers; /// <summary> /// Get http headers /// </summary> public Dictionary<string, string> Headers { get { return _headers; } } private string _serverUrl; /// <summary> /// Get or set server url /// </summary> public string Server { get { return _serverUrl; } set { if (!value.StartsWith("https://")) throw new Exception(value + "is not a HTTPS server"); _serverUrl = value; } } private string _content; /// <summary> /// Get or set conent which would be send to server /// </summary> public string Content { get { return _content; } set { _content = value; } } private SimpleHttps _response; /// <summary> /// Get the response from server /// </summary> public SimpleHttps Response { get { return _response; } } private SimpleHttps _request; /// <summary> /// Get the resquest to server /// </summary> public SimpleHttps Request { get { return _request; } } private int _stateCode = 0; /// <summary> /// Get the state code for response /// <br /> only avaible when this instance is response /// </summary> public int StateCode { get { return _stateCode; } } /// <summary> /// construct /// </summary> public SimpleHttps() { _headers = new Dictionary<string, string>(); } /// <summary> /// use when get the response /// </summary> /// <param name="request"></param> private SimpleHttps(SimpleHttps request) { _request = request; _headers = new Dictionary<string, string>(); } /// <summary> /// send request and get the response /// </summary> /// <returns></returns> public async Task<SimpleHttps> DoWorkAsync() { if (_serverUrl != null) { int index = _serverUrl.IndexOf('/', 8); if(index >0) { string host = _serverUrl.Substring(8, index - 8); string location = _serverUrl.Substring(index); //prepear the http headers StringBuilder data = new StringBuilder(); data.AppendFormat("{0} {1} HTTP/1.1\r\n", _method.Method, location); data.AppendFormat("Host: {0}\r\n", host); data.Append("Connection: Keep-Alive\r\n"); data.Append("Expect: 100-continue\r\n"); foreach (KeyValuePair<string, string> pair in _headers) { data.AppendFormat("{0}: {1}\r\n", pair.Key, pair.Value); } data.AppendFormat("Content-Length: {0}\r\n\r\n{1}", Encoding.UTF8.GetByteCount(_content), _content); //connect to server StreamSocket socket = new StreamSocket(); await socket.ConnectAsync(new HostName(host), SERVER_PORT.ToString(), SocketProtectionLevel.SslAllowNullEncryption); DataWriter writer = new DataWriter(socket.OutputStream); DataReader reader = new DataReader(socket.InputStream); reader.InputStreamOptions = InputStreamOptions.Partial; //write http headers and content string temp = data.ToString(); writer.WriteString(temp); await writer.StoreAsync(); // new the response _response = new SimpleHttps(this); //read the replay await _response.ReadHeadersAsync(reader); //read content await _response.ReadContentAsync(reader); return _response; } } return null; } /// <summary> /// reader header include stata code and http headers /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task ReadHeadersAsync(DataReader reader) { // read "HTTP/1.1 XXX" string stateCode = await reader.ReadMyString(12); _stateCode = int.Parse(stateCode.Substring(9, 3)); switch (_stateCode) { case 100: // read " Continue\r\n\r\n" await reader.ReadMyString(13); await ReadHeadersAsync(reader); break; case 200: // read " OK\r\n" await reader.ReadMyString(5); await ReadHttpHeadersAsync(reader); break; default: // just support 100 and 200 // because this class is simple as its name break; } } /// <summary> /// read http headers /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task ReadHttpHeadersAsync(DataReader reader) { string key, value; while (true) { key = await ReadKeyAsync(reader); if (key == null)//head is over break; value = await ReadValueAsync(reader); _headers.Add(key.Trim(), value.Trim()); } } /// <summary> /// read key in one httpHeader /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task<string> ReadKeyAsync(DataReader reader) { StringBuilder key = new StringBuilder(); byte oneByte = await reader.ReadMyByte(); // head is over if (oneByte == '\r') { oneByte = await reader.ReadMyByte(); if (oneByte == '\n') return null; } // read until meet the ":" while (oneByte != ':') { key.Append((char)oneByte); oneByte = await reader.ReadMyByte(); } return key.ToString(); } /// <summary> /// read value in one HttpHeader /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task<string> ReadValueAsync(DataReader reader) { StringBuilder value = new StringBuilder(); byte oneByte = await reader.ReadMyByte(); // read until meet the "\r\n" while (true) { if (oneByte == '\r') { oneByte = await reader.ReadMyByte(); if (oneByte == '\n') break; } value.Append((char)oneByte); oneByte = await reader.ReadMyByte(); } return value.ToString(); } /// <summary> /// read the content /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task ReadContentAsync(DataReader reader) { if (_headers.ContainsKey("Transfer-Encoding")) { if (_headers["Transfer-Encoding"].ToLower().Equals("chunked")) { StringBuilder content = new StringBuilder(); uint length = await ReadIntAsync(reader); while (length > 0) { content.Append(await reader.ReadMyString(length)); // read "\r\n" reader.ReadMyString(2); // read next length length = await ReadIntAsync(reader); } _content = content.ToString(); return; } } if (_headers.ContainsKey("Content-Length")) { uint length = Convert.ToUInt32(_headers["Content-Length"]); _content = await reader.ReadMyString(length); } } /// <summary> /// read an int /// </summary> /// <param name="reader"></param> /// <returns></returns> private async Task<uint> ReadIntAsync(DataReader reader) { string value = ""; byte oneByte = await reader.ReadMyByte(); while(oneByte != '\r') { value += (char)oneByte; oneByte = await reader.ReadMyByte(); } oneByte = await reader.ReadMyByte(); return Convert.ToUInt32(value,16); } } /// <summary> /// extends the DataReader to speed the small data read /// </summary> static class DataReaderExtension { public static async Task<string> ReadMyString(this DataReader reader, uint length) { while (length > reader.UnconsumedBufferLength) { await reader.LoadAsync(1024); } return reader.ReadString(length); } public static async Task<byte> ReadMyByte(this DataReader reader) { while (reader.UnconsumedBufferLength == 0) { await reader.LoadAsync(1024); } return reader.ReadByte(); } public static async Task<byte[]> ReadMyBytes(this DataReader reader, uint length) { while (length > reader.UnconsumedBufferLength) { await reader.LoadAsync(1024); } byte[] buffer = new byte[length]; reader.ReadBytes(buffer); return buffer; } } }
Ray_ni
- Marked as answer by NMG1852951 Wednesday, April 11, 2012 2:00 AM
Wednesday, April 11, 2012 1:54 AM