How can I simulate server for Unit test in Grails (Spock)? - unit-testing

I have written this simple service for doing subrequest via HTTPBuilder, to get instance of class representing obtained page for further use:
package cmspage
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.HTML
class CmsPageService {
static transactional = false
final String SUBREQUEST_HOST = "www.mydomainforsubrequest.com"
CmsPage getCmsPageInstance(Object request) {
String host = request.getServerName()
String url = request.getRequestURI()
HashMap queryMap = this.queryStringToMap(request.getQueryString())
return this.subRequest(host, url, queryMap)
}
CmsPage getCmsPageInstance(String host, String url, String queryString = null) {
HashMap queryMap = queryStringToMap(queryString)
return this.subRequest(host, url, queryMap)
}
private CmsPage subRequest(String host, String url, HashMap queryMap = null) {
CmsPage cmsPageInstance = new CmsPage()
HTTPBuilder http = new HTTPBuilder()
http.request("http://" + SUBREQUEST_HOST, GET, HTML) { req ->
uri.path = url
uri.query = queryMap
headers.'X-Original-Host' = 'www.mydomain.com'
response.success = { resp, html ->
cmsPageInstance.responseStatusCode = resp.status
if (resp.status < 400) {
cmsPageInstance.html = html
}
}
response.failure = { resp ->
cmsPageInstance.responseStatusCode = resp.status
return null
}
}
return cmsPageInstance
}
private HashMap queryStringToMap(String queryString) {
if (queryString) {
queryString = queryString.replace("?", "")
String[] splitToParameters = queryString.split("&")
HashMap queryMap = new HashMap()
splitToParameters.each {
String[] split = it.split("=")
for (int i = 0; i < split.length; i += 2) {
queryMap.put(split[i], split[i + 1])
}
}
return queryMap
} else return null
}
}
Now I need to write unit test for this service. I would like to use some simple html document to test it instead of testing some "live" site. But I do not know how?
Can anybody help me?

Jadler should suite you well. Check its documentation and this post on basic usage.

Related

Connect to Azure Text Analytics from Console App without await

I am trying to call an Azure API (Text Analytics API) from a C# console application with a HttpRequest and I do not want to use any DLLs or await
but using the below snippet I am receiving "Bad Request". Can someone help me where it is going wrong.
public static void ProcessText()
{
string apiKey = "KEY FROM AZURE";
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", apiKey);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var requestUri = "https://eastus.api.cognitive.microsoft.com/text/analytics/v2.0/sentiment?" + queryString;
//HttpResponseMessage response;
// Request body
byte[] byteData = Encoding.UTF8.GetBytes("I really love Azure. It is the best cloud platform");
using (var content = new ByteArrayContent(byteData))
{
//content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = client.PostAsync(requestUri, content).Result;
Console.WriteLine(response);
Console.ReadLine();
}
}
string apiKey = "<<Key from Azure>>";
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", apiKey);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var requestUri = "https://**eastus**.api.cognitive.microsoft.com/text/analytics/v2.0/sentiment?" + queryString;
//HttpResponseMessage response;
var body = new
{
documents = new[]
{
new
{
ID="1", text="I really love Azure. It is the best cloud platform"
}
}
};
string json = JsonConvert.SerializeObject(body);
byte[] byteData = Encoding.UTF8.GetBytes(json);
dynamic item = null;
using (var con = new ByteArrayContent(byteData))
{
//content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = client.PostAsync(requestUri, con).Result;
if (response.StatusCode == HttpStatusCode.OK)
{
string res = string.Empty;
using (HttpContent content = response.Content)
{
Task<string> result = content.ReadAsStringAsync();
res = result.Result;
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
item = serializer.Deserialize<object>(res);
}
}
Hi All, I could able to get the API output using the above approach

Invoke AWS API Gateway URL in C#

We are trying to call AWS API Gateway from C# Windows Service, for a background job. Which was supposed to trigger API Gateway periodically initialize request?
We used RestSharp to invoke API Endpoint, the class called AwsAuthenticator , which is inherited from RestSharp.Authenticators.IAuthenticator.
But when we invoke API Gateway we received with error as
"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
namespace ConsoleApp3
{
public class AwsAuthenticator : RestSharp.Authenticators.IAuthenticator
{
public string AccessKeyId { get; }
public string AccessKeySecret { get; }
public string Region { get; }
public AwsAuthenticator(string accessKeyId, string accessKeySecret, string region)
{
AccessKeyId = accessKeyId;
AccessKeySecret = accessKeySecret;
Region = region;
}
private static HashSet<string> ignoredHeaders = new HashSet<string>() {
"authorization",
"content-length",
"content-type",
"user-agent"
};
public void Authenticate(RestSharp.IRestClient client, RestSharp.IRestRequest request)
{
DateTime signingDate = DateTime.UtcNow;
SetContentMd5(request);
SetContentSha256(request);
SetHostHeader(request, client);
SetDateHeader(request, signingDate);
SortedDictionary<string, string> headersToSign = GetHeadersToSign(request);
string signedHeaders = GetSignedHeaders(headersToSign);
string canonicalRequest = GetCanonicalRequest(client, request, headersToSign);
byte[] canonicalRequestBytes = System.Text.Encoding.UTF8.GetBytes(canonicalRequest);
string canonicalRequestHash = BytesToHex(ComputeSha256(canonicalRequestBytes));
string stringToSign = GetStringToSign(Region, signingDate, canonicalRequestHash);
byte[] signingKey = GenerateSigningKey(Region, signingDate);
byte[] stringToSignBytes = System.Text.Encoding.UTF8.GetBytes(stringToSign);
byte[] signatureBytes = SignHmac(signingKey, stringToSignBytes);
string signature = BytesToHex(signatureBytes);
string authorization = GetAuthorizationHeader(signedHeaders, signature, signingDate, Region);
request.AddHeader("Authorization", authorization);
}
public string GetCredentialString(DateTime signingDate, string region)
{
return AccessKeyId + "/" + GetScope(region, signingDate);
}
private string GetAuthorizationHeader(string signedHeaders, string signature, DateTime signingDate, string region)
{
return "AWS4-HMAC-SHA256 Credential=" + this.AccessKeyId + "/" + GetScope(region, signingDate) +
", SignedHeaders=" + signedHeaders + ", Signature=" + signature;
}
private string GetSignedHeaders(SortedDictionary<string, string> headersToSign)
{
return string.Join(";", headersToSign.Keys);
}
private byte[] GenerateSigningKey(string region, DateTime signingDate)
{
byte[] formattedDateBytes = System.Text.Encoding.UTF8.GetBytes(signingDate.ToString("yyyMMdd"));
byte[] formattedKeyBytes = System.Text.Encoding.UTF8.GetBytes("AWS4" + this.AccessKeySecret);
byte[] dateKey = SignHmac(formattedKeyBytes, formattedDateBytes);
byte[] regionBytes = System.Text.Encoding.UTF8.GetBytes(region);
byte[] dateRegionKey = SignHmac(dateKey, regionBytes);
byte[] serviceBytes = System.Text.Encoding.UTF8.GetBytes("execute-api");
byte[] dateRegionServiceKey = SignHmac(dateRegionKey, serviceBytes);
byte[] requestBytes = System.Text.Encoding.UTF8.GetBytes("aws4_request");
return SignHmac(dateRegionServiceKey, requestBytes);
}
private byte[] SignHmac(byte[] key, byte[] content)
{
HMACSHA256 hmac = new HMACSHA256(key);
hmac.Initialize();
return hmac.ComputeHash(content);
}
private string GetStringToSign(string region, DateTime signingDate, string canonicalRequestHash)
{
return "AWS4-HMAC-SHA256\n" +
signingDate.ToString("yyyyMMddTHHmmssZ") + "\n" +
GetScope(region, signingDate) + "\n" +
canonicalRequestHash;
}
private string GetScope(string region, DateTime signingDate)
{
string formattedDate = signingDate.ToString("yyyyMMdd");
return formattedDate + "/" + region + "/execute-api/aws4_request";
}
private byte[] ComputeSha256(byte[] body)
{
SHA256 sha256 = SHA256.Create();
return sha256.ComputeHash(body);
}
private string BytesToHex(byte[] checkSum)
{
return BitConverter.ToString(checkSum).Replace("-", string.Empty).ToLower();
}
public string PresignPostSignature(string region, DateTime signingDate, string policyBase64)
{
byte[] signingKey = this.GenerateSigningKey(region, signingDate);
byte[] stringToSignBytes = System.Text.Encoding.UTF8.GetBytes(policyBase64);
byte[] signatureBytes = SignHmac(signingKey, stringToSignBytes);
string signature = BytesToHex(signatureBytes);
return signature;
}
public string PresignURL(RestSharp.IRestClient client, RestSharp.IRestRequest request, int expires)
{
DateTime signingDate = DateTime.UtcNow;
string requestQuery = "";
string path = request.Resource;
requestQuery = "X-Amz-Algorithm=AWS4-HMAC-SHA256&";
requestQuery += "X-Amz-Credential="
+ this.AccessKeyId
+ Uri.EscapeDataString("/" + GetScope(Region, signingDate))
+ "&";
requestQuery += "X-Amz-Date="
+ signingDate.ToString("yyyyMMddTHHmmssZ")
+ "&";
requestQuery += "X-Amz-Expires="
+ expires
+ "&";
requestQuery += "X-Amz-SignedHeaders=host";
string canonicalRequest = GetPresignCanonicalRequest(client, request, requestQuery);
byte[] canonicalRequestBytes = System.Text.Encoding.UTF8.GetBytes(canonicalRequest);
string canonicalRequestHash = BytesToHex(ComputeSha256(canonicalRequestBytes));
string stringToSign = GetStringToSign(Region, signingDate, canonicalRequestHash);
byte[] signingKey = GenerateSigningKey(Region, signingDate);
byte[] stringToSignBytes = System.Text.Encoding.UTF8.GetBytes(stringToSign);
byte[] signatureBytes = SignHmac(signingKey, stringToSignBytes);
string signature = BytesToHex(signatureBytes);
// Return presigned url.
return client.BaseUrl + path + "?" + requestQuery + "&X-Amz-Signature=" + signature;
}
private string GetPresignCanonicalRequest(RestSharp.IRestClient client, RestSharp.IRestRequest request, string requestQuery)
{
LinkedList<string> canonicalStringList = new LinkedList<string>();
canonicalStringList.AddLast(request.Method.ToString());
string path = request.Resource;
if (!path.StartsWith("/"))
{
path = "/" + path;
}
canonicalStringList.AddLast(path);
canonicalStringList.AddLast(requestQuery);
canonicalStringList.AddLast("host:" + client.BaseUrl.Host);
canonicalStringList.AddLast("");
canonicalStringList.AddLast("host");
canonicalStringList.AddLast("UNSIGNED-PAYLOAD");
return string.Join("\n", canonicalStringList);
}
private string GetCanonicalRequest(RestSharp.IRestClient client, RestSharp.IRestRequest request,
SortedDictionary<string, string> headersToSign)
{
LinkedList<string> canonicalStringList = new LinkedList<string>();
canonicalStringList.AddLast(request.Method.ToString());
string[] path = request.Resource.Split(new char[] { '?' }, 2);
if (!path[0].StartsWith("/"))
{
path[0] = "/" + path[0];
}
canonicalStringList.AddLast(path[0]);
string query = "";
if (path.Length == 2)
{
var parameterString = path[1];
var parameterList = parameterString.Split('&');
SortedSet<string> sortedQueries = new SortedSet<string>();
foreach (string individualParameterString in parameterList)
{
if (individualParameterString.Contains('='))
{
string[] splitQuery = individualParameterString.Split(new char[] { '=' }, 2);
sortedQueries.Add(splitQuery[0] + "=" + splitQuery[1]);
}
else
{
sortedQueries.Add(individualParameterString + "=");
}
}
query = string.Join("&", sortedQueries);
}
canonicalStringList.AddLast(query);
foreach (string header in headersToSign.Keys)
{
canonicalStringList.AddLast(header + ":" + headersToSign[header]);
}
canonicalStringList.AddLast("");
canonicalStringList.AddLast(string.Join(";", headersToSign.Keys));
if (headersToSign.Keys.Contains("x-amz-content-sha256"))
{
canonicalStringList.AddLast(headersToSign["x-amz-content-sha256"]);
}
else
{
canonicalStringList.AddLast("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
}
return string.Join("\n", canonicalStringList);
}
private SortedDictionary<string, string> GetHeadersToSign(RestSharp.IRestRequest request)
{
var headers = request.Parameters.Where(p => p.Type.Equals(RestSharp.ParameterType.HttpHeader)).ToList();
SortedDictionary<string, string> sortedHeaders = new SortedDictionary<string, string>();
foreach (var header in headers)
{
string headerName = header.Name.ToLower();
string headerValue = header.Value.ToString();
if (!ignoredHeaders.Contains(headerName))
{
sortedHeaders.Add(headerName, headerValue);
}
}
return sortedHeaders;
}
private void SetDateHeader(RestSharp.IRestRequest request, DateTime signingDate)
{
request.AddHeader("x-amz-date", signingDate.ToString("yyyyMMddTHHmmssZ"));
}
private void SetHostHeader(RestSharp.IRestRequest request, RestSharp.IRestClient client)
{
request.AddHeader("Host", client.BaseUrl.Host + (client.BaseUrl.Port != 80 ? ":" + client.BaseUrl.Port : string.Empty));
}
private void SetContentSha256(RestSharp.IRestRequest request)
{
if (request.Method == RestSharp.Method.PUT || request.Method.Equals(RestSharp.Method.POST))
{
var bodyParameter = request.Parameters.Where(p => p.Type.Equals(RestSharp.ParameterType.RequestBody)).FirstOrDefault();
if (bodyParameter == null)
{
request.AddHeader("x-amz-content-sha256", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
return;
}
byte[] body = null;
if (bodyParameter.Value is string)
{
body = System.Text.Encoding.UTF8.GetBytes(bodyParameter.Value as string);
}
if (bodyParameter.Value is byte[])
{
body = bodyParameter.Value as byte[];
}
if (body == null)
{
body = new byte[0];
}
SHA256 sha256 = System.Security.Cryptography.SHA256.Create();
byte[] hash = sha256.ComputeHash(body);
string hex = BitConverter.ToString(hash).Replace("-", string.Empty).ToLower();
request.AddHeader("x-amz-content-sha256", hex);
}
else
{
request.AddHeader("x-amz-content-sha256", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
}
}
private void SetContentMd5(RestSharp.IRestRequest request)
{
if (request.Method == RestSharp.Method.PUT || request.Method.Equals(RestSharp.Method.POST))
{
var bodyParameter = request.Parameters.Where(p => p.Type.Equals(RestSharp.ParameterType.RequestBody)).FirstOrDefault();
if (bodyParameter == null)
{
return;
}
byte[] body = null;
if (bodyParameter.Value is string)
{
body = System.Text.Encoding.UTF8.GetBytes(bodyParameter.Value as string);
}
if (bodyParameter.Value is byte[])
{
body = bodyParameter.Value as byte[];
}
if (body == null)
{
body = new byte[0];
}
MD5 md5 = MD5.Create();
byte[] hash = md5.ComputeHash(body);
string base64 = Convert.ToBase64String(hash);
request.AddHeader("Content-MD5", base64);
}
}
}
////////////////////////
public class MainClass
{
public void Execute()
{
var client = new RestClient("https://nm47849kod.execute-api.ap-southeast1.amazonaws.com/samplegateway/");
var request = new RestRequest("/", Method.POST);
var postData = new { Mode = 4 };
request.AddParameter("application/json",JsonConvert.SerializeObject(postData),ParameterType.RequestBody); AwsAuthenticator awsAuthenticator = new AwsAuthenticator("AccessKeyXXXXX", "SECKEYxxxx12313123123123123", "apsoutheast-1");
awsAuthenticator.Authenticate(client,request);
IRestResponse response = client.Execute(request);
var content = response.Content; // raw content as string
Console.WriteLine(content);
Console.ReadLine();
}
}
Error Details:
{"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.\n\nThe Canonical String for this request should have been\n'POST\n/samplegateway/\n\ncontent-md5:rkT7BbUvFInBgrPCuA0UZw==\nhost:nm47849kod.execute-api.ap-southeast-1.amazonaws.com\nx-amz-content-sha256:0318f62547c9078687e73f987ec26fa557047b67f54bb99b8047c950990ae42c\nx-amz-date:20190601T102835Z\n\ncontent-md5;host;x-amz-content-sha256;x-amz-date\n0318f62547c9078687e73f987ec26fa557047b67f54bb99b8047c950990ae42c'\n\nThe String-to-Sign should have been\n'AWS4-HMAC-SHA256\n20190601T102835Z\n20190601/ap-southeast-1/execute-api/aws4_request\n8f89bd5010655fb26a8de5e29d48d6129ac7875e5eb6bc2faeb8e41864b4d49e'\n"}.
We identified the problem.
Below is the working code and this resolves my issue. I am sharing this so that the group can get benefitted. The above class is entirely rewritten and when invoked it worked.
public class ApiRequest
{
private const string ServiceName = "execute-api";
private const string Algorithm = "AWS4-HMAC-SHA256";
private const string ContentType = "application/json";
private const string SignedHeaders = "content-type;host;x-amz-date;x-api-key";
private const string DateTimeFormat = "yyyyMMddTHHmmssZ";
private const string DateFormat = "yyyyMMdd";
public AwsApiGatewayRequest AwsApiGatewayRequest;
public ApiRequest(AwsApiGatewayRequest request)
{
AwsApiGatewayRequest = request;
if (string.IsNullOrEmpty(AwsApiGatewayRequest.RequestMethod))
AwsApiGatewayRequest.RequestMethod = "POST";
if (string.IsNullOrEmpty(AwsApiGatewayRequest.xApiKey))
AwsApiGatewayRequest.xApiKey = "";
}
public WebResponse GetPostResponse()
{
var request = GetPostRequest();
return request.GetResponse();
}
public WebRequest GetPostRequest()
{
string hashedRequestPayload = CreateRequestPayload(AwsApiGatewayRequest.JsonData);
string authorization = Sign(hashedRequestPayload, AwsApiGatewayRequest.RequestMethod, AwsApiGatewayRequest.AbsolutePath, AwsApiGatewayRequest.QueryString);
string requestDate = DateTime.UtcNow.ToString(DateTimeFormat);
var webRequest = WebRequest.Create($"https://{AwsApiGatewayRequest.Host}{AwsApiGatewayRequest.AbsolutePath}");
webRequest.Timeout = AwsApiGatewayRequest.RequestTimeout.HasValue ? AwsApiGatewayRequest.RequestTimeout.Value : 50000;
webRequest.Method = AwsApiGatewayRequest.RequestMethod;
webRequest.ContentType = ContentType;
webRequest.Headers.Add("X-Amz-date", requestDate);
webRequest.Headers.Add("Authorization", authorization);
webRequest.Headers.Add("x-amz-content-sha256", hashedRequestPayload);
if (!string.IsNullOrEmpty(AwsApiGatewayRequest.AdditionalHeaders))
{
// parse apart and apply the additional headers
string[] headers = AwsApiGatewayRequest.AdditionalHeaders.Split(';');
foreach (string header in headers)
{
var headervalue = header.Split('=');
if (headervalue.Count() == 2)
webRequest.Headers.Add(headervalue[0], headervalue[1]);
}
}
if (!string.IsNullOrEmpty(AwsApiGatewayRequest.SessionToken))
webRequest.Headers.Add("X-Amz-Security-Token", AwsApiGatewayRequest.SessionToken);
webRequest.ContentLength = AwsApiGatewayRequest.JsonData.Length;
var encoding = new ASCIIEncoding();
var data = encoding.GetBytes(AwsApiGatewayRequest.JsonData);
using (var newStream = webRequest.GetRequestStream())
{
newStream.Write(data, 0, data.Length);
newStream.Close();
}
return webRequest;
}
private string CreateRequestPayload(string jsonString)
{
return HexEncode(Hash(ToBytes(jsonString)));
}
private string Sign(string hashedRequestPayload, string requestMethod, string canonicalUri, string canonicalQueryString)
{
var currentDateTime = DateTime.UtcNow;
var dateStamp = currentDateTime.ToString(DateFormat);
var requestDate = currentDateTime.ToString(DateTimeFormat);
var credentialScope = $"{dateStamp}/{AwsApiGatewayRequest.RegionName}/{ServiceName}/aws4_request";
var headers = new SortedDictionary<string, string> {
{ "content-type", ContentType },
{ "host", AwsApiGatewayRequest.Host },
{ "x-amz-date", requestDate },
{ "x-api-key", AwsApiGatewayRequest.xApiKey }
};
var canonicalHeaders = string.Join("\n", headers.Select(x => x.Key.ToLowerInvariant() + ":" + x.Value.Trim())) + "\n";
// Task 1: Create a Canonical Request For Signature Version 4
var canonicalRequest = $"{requestMethod}\n{canonicalUri}\n{canonicalQueryString}\n{canonicalHeaders}\n{SignedHeaders}\n{hashedRequestPayload}";
var hashedCanonicalRequest = HexEncode(Hash(ToBytes(canonicalRequest)));
// Task 2: Create a String to Sign for Signature Version 4
var stringToSign = $"{Algorithm}\n{requestDate}\n{credentialScope}\n{hashedCanonicalRequest}";
// Task 3: Calculate the AWS Signature Version 4
var signingKey = GetSignatureKey(AwsApiGatewayRequest.SecretKey, dateStamp, AwsApiGatewayRequest.RegionName, ServiceName);
var signature = HexEncode(HmacSha256(stringToSign, signingKey));
// Task 4: Prepare a signed request
// Authorization: algorithm Credential=access key ID/credential scope, SignedHeadaers=SignedHeaders, Signature=signature
var authorization = $"{Algorithm} Credential={AwsApiGatewayRequest.AccessKey}/{dateStamp}/{AwsApiGatewayRequest.RegionName}/{ServiceName}/aws4_request, SignedHeaders={SignedHeaders}, Signature={signature}";
return authorization;
}
private byte[] GetSignatureKey(string key, string dateStamp, string regionName, string serviceName)
{
var kDate = HmacSha256(dateStamp, ToBytes("AWS4" + key));
var kRegion = HmacSha256(regionName, kDate);
var kService = HmacSha256(serviceName, kRegion);
return HmacSha256("aws4_request", kService);
}
private byte[] ToBytes(string str)
{
return Encoding.UTF8.GetBytes(str.ToCharArray());
}
private string HexEncode(byte[] bytes)
{
return BitConverter.ToString(bytes).Replace("-", string.Empty).ToLowerInvariant();
}
private byte[] Hash(byte[] bytes)
{
return SHA256.Create().ComputeHash(bytes);
}
private byte[] HmacSha256(string data, byte[] key)
{
return new HMACSHA256(key).ComputeHash(ToBytes(data));
}
}
Execution Parameter:
var request = new AwsApiGatewayRequest()
{
RegionName = "",
Host = ,
AccessKey = "",
SecretKey = "",
RequestMethod = "POST",
AbsolutePath = ,
JsonData = "{\"Mode\":\"4\"}",
SessionToken = ""
};//Invoke this using RestClient...
The problem here is we failed to add an additional header which was required by AWS. In this version, we have added hence it rectified.
Thanks for your support.

Vimeo API C# - Uploading a video

I'm following the api's guide about resumable uploads.
I managed to get a response after step 1 ("create the video"),
with a uri and a upload_link.
About the second part, things are not as clear.
It only says which headers should I sent, but there are two things I don't get,
first - where do I need to put the "upload_link"?
Should the call be like this:
/me/{upload_link}? (of course im also adding the access token, etc)
second, what about the actual file? I guess i should send it in the same method, but how? No word about it.
This is the code for the PATCH request:
public string UploadPatch(
string uploadlink,
string method)
{
var headers = new WebHeaderCollection()
{
{ "Tus-Resumable", "1.0.0" },
{ "Upload-Offest", "0" }
};
method = method.ToUpper();
string body = "";
string contentType = "application/offset+octet-stream";
return Helpers.HTTPUpload(uploadlink, method, headers, body, contentType);
}
And HTTPUpload():
public static string HTTPPatch(string url, string method,
WebHeaderCollection headers, string payload,
string contentType)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.CreateHttp(url);
if (Proxy != null) request.Proxy = Proxy;
request.Headers = headers;
request.Method = method;
request.Accept = "application/vnd.vimeo.*+json; version=3.1";
request.ContentType = contentType;
request.KeepAlive = false;
if (!String.IsNullOrWhiteSpace(payload))
{
var streamBytes = Helpers.ToByteArray(payload);
request.ContentLength = streamBytes.Length;
Stream reqStream = request.GetRequestStream();
reqStream.Write(streamBytes, 0, streamBytes.Length);
reqStream.Close();
}
HttpWebResponse response = (HttpWebResponse)(request.GetResponse());
Debug.WriteLine(((HttpWebResponse)response).StatusDescription);
var dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
Debug.WriteLine(String.Format("Response from URL {0}:", url), "HTTPFetch");
Debug.WriteLine(responseFromServer, "HTTPFetch");
return responseFromServer;
}
Thanks
The upload_link is the URL where you upload the video to. In other words, make your call to the https://[...].cloud.vimeo.com/upload?[...] URL instead of the https://api.vimeo.com host that is used for other API requests.
Additionally, when you make a request to that cloud.vimeo.com upload_link, only provide the required headers as specified in the documentation.
https://developer.vimeo.com/api/upload/videos#resumable-approach
The code is VB.Net, but you can change to C#
'Imports / use these classes
'Imports System.Net
'Imports Newtonsoft.Json
'Imports System.IO
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
'Receive the video from File Upload
If Not IsNothing(fuVideo.PostedFile) Then
'You will need this for SSL
System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType.Tls Or (SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls12))
'Path to save the video Save
Dim vFilePath As String = Server.MapPath("App_data/Videos")
Dim vFileNameAndPath As String = vFilePath & "/" & fuVideo.PostedFile.FileName
'Save Video
fuVideo.PostedFile.SaveAs(vFileNameAndPath)
'Get the size
Dim vSize As String = New FileInfo(vFileNameAndPath).Length()
'Vimeo URL
Dim vVimeURL As String = "https://api.vimeo.com/me/videos"
Dim wc As WebClient = New WebClient()
wc.Headers.Clear()
wc.Headers.Add("Authorization", "bearer XXXXXXXXXXXXXXXXX") 'Use your App Code
wc.Headers.Add("Content-Type", "application/json")
wc.Headers.Add("Accept", "application/vnd.vimeo.*+json;version=3.4")
wc.Encoding = System.Text.Encoding.UTF8
'txtName is a text box, so you can give a Title to the Video
Dim vData As String = "{ ""upload"": {""approach"": ""tus"",""size"": """ & vSize & """ }, ""name"" : """ & txtName.Text & """ }"
Dim vimeoTicket = JsonConvert.DeserializeObject(wc.UploadString(vVimeURL, "POST", vData))
wc.Headers.Clear()
wc.Headers.Add("Content-Type", "application/offset+octet-stream")
wc.Headers.Add("Accept", "application/vnd.vimeo.*+json;version=3.4")
wc.Headers.Add("Tus-Resumable", "1.0.0")
wc.Headers.Add("Upload-Offset", "0")
Dim vupload_link As String = vimeoTicket("upload")("upload_link").Value 'Json from Vimeo has the upload_link
Dim vResponse As Byte() = wc.UploadFile(vupload_link, "PATCH", vFileNameAndPath)
Response.Write(System.Text.Encoding.Unicode.GetString(vResponse)) ' If everething is ok, vResponse is Nothing
End If
Catch ex As Exception
ltrErro.Text = "Error"
End Try
End Sub
for this may look at the sample code below:-
I am using a nuget library vimeo-dot-net also at https://github.com/mfilippov/vimeo-dot-net, this has a wrapper built around upload, delete etc.
public ActionResult UploadChapterVideoVimeo(HttpPostedFileBase file, string productID = "")
{
if (file != null){
var authCheck = Task.Run(async () => await vimeoClient.GetAccountInformationAsync()).Result;
if (authCheck.Name != null)
{
BinaryContent binaryContent = new BinaryContent(file.InputStream, file.ContentType);
int chunkSize = 0;
int contenetLength = file.ContentLength;
int temp1 = contenetLength / 1024;
if (temp1 > 1)
{
chunkSize = temp1 / 1024;
chunkSize = chunkSize * 1048576;
}
else
{ chunkSize = chunkSize * 1048576; }
binaryContent.OriginalFileName = file.FileName;
var d = Task.Run(async () => await vimeoClient.UploadEntireFileAsync(binaryContent, chunkSize, null)).Result;
vmodel.chapter_vimeo_url = "VIMEO-" + d.ClipUri;
}
return RedirectToAction("ProductBuilder", "Products", new { productId = EncryptedProductID, message = "Successfully Uploaded video", type = 1 });
}
}
catch (Exception exc)
{
return RedirectToAction("ProductBuilder", "Products", new { productId = EncryptedProductID, message = "Failed to Uploaded video " + exc.Message, type = 0 });
}
}
return null; }

Play Framework: getting foursquare access token

I am trying to grasp how Play framework handles its web service calls.
This is Foursquare's directions (after 1 and 2):
Your server will make a request for
https://foursquare.com/oauth2/access_token
?client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&grant_type=authorization_code
&redirect_uri=YOUR_REGISTERED_REDIRECT_URI
&code=CODE
The response will be JSON
{ access_token: ACCESS_TOKEN }
And this is my code:
public static Result index() {
String base = "http://foursquare.com/oauth2/authenticate";
String clientId = "?client_id=***";
String responseType = "&response_type=code";
String redirectUri = "&redirect_uri=http://localhost:9000/code";
return redirect(base + clientId + responseType + redirectUri);
}
public static Result code() {
String base = "http://foursquare.com/oauth2/access_token";
String clientId = "?client_id=***";
String clientsecret = "&client_secret=***";
String grantType = "&grant_type=authorization_code";
String redirectUri = "&redirect_uri=http://localhost:9000/json";
String code = "&code=" + request().getQueryString("code");
return redirect(base + clientId + clientsecret + grantType
+ redirectUri + code);
}
There are two things I am curios about:
1) I am redirected to a page with the access token displayed on screen:
URL: https://foursquare.com/oauth2/access_token?client_id=***&client_secret=***&grant_type=authorization_code&redirect_uri=http://localhost:9000/json&code=***
With this displayed:
{"access_token":"***"}
I would have expected to be redirected to http://localhost:9000/json as that was the redirect uri...
2) How do I grab the access token? I have tried using the asynchronous web service calls vis http://www.playframework.com/documentation/2.2.x/JavaWS but I cannot make them work.
My attempt:
String feedUrl = base + clientId + clientsecret + grantType
+ redirectUri + code;
final Promise<Result> resultPromise = WS.url(feedUrl).get().map(
new Function<WS.Response, Result>() {
public Result apply(WS.Response response) {
return ok("Feed title:" + response.asJson().findPath("access_token").asText());
}
}
);
return resultPromise;
This gives me an exception: [ConnectException: Connection refused: no further information: foursquare.com/107.23.103.139:80 to http://foursquare.com/oauth2/access_token]
All help is appreciated greatly!
This is the class that I made to get the foursquare access_token and submit a new search to foursquare:
public class Application extends Controller {
static final String HOST_AUTHENTICATE = "foursquare.com/oauth2/authenticate";
static final String HOST_ACCESS_TOKEN = "https://www.foursquare.com/oauth2/access_token";
static final String CLIENT_ID = "***";
static final String REDIRECT_URI = "http://localhost:9000/code";
static final String CLIENT_SECRET = "***";
static final String GRANT_TYPE = "authorization_code";
static final String RESPONSE_TYPE = "code";
static final String FOURSQUARE_API_FRIENDS = "https://api.foursquare.com/v2/users/self/friends";
public static Result index() {
String uri = new URIBuilder().setScheme("https").setHost(HOST_AUTHENTICATE)
.setParameter("client_id", CLIENT_ID).setParameter("response_type", RESPONSE_TYPE)
.setParameter("redirect_uri", REDIRECT_URI).toString();
return redirect(uri);
}
public static Promise<Result> code() {
WSRequestHolder authenticate = WS.url(HOST_ACCESS_TOKEN).setQueryParameter("client_id", CLIENT_ID)
.setQueryParameter("client_secret", CLIENT_SECRET).setQueryParameter("grant_type", GRANT_TYPE)
.setQueryParameter("redirect_uri", REDIRECT_URI)
.setQueryParameter("code", request().getQueryString("code").toString());
final Promise<Result> resultPromise = authenticate.get().flatMap(new Function<WS.Response, Promise<Result>>() {
public Promise<Result> apply(WS.Response response) {
JsonNode json = response.asJson();
return WS.url(FOURSQUARE_API_FRIENDS).setQueryParameter("oauth_token", json.findPath("access_token").asText())
.setQueryParameter("v", "20131108").get().map(new Function<WS.Response, Result>() {
public Result apply(WS.Response response) {
return ok(response.asJson());
}
});
}
});
return resultPromise;
}
}

Get the AccessToken of Facebook without login using HttpWebRequest for WP8

I am trying to get the accesstoken like this,
string uri = "https://graph.facebook.com/oauth/access_token?client_id=" +
APP_ID +
"&redirect_uri=&client_secret=" + APP_SECRET + "&grant_type=client_credentials";
var access_token = GetMyData(uri);
public async Task<string> GetMyData(string urlToCall)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlToCall);
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
using (var sr = new StreamReader(response.GetResponseStream()))
{
return sr.ReadToEnd();
}
}
public static Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest request)
{
var taskComplete = new TaskCompletionSource<HttpWebResponse>();
request.BeginGetResponse(asyncResponse =>
{
try
{
HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState;
HttpWebResponse someResponse = (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse);
taskComplete.TrySetResult(someResponse);
}
catch (WebException webExc)
{
HttpWebResponse failedResponse = (HttpWebResponse)webExc.Response;
taskComplete.TrySetResult(failedResponse);
}
}, request);
return taskComplete.Task;
}
It gets stuck in the var taskComplete = new TaskCompletionSource(); and takes a lot of time and does not get the accesstoken also.what is wrong?
You can probably achieve this with the following code
public void GetMyData(string urlToCall)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(urlToCall);
request.BeginGetResponse(new AsyncCallback(ReadWebRequestCallback), request);
}
private static void ReadWebRequestCallback(IAsyncResult callbackResult)
{
HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse myResponse = (HttpWebResponse)myRequest.EndGetResponse(callbackResult);
using (StreamReader httpwebStreamReader = new StreamReader(myResponse.GetResponseStream()))
{
// Here you get the result
string results = httpwebStreamReader.ReadToEnd();
}
myResponse.Close();
}