/// <summary>Creates a message representation as follows: /// HTTP method\n + /// Content-MD5\n + /// Response content type (accept header)\n + /// Canonicalized URI\n /// ISO-8601 UTC timestamp including milliseconds (e.g. 2013-09-23T09:24:43.5395441Z)\n /// Public-Key /// </summary> public string CreateMessageRepresentation(WebApiRequestContext context, string contentMd5Hash, string timestamp, bool queryStringDecode = false) { if (context == null || !context.IsValid) { return(null); } var url = context.Url; if (queryStringDecode) { var uri = new Uri(url); if (uri.Query != null && uri.Query.Length > 0) { url = string.Concat(uri.GetLeftPart(UriPartial.Path), HttpUtility.UrlDecode(uri.Query)); } } var result = string.Join(_delimiterRepresentation, context.HttpMethod.ToLower(), contentMd5Hash ?? "", context.HttpAcceptType.ToLower(), url.ToLower(), timestamp, context.PublicKey.ToLower() ); return(result); }
public HttpWebRequest StartRequest(WebApiRequestContext context, string content, Dictionary <string, object> multipartData, out StringBuilder requestContent) { requestContent = new StringBuilder(); if (context == null || !context.IsValid) { return(null); } // client system time must not be too far away from api server time! check response header. // ISO-8601 utc timestamp with milliseconds (e.g. 2013-09-23T09:24:43.5395441Z) string timestamp = DateTime.UtcNow.ToString("o"); byte[] data = null; string contentMd5Hash = ""; var request = (HttpWebRequest)WebRequest.Create(context.Url); SetTimeout(request); request.UserAgent = Program.ConsumerName; // optional request.Method = context.HttpMethod; request.Headers.Add(HttpRequestHeader.Pragma, "no-cache"); request.Headers.Add(HttpRequestHeader.CacheControl, "no-cache, no-store"); request.Accept = context.HttpAcceptType; request.Headers.Add(HttpRequestHeader.AcceptCharset, "UTF-8"); request.Headers.Add(WebApiGlobal.HeaderName.PublicKey, context.PublicKey); request.Headers.Add(WebApiGlobal.HeaderName.Date, timestamp); if (multipartData != null && multipartData.Count > 0) { var formDataBoundary = string.Format("----------{0:N}", Guid.NewGuid()); data = GetMultipartFormData(multipartData, formDataBoundary, requestContent); contentMd5Hash = CreateContentMd5Hash(data); request.ContentLength = data.Length; request.ContentType = "multipart/form-data; boundary=" + formDataBoundary; } else if (!string.IsNullOrWhiteSpace(content) && BodySupported(request.Method)) { requestContent.Append(content); data = Encoding.UTF8.GetBytes(content); contentMd5Hash = CreateContentMd5Hash(data); request.ContentLength = data.Length; request.ContentType = "application/json; charset=utf-8"; } else if (BodySupported(request.Method)) { request.ContentLength = 0; } if (!string.IsNullOrEmpty(contentMd5Hash)) { // optional... provider returns HmacResult.ContentMd5NotMatching if there's no match request.Headers.Add(HttpRequestHeader.ContentMd5, contentMd5Hash); } string messageRepresentation = CreateMessageRepresentation(context, contentMd5Hash, timestamp, true); //Debug.WriteLine(messageRepresentation); string signature = CreateSignature(context.SecretKey, messageRepresentation); request.Headers.Add(HttpRequestHeader.Authorization, CreateAuthorizationHeader(signature)); if (data != null) { using (var stream = request.GetRequestStream()) { stream.Write(data, 0, data.Length); } } requestContent.Insert(0, request.Headers.ToString()); return(request); }