/// <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 void AddApiFileParameter(Dictionary<string, object> multipartData, string filePath, int pictureId) //{ // var count = 0; // var paths = filePath.Contains(";") ? filePath.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList() : new List<string> { filePath }; // foreach (var path in paths) // { // using (var fstream = new FileStream(path, FileMode.Open, FileAccess.Read)) // { // byte[] data = new byte[fstream.Length]; // fstream.Read(data, 0, data.Length); // var name = Path.GetFileName(path); // var id = string.Format("my-file-{0}", ++count); // var apiFile = new ApiFileParameter(data, name, MimeMapping.GetMimeMapping(name)); // if (pictureId != 0) // { // apiFile.Parameters.Add("PictureId", pictureId.ToString()); // } // // Test pass through of custom parameters // apiFile.Parameters.Add("CustomValue1", string.Format("{0:N}", Guid.NewGuid())); // apiFile.Parameters.Add("CustomValue2", string.Format("say hello to {0}", id)); // multipartData.Add(id, apiFile); // fstream.Close(); // } // } //} 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 APPI 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; var contentMd5Hash = string.Empty; var request = (HttpWebRequest)WebRequest.Create(context.Url); SetTimeout(request); // Optional. request.UserAgent = Program.ConsumerName; 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); // Additional headers. if (context.AdditionalHeaders.HasValue()) { var jsonHeaders = JObject.Parse(context.AdditionalHeaders); foreach (var item in jsonHeaders) { var value = item.Value?.ToString(); if (item.Key.HasValue() && value.HasValue()) { request.Headers.Add(item.Key, value); } } } if (BodySupported(context.HttpMethod)) { if (MultipartSupported(context.HttpMethod) && (multipartData?.Any() ?? false)) { 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)) { requestContent.Append(content); data = Encoding.UTF8.GetBytes(content); contentMd5Hash = CreateContentMd5Hash(data); request.ContentLength = data.Length; request.ContentType = "application/json; charset=utf-8"; } else { request.ContentLength = 0; } } if (!string.IsNullOrEmpty(contentMd5Hash)) { // Optional. Provider returns HmacResult.ContentMd5NotMatching if there's no match. request.Headers.Add(HttpRequestHeader.ContentMd5, contentMd5Hash); } var messageRepresentation = CreateMessageRepresentation(context, contentMd5Hash, timestamp, true); //Debug.WriteLine(messageRepresentation); var 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); }
private void CallTheApi() { if (txtUrl.Text.HasValue() && !txtUrl.Text.EndsWith("/")) { txtUrl.Text += "/"; } if (cboPath.Text.HasValue() && !cboPath.Text.StartsWith("/")) { cboPath.Text = "/" + cboPath.Text; } var context = new WebApiRequestContext { PublicKey = txtPublicKey.Text, SecretKey = txtSecretKey.Text, Url = txtUrl.Text + (radioOdata.Checked ? "odata/" : "api/") + txtVersion.Text + cboPath.Text, HttpMethod = cboMethod.Text, HttpAcceptType = radioJson.Checked ? ApiConsumer.JsonAcceptType : ApiConsumer.XmlAcceptType, AdditionalHeaders = cboHeaders.Text }; if (cboQuery.Text.HasValue()) { context.Url = string.Format("{0}?{1}", context.Url, cboQuery.Text); } if (!context.IsValid) { "Please enter Public-Key, Secret-Key, URL and method.".Box(MessageBoxButtons.OK, MessageBoxIcon.Exclamation); Debug.WriteLine(context.ToString()); return; } var apiConsumer = new ApiConsumer(); var response = new WebApiConsumerResponse(); var sb = new StringBuilder(); StringBuilder requestContent = null; Dictionary <string, object> multiPartData = null; lblRequest.Text = "Request: " + context.HttpMethod + " " + context.Url; lblRequest.Refresh(); // Create multipart form data. if (cboFileUpload.Text.HasValue()) { try { var fileUploadModel = JsonConvert.DeserializeObject(cboFileUpload.Text, typeof(FileUploadModel)) as FileUploadModel; multiPartData = apiConsumer.CreateMultipartData(fileUploadModel); } catch { cboFileUpload.RemoveCurrent(); cboFileUpload.Text = string.Empty; "File upload data is invalid.".Box(MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } } var webRequest = apiConsumer.StartRequest(context, cboContent.Text, multiPartData, out requestContent); txtRequest.Text = requestContent.ToString(); var result = apiConsumer.ProcessResponse(webRequest, response, folderBrowserDialog1); lblResponse.Text = "Response: " + response.Status; sb.Append(response.Headers); if (result && response.Content.HasValue()) { if (radioJson.Checked && radioOdata.Checked) { var customers = response.TryParseCustomers(); if (customers != null) { sb.AppendLine("Parsed {0} customer(s):".FormatInvariant(customers.Count)); customers.ForEach(x => sb.AppendLine(x.ToString())); sb.Append("\r\n"); } } } sb.Append(response.Content); txtResponse.Text = sb.ToString(); cboPath.InsertRolled(cboPath.Text, 64); cboQuery.InsertRolled(cboQuery.Text, 64); cboContent.InsertRolled(cboContent.Text, 64); cboHeaders.InsertRolled(cboHeaders.Text, 64); cboFileUpload.InsertRolled(cboFileUpload.Text, 64); }