I am having .NET code to call the google api in batch request for getting the message details for multiple Ids. The request I am creating, when run through postman it works perfectly but when run this console app it gives me the Response Status code = 0 and Error Specified value has invalid CRLF characters.\r\nParameter name: value
Can someone please look into this and help me ... I have searched almost everything now but could not get any solution.
Here is my code --
var baseUrl = "/gmail/v1/users/" + _accountID + "/messages/";
RestClient client = null;
RestRequest request = null;
StringBuilder sbBody = null;
for (int j = 0; j < _messageId.Count; j++)
{
msgCount++;
if (msgCount == 1)
{
boundary = "testing_batch";
sbBody = new StringBuilder();
client = new RestClient("https://www.googleapis.com/batch/");
request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "multipart/mixed; boundary=\"" + boundary + "\"");
request.AddHeader("Authorization", "Bearer " + accessToken);
}
sbBody.Append(string.Format("--{0}\n", boundary));
sbBody.Append("Content-Type: application/http\n\n");
sbBody.Append(string.Format("GET {0}{1}\n\n", baseUrl, _messageId[j]));
if (msgCount == 1)
sbBody.Append(string.Format("--{0}--", boundary));
if (msgCount == 1)
{
msgCount = 0;
//request.AddBody(sbBody.ToString());
request.AddHeader("RequestBody", sbBody.ToString());
IRestResponse response = client.Execute(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
//Do nothing for now
}
else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
Console.ReadLine();
break;
}
else
{
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
Console.ReadLine();
break;
}
}
Related
I am able to get access token for SharePoint from accounts.accesscontrol.windows.net while I am running my application on a machine which is allowed to connect to external URL.
But when I am running my application on an environment where I can only go via a proxy server, its giving me 401: Permission denied (connect failed) even through I have added the proxy code. I am given a ProxyServer URL and port; its of type http.
Please find my code for direct hit below. This is working absolutely fine in open env:
private String getToken(String tenant_id,String client_id, String client_secret, String domain)
{
String resultToken=null;
try {
// AccessToken url
String wsURL = "https://accounts.accesscontrol.windows.net/"+ tenant_id+"/tokens/OAuth/2";
URL url = new URL(wsURL);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
// Set header
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.setRequestMethod("POST");
String jsonParam = "grant_type=client_credentials"
+ "&client_id="+client_id+"#"+tenant_id
+ "&client_secret="+client_secret
+ "&resource=00000003-0000-0ff1-ce00-000000000000/" +domain+".com#"+tenant_id;
System.out.println("TokenRequestString : " + jsonParam);
// Send Request
DataOutputStream wr = new DataOutputStream(httpConn.getOutputStream());
wr.writeBytes(jsonParam);
wr.flush();
wr.close();
// Read the response.
InputStreamReader isr = null;
if (httpConn.getResponseCode() == 200) {
isr = new InputStreamReader(httpConn.getInputStream());
} else {
isr = new InputStreamReader(httpConn.getErrorStream());
}
BufferedReader in = new BufferedReader(isr);
String responseString = "";
String outputString = "";
// Write response to a String.
while ((responseString = in.readLine()) != null) {
outputString = outputString + responseString;
}
// Extracting accessToken from string, here response
// (outputString)is a Json format string
if (outputString.indexOf("access_token\":\"") > -1) {
int i1 = outputString.indexOf("access_token\":\"");
String str1 = outputString.substring(i1 + 15);
int i2 = str1.indexOf("\"}");
String str2 = str1.substring(0, i2);
accessToken = str2;
}
} catch (Exception e) {
accessToken = "Error: " + e.getMessage();
}
return accessToken;
}
Below is my code where I am trying to achieve the same thing through proxy server. This is throwing Permission Denied (401)
private String getToken(String tenant_id,String client_id, String client_secret, String domain)
{
String resultToken=null;
try {
// AccessToken url
String wsURL = "https://accounts.accesscontrol.windows.net/"+ tenant_id+"/tokens/OAuth/2";
URL url = new URL(wsURL);
// via Proxy
Proxy webProxy
= new Proxy(Proxy.Type.HTTP, new InetSocketAddress("internet.xyz.com", 83);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(webProxy);
// Set header
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.setRequestMethod("POST");
String jsonParam = "grant_type=client_credentials"
+ "&client_id="+client_id+"#"+tenant_id
+ "&client_secret="+client_secret
+ "&resource=00000003-0000-0ff1-ce00-000000000000/" +domain+".com#"+tenant_id;
System.out.println("TokenRequestString : " + jsonParam);
// Send Request
DataOutputStream wr = new DataOutputStream(httpConn.getOutputStream());
wr.writeBytes(jsonParam);
wr.flush();
wr.close();
// Read the response.
InputStreamReader isr = null;
if (httpConn.getResponseCode() == 200) {
isr = new InputStreamReader(httpConn.getInputStream());
} else {
isr = new InputStreamReader(httpConn.getErrorStream());
}
BufferedReader in = new BufferedReader(isr);
String responseString = "";
String outputString = "";
// Write response to a String.
while ((responseString = in.readLine()) != null) {
outputString = outputString + responseString;
}
// Extracting accessToken from string, here response
// (outputString)is a Json format string
if (outputString.indexOf("access_token\":\"") > -1) {
int i1 = outputString.indexOf("access_token\":\"");
String str1 = outputString.substring(i1 + 15);
int i2 = str1.indexOf("\"}");
String str2 = str1.substring(0, i2);
accessToken = str2;
}
} catch (Exception e) {
accessToken = "Error: " + e.getMessage();
}
return accessToken;
}
I am getting the following error when trying to use paypal API
HttpStatusCode: Unauthorized; AUTHENTICATION_FAILURE; Authentication failed due to invalid authentication credentials or a missing Authorization header.
But problem is only when i publish my code to Azure Api. Live store works if I run it on visual studio.
public async Task<bool> InvoicingCreate(Models.ShopTransaction t)
{
sentJson = null;
if (_accessToken == null) await GetAccessTokenAsync();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "v2/invoicing/invoices");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken.access_token);
bool addNotes;
if (t.Product.TotalPrice == 0.0) addNotes = false;
else if (t.PaymentMethod == null) addNotes = true;
else if (t.PaymentMethod == "paypal" || t.PaymentMethod == "credit_card") addNotes = false;
else addNotes = true;
string billingEmail;
if (t.Product.IndividualCouponId.HasValue)
{
billingEmail = _configuration["Shop:CouponInvoiceEmail"];
}
else
{
billingEmail = t.BillingAddress.Email;
}
var inv = new Root
{
detail = new Detail
{
.......details the items. ...
},
.......Fill the items. ...
sentJson = JsonConvert.SerializeObject(inv, Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
request.Content = new StringContent(JsonConvert.SerializeObject(inv), Encoding.UTF8, "application/json");
HttpResponseMessage response = await _httpClient.SendAsync(request);
string content = await response.Content.ReadAsStringAsync();
if (response.StatusCode != System.Net.HttpStatusCode.Created)
{
Error error = JsonConvert.DeserializeObject<Error>(content);
throw new Exception(CompactError("Invoicing-create", response.StatusCode, error));
}
CreateResponse invoiceCreated = JsonConvert.DeserializeObject<CreateResponse>(content);
t.InvoiceId = invoiceCreated.href.Split('/').Last();
return true;
}
Auth methode
appsettings.json paypalmodel
Invoicing methode
I found the problem.
It's an domain issue. It has send to many request on paypal server. So classic denial of service.
I'm new to this. The example of android is from
GetStartedFirebase
Below are the steps:
1) I install the android to my phone
2) I followed this example to create my web api
https//learn.microsoft.com/en-us/azure/notification-hubs/notification-hubs-aspnet-backend-gcm-android-push-to-user-google-notification
3) i comment out the AuthenticationTestHandler class
4)i call the below code from fiddle
The DeviceRegistration object
{
"Platform": "gcm",
"Handle": "regid i get from android",
"Tags": [
"1",
"2"
]
}
// This creates or updates a registration (with provided channelURI) at the specified id
public async Task<HttpResponseMessage> Put(string id, DeviceRegistration deviceUpdate)
{
RegistrationDescription registration = null;
switch (deviceUpdate.Platform)
{
case "mpns":
registration = new MpnsRegistrationDescription(deviceUpdate.Handle);
break;
case "wns":
registration = new WindowsRegistrationDescription(deviceUpdate.Handle);
break;
case "apns":
registration = new AppleRegistrationDescription(deviceUpdate.Handle);
break;
case "gcm":
registration = new GcmRegistrationDescription(deviceUpdate.Handle);
break;
default:
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
registration.RegistrationId = id;
var username = "test";
string[] userTag = new string[1];
userTag[0] = "username:" + username;
registration.Tags = new HashSet<string>(userTag);
try
{
await hub.CreateOrUpdateRegistrationAsync(registration);
}
catch (MessagingException e)
{
ReturnGoneIfHubResponseIsGone(e);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
5) Then i call to send the push notification
http://localhost:4486/api/Notifications?pns=gcm&to_tag=test
public async Task<HttpResponseMessage> Post(string pns, [FromBody]string message, string to_tag)
{
var user = "test";
message = "msg";
string[] userTag = new string[1];
userTag[0] = "username:" + to_tag;
Microsoft.Azure.NotificationHubs.NotificationOutcome outcome = null;
HttpStatusCode ret = HttpStatusCode.InternalServerError;
switch (pns.ToLower())
{
case "wns":
// Windows 8.1 / Windows Phone 8.1
var toast = #"<toast><visual><binding template=""ToastText01""><text id=""1"">" +
"From " + user + ": " + message + "</text></binding></visual></toast>";
outcome = await Notifications.Instance.Hub.SendWindowsNativeNotificationAsync(toast, userTag);
break;
case "apns":
// iOS
var alert = "{\"aps\":{\"alert\":\"" + "From " + user + ": " + message + "\"}}";
outcome = await Notifications.Instance.Hub.SendAppleNativeNotificationAsync(alert, userTag);
break;
case "gcm":
// Android
var notif = "{ \"data\" : {\"message\":\"" + "From " + user + ": " + message + "\"}}";
outcome = await Notifications.Instance.Hub.SendGcmNativeNotificationAsync(notif, userTag);
break;
}
if (outcome != null)
{
if (!((outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Abandoned) ||
(outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Unknown)))
{
ret = HttpStatusCode.OK;
}
}
return Request.CreateResponse(ret);
}
No error returned but i do not receive any notification.
I try to remove usertag as below:
outcome = await Notifications.Instance.Hub.SendGcmNativeNotificationAsync(notif);
I am able to receive the notification.
Why the tag doesn't work ?
Any help appreciated.
var allRegistrations = await Notifications.Instance.Hub.GetAllRegistrationsAsync(0);
Check your tag in allRegistrations. If it is there then it should work.
You can check test notification from http://pushtry.com
I'm confused - JSON from Fiddler shows that the registration has "1" and "2" tags, but everywhere in the code you are using "username:test" tag. Can you get this registration from the hub and make sure that it has correct tags?
You can use GetRegistrationAsync<TRegistrationDescription>(String) [1], GetRegistrationsByChannelAsync(String, Int32) [2] or GetAllRegistrationsAsync(Int32) [3] methods to get the registration.
[1] https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.notificationhubs.notificationhubclient#Microsoft_Azure_NotificationHubs_NotificationHubClient_GetRegistrationAsync__1_System_String_
[2] https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.notificationhubs.notificationhubclient#Microsoft_Azure_NotificationHubs_NotificationHubClient_GetRegistrationsByChannelAsync_System_String_System_Int32_
[3] https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.notificationhubs.notificationhubclient#Microsoft_Azure_NotificationHubs_NotificationHubClient_GetAllRegistrationsAsync_System_Int32_
I am just now exploring the API Test capabilities in Fiddler. What a boon! I have this question:
When running a sequence of calls, the first call is to LOGIN. The result of this call contains an Access Token. On all subsequent calls, the HEADER needs to have this token in the form of:
Authorization: Bearer eyJ0eXAiOiJKV1QiLC......
How do I script this so that the following tests have the new token assigned?
Puzzled it out:
static function BeforeTestList(arrSess: Session[]): boolean
{
// In this method, you can do any setup you need for the test,
// e.g. adding an Authorization: token OAUTH value that you
// obtained programmatically...
var sOAUTHToken = obtainToken();
if (String.IsNullOrEmpty(sOAUTHToken)) return false;
for (var i: int=0; i<arrSess.Length; i++)
{
arrSess[i].oRequest["Authorization"] = sOAUTHToken;
}
MessageBox.Show("Token Set. Running " + arrSess.Length.ToString() + " tests.", "BeforeTestList");
return true; // Test should proceed; return false to cancel
}
static function obtainToken()
{
try
{
var Content: byte[] = System.Text.Encoding.UTF8.GetBytes("{\"UserName\":\"username\",\"Password\":\"password\"}");
var oRQH: HTTPRequestHeaders = new HTTPRequestHeaders("/auth/login", ['Host: localhost:58960','Content-Length: ' + Content.length.ToString(), 'Content-Type: application/json']);
oRQH.HTTPMethod = "POST";
var oSD = new System.Collections.Specialized.StringDictionary();
var newSession = FiddlerApplication.oProxy.SendRequestAndWait(oRQH, Content, oSD, null);
if(newSession.responseCode == 200)
{
var bodyStr = newSession.GetResponseBodyAsString();
var bodyJson=Fiddler.WebFormats.JSON.JsonDecode(bodyStr);
var token = bodyJson.JSONObject["accessToken"];
//MessageBox.Show("Authorization: Bearer " + token);
return "Bearer " + token;
}
}
catch(e)
{
MessageBox.Show("send failed" + e.ToString());
}
}
IF I remove
.spec(responseSpec)
from my call, the response prints fine at "FOO". If I include the builder, the response prints an empty string (even though the test is passing). Anyone know why, or how to fix this? I would like to use the builder and print the response of the passing test.
public void getCirclesId()
{
String endpoint = "getCirclesId";
String url = baseUrl + resourcePath + "/" + circleId;
RequestSpecification given = given().header("Authorization", RestTest.BEARER_TOKEN);
ResponseSpecBuilder specBuilder = new ResponseSpecBuilder();
specBuilder.expectBody("features.priceMonth", is("5.00"));
specBuilder.expectBody("features.priceYear", is("50.00"));
Response response = JsonTest.executeRequestWithSpec(given, url, resource, endpoint, JsonTest.HttpType.GET, specBuilder);
}
...
public static Response executeRequestWithSpec(RequestSpecification given, String url, String resource, String endpoint, HttpType type, ResponseSpecBuilder builder)
{
Response response = null;
try {
switch (type) {
case GET:
response = executeGetRequestWithSpec(given, url, builder);
break;
case POST:
response = executePostRequestWithSpec(given, url, builder);
break;
case PUT:
response = executePutRequestWithSpec(given, url, builder);
break;
case DELETE:
response = executeDeleteRequestWithSpec(given, url, builder);
break;
}
System.out.println(resource + " - " + endpoint + ": " + response.print());
} catch (AssertionError e) {
RestTest.failCount++;
System.err.println(resource + " - " + endpoint + " Error: " + e.getMessage());
}
return response;
}
private static Response executeGetRequestWithSpec(RequestSpecification given, String url, ResponseSpecBuilder builder)
{
ResponseSpecification responseSpec = builder.build();
Response response = given.when().get(url + ".json").then().assertThat().statusCode(200).spec(responseSpec).extract().response();
System.out.println("FOOOO" + response.print());
return response;
}
Are you using the latest version of REST Assured (currently 2.3.0)? Otherwise I suggest you to upgrade to this version. There was some problems with response specifications in 2.0.