Indy 10 in Lazarus RingCentral API RingOut TIdHTTP - indy

Lazarus 1.8.4
Indy 10 (March 2020)
Windows Server 2016
I'm trying to build a little "Dialer" module for a contact list I've built in Lazarus. After fiddling for months, I was finally able to translate all the RingCentral API settings into Postman, then into Indy HTTP settings, to accomplish obtaining a token. That part works reliably. However, I am unable to do a RingOut API. I always get 404 not found. The examples in other programming languages given by RingCentral in their docs don't translate well into Indy.
if htpCall.Connected then
htpCall.Request.Connection := 'close'; // Close the socket after using it to obtain the token
htpCall.Request.Clear;
htpCall.Request.Accept := 'application/json';
htpCall.Request.ContentType := 'application/json';
htpCall.Request.Username := '<redacted>'; // Client ID
htpCall.Request.Password := '<redacted>'; // Client Secret
htpCall.Request.CustomHeaders.Clear;
htpCall.Request.CustomHeaders.FoldLines := False;
htpCall.Request.BasicAuthentication := False;
htpCall.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + acc_tkn);
prms_lst.Add('from=<redacted>');
prms_lst.Add('to=<redacted>');
prms_lst.Add('callerId=<redacted>');
prms_lst.Add('country=Canada');
prms_lst.Add('playPrompt=true');
// Remove the text ".devtest" for the production version of your code, and replace the phone account with the real main phone number
htpCall.Post('https://platform.devtest.ringcentral.com/restapi/v1.0/account/<redacted>/extension/101/ring-out', prms_lst);
UPDATE:
If I leave the TIdHTTP open, then run the code above, I get a different error.
Sent:
POST /restapi/v1.0/account//extension/101/ring-out HTTP/1.1
Content-Type: application/json
Content-Length: 82
Authorization: Basic
Host: platform.devtest.ringcentral.com
Accept: application/json
User-Agent: Mozilla/3.0 (compatible; Indy Library)
from=&to=&callerId=&country=Canada&playPrompt=true
Rcvd:
HTTP/1.1 401 Unauthorized
Server: nginx
Date: Tue, 25 Aug 2020 01:50:24 GMT
Content-Type: application/json
Content-Length: 175
Connection: keep-alive
WWW-Authenticate: Bearer realm="RingCentral REST API"
RCRequestId: 57c97008-e675-11ea-87cf-005056bb81b6
{
"errorCode" : "AGW-402",
"message" : "Invalid Authorization header",
"errors" : [ {
"errorCode" : "AGW-402",
"message" : "Invalid Authorization header"
} ]
}

Related

Not able to consume WEB API hosted in same server

Below web API returns JSON for the given ID.
http://aws-av-devser/Assigning_ID/api/QidMasters/2
It's working as expected in postman.
but when I try to consume this web API in different projects on the same server. I am getting
404 Not found Error
Below is the code to consume the web API
var uri = "http://aws-av-devser/Assigning_ID/api/QidMasters/2";
var response = await httpClient.GetAsync(uri);
Error Message :
{
StatusCode: 404,
ReasonPhrase: 'Not Found',
Version: 1.1,
Content: System.Net.Http.HttpConnectionResponseContent,
Headers:
{
Server: Microsoft-HTTPAPI/2.0
Date: Fri, 17 Jun 2022 17:59:28 GMT
Connection: close
Content-Type: text/html; charset=us-ascii
Content-Length: 315
}
}
Please correct me if I am missing something

CORS preflight mysteriously failing with gorilla/handlers

I am publishing a Golang API for my application through Heroku. Not able to get my webapp (Flutter/Dart stack) to actually get a successful response from my api. However I am able to get a successful response using curl commands from local. I've read through several posts about altering the Go mux server and adding the correct headers but this has not worked for me. I even see these headers returned back during my curl requests. Could really use some help as this is slowing me down.
essentially this is my main class which creates the server
import (
"api/preventative_care"
"api/user"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"log"
"net/http"
"os"
)
func main() {
log.SetFlags(log.LstdFlags | log.Llongfile)
router := mux.NewRouter()
// Where ORIGIN_ALLOWED is like `scheme://dns[:port]`, or `*` (insecure)
headersOk := handlers.AllowedHeaders([]string{"*"})
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
originsOk := handlers.AllowedOrigins([]string{"*"})
router.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
log.Println("Up and running!")
})
router.HandleFunc("/api/login", user.LoginHandler).Methods("GET")
router.HandleFunc("/api/recommendations", preventative_care.RecommendationHandler).Methods("GET")
var port = os.Getenv("PORT")
log.Printf("Starting application on port %s\n", port)
//log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), router))
log.Fatal(http.ListenAndServe(":" + os.Getenv("PORT"), handlers.CORS(originsOk, headersOk, methodsOk)(router)))
}
And the dart code which calls this API looks like this:
Map<String, String> headers = {
"content-type": "application/json",
"username": username,
"password": password
};
final response = await http.get(Uri.parse(uri), headers: headers);
I'm hosting both the webapp and the API in 2 separate Heroku Dynos. When I hit the API from my local using curl I see below:
$ > curl -iXGET https://my-app-api.herokuapp.com/api/login -H "username:hello" -H "password:pizza"
HTTP/1.1 200 OK
Server: Cowboy
Connection: keep-alive
Content-Type: application/json
Date: Thu, 18 Nov 2021 23:39:56 GMT
Content-Length: 160
Via: 1.1 vegur
I thought I was supposed to see see the Header Access-Control-Allow-Origin: * added there but it's not yet I still get 200 success back. However when I try to use my Webapp to hit the API from a login screen using Google Chrome I see this error:
Access to XMLHttpRequest at 'https://my-app-api.herokuapp.com/api/login' from origin 'https://my-app-staging.herokuapp.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
No idea - it's like the header is being removed by Chrome or something maybe?
EDIT: I've also tried sending a preflight request using CURL and I am seeing the correct headers - however it's still showing me 4XX error.
$ > curl -H "Access-Control-Request-Method: GET" -H "Origin: https://my-app-staging.herokuapp.com" --head https://my-app-api.herokuapp.com/api/login
HTTP/1.1 405 Method Not Allowed
Server: Cowboy
Connection: keep-alive
Access-Control-Allow-Origin: *
Date: Fri, 19 Nov 2021 00:51:52 GMT
Via: 1.1 vegur
So now I'm REALLY not sure
TL;DR
gorilla/handlers doesn't (yet?) support the wildcard for Access-Control-Allow-Headers. You must specify all the allowed headers explicitly. In your case, instead of
handlers.AllowedHeaders([]string{"*"})
you should have
handlers.AllowedHeaders([]string{"content-type", "username", "password"})
More details
The Fetch standard added support (in the case of non-credentialed requests) for the wildcard in the Access-Control-Allow-Headers header back in 2016. Most modern browsers now support this feature.
However, gorilla/handlers doesn't seem to have caught up with the spec yet. If you inspect the source code for the handlers.AllowedHeaders function and for the *cors.ServeHTTP method, you'll see that there's no special handling of the "*" value: it's treated literally. As a result, the CORS middleware detects a mismatch between the request headers supplied by your preflight request (content-type, username, and password) and your allowed headers (*, taken literally) and responds with a 403 without even setting the Access-Control-Allow-Origin header, thereby causing the access-control check to fail.

Which IIS config causes the "405 Method not allowed" error for specific calls?

In our current WebAPI calls, only a few specific ones are returning the 405 error message (405 Method not allowed), the rest are working okay. The ones that are failing are only failing in a specific environment, in all the other environments all calls are returning 200 and everything is kosher.
Which IIS setting or system setting can cause this ? I am zooming in on this because this looks more like a systems/config issue.
Request URL : <hostname/GetAllStuff?userId=johndoe&sortByCustom=CreatedDate&sortByOrder=desc
Request Method: GET
Status Code: 405 Method Not Allowed
Remote Address: 172.72.78.33:443
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Origin: *
Allow: GET,POST,DELETE,PUT
Cache-Control: no-cache
Content-Length: 136
Content-Type: application/json; charset=utf-8
Date: Tue, 06 Nov 2018 17:16:28 GMT
Expires: -1
The Response looks like this. What is strange is that ALL the API calls are 1.0 (api-version: 1.0) yet only a couple of calls throw this error and that too in a specific environment.
{
"Error": {
"Code": "UnsupportedApiVersion",
"Message": "The requested resource with API version '1.0' does not support HTTP method 'GET'."
}
}

JMeter HTTP request showing Invalid credential and not getting Pass

I am testing a site having login page and then some blogs on which we can comment/post.
I first login to the site and then select a blog and make a comment on that blog.
I am able to pass the login request and select blog request but comment on the blog request showing error Invalid credential.
Here is the response message:
Thread Name: Thread Group 1-1
Sample Start: 2014-09-17 12:41:42 IST
Load time: 9
Latency: 9
Size in bytes: 286
Headers size in bytes: 286
Body size in bytes: 0
Sample Count: 1
Error Count: 1
Response code: 403
Response message: Invalid credentials
Response headers:
HTTP/1.1 403 Invalid credentials
Cache-Control: private
Server: Microsoft-IIS/8.5
X-FRAME-OPTIONS: SAMEORIGIN
X-UA-Compatible: IE=Edge
X-Telligent-Evolution: 8.0.0.37997
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 17 Sep 2014 07:11:42 GMT
Content-Length: 0
HTTPSampleResult fields:
ContentType:
DataEncoding: null
And this is the request data:
POST http://192.xx.xx.61/TelligentCommunity/api.ashx/v2/comments.json
POST data:
Body=This+is+the+sample+post+by+Arjun&ContentId=c6bc2886-1fcb-46a4-8120-e344b8d8e4a1&ContentTypeId=f7d226ab-d59f-475c-9d22-
Cookie Data:
AuthorizationCookie=71710e44-7ba7-4af7-b390-6ae81cdec229; .Telligent.Evolution=F426475F7F35ED7250E97697BCC3DE0147BD3D15C494681A9C188922459CC698DD6F6A0CA77D61E2D5C6A56A5239B338B8DC484DAB6A4073B69F9F9139500867A843A9EB39D217825C47672E1B5165214A990F8E9CF519ED6159591B510967F84F6810CBCC4466E0DA5E37D03AB0E341A6DA0970861A2F58EE873E168D1A851D9B956033B10C9856D680FC6AC5736F961631BDD1A66EE89024020BF55A8422B24A485311C87C5074F2507E4FFA9EFBADC36B0DCBC051965ACE32EDA2B5607FEBDE17F0C2F486A42E05680FD90F30494B
Request Headers:
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Rest-Authorization-Code: 7a24113f-2a71-428b-80c7-57234aac67c1
Accept-Language: en-US
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
DNT: 1
Pragma: no-cache
Authorization-Code: 7a24113f-2a71-428b-80c7-57234aac67c1
X-Requested-With: XMLHttpRequest
Referer: http://192.xx.xx.61/TelligentCommunity/certification/b/90days2mcsa/archive/2014/09/12/how-to-win-by-contributing-to-the-mcp-community
Accept-Encoding: gzip, deflate
Content-Length: 123
Host: 192.xx.xx.61
Are you sure that your login request is successful? How do you know? ASP.NET applications use dynamic parameters like viewstate or eventvalidation and they need to be extracted from the previous response and added to the next one. See ASP.NET Login Testing with JMeter guide for details.
Looking into api and json URL bits I would expect that Content-Type header should be application/json. I would suggest adding a HTTP Header Manager as a child of the request which posts a blog comment and configure it to send above Content-Type.
This Authorization-Code header value: is it something you recorded or it came from correlation? If first you need to pass the correct value as well.

Unsafe JavaScript attempt to access frame, when try to upload file with ajax

My goal is to upload file with ajax-way.
I use this javascript library http://valums.com/wp-content/uploads/ajax-upload/demo-jquery.htm
There is a link on my page like "Upload" button on example page.
When I click it, "Open file" dialog is open.
I choose file and form is automatically submitted.
This is my javascript code.
var upload_btn = $('#upload-opml');
new AjaxUpload(upload_btn.attr('id'), {
action: upload_btn.attr('href'),
name: 'opml',
onComplete: function (file, response) {
//
}
});
This is server code in Ruby on Rails.
def upload_opml
render :text => 'hello'
end
Headers, taken from Firebug.
>> Response headers
Server nginx/0.7.62
Date Wed, 09 Jun 2010 19:03:28 GMT
Content-Type text/html; charset=utf-8
Connection keep-alive
Etag "5d41402abc4b2a76b9719d911017c592"
X-Runtime 18
Content-Length 5
Cache-Control private, max-age=0, must-revalidate
Set-Cookie _RssWebApp_session=BAh7CDoPc2Vzc2lvbl9pZCIlMzJhMTQ0ZWZhOGM3YmIwODFhZmFmNjkwYTI1YWQ2ZjQ6EF9jc3JmX3Rva2VuIjEvZHVzdm1NOVlMTUF6bEw3cGRFT2I3RzZvcVJZUU42bCtMNS9PVVYrNHdBPToMdXNlcl9pZGkG--13f1950a9530591881404fbfab7b1246f98f0d81; path=/; HttpOnly
>> Request headers
Host readbox.cz
User-Agent Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.2) Gecko/20100115 Firefox/3.6
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language ru,en-us;q=0.7,en;q=0.3
Accept-Encoding gzip,deflate
Accept-Charset windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive 115
Connection keep-alive
Referer http://readbox.cz/view
Cookie _RssWebApp_session=BAh7CDoPc2Vzc2lvbl9pZCIlMzJhMTQ0ZWZhOGM3YmIwODFhZmFmNjkwYTI1YWQ2ZjQ6EF9jc3JmX3Rva2VuIjEvZHVzdm1NOVlMTUF6bEw3cGRFT2I3RzZvcVJZUU42bCtMNS9PVVYrNHdBPToMdXNlcl9pZGkG--13f1950a9530591881404fbfab7b1246f98f0d81; login=1; APE_Cookie=%7B%22frequency%22%3A11%7D; show-tsl=0
But in Firefox I get an error
!:#8?BC http://readbox.cz (document.domain=http://readbox.cz) >B:070=> 2 #07#5H5=88 =0 ?>;CG5=85 A2>9AB20 HTMLDocument.readyState 87 http://readbox.cz (document.domain =5 1K; CAB0=>2;5=).
[Break on this error] if (doc.readyState && doc.readyState != 'complete') {
In Google Chrome
Unsafe JavaScript attempt to access frame with URL http://readbox.cz/subscriptions/upload_opml from frame with URL http://readbox.cz/view#/posts/all. Domains, protocols and ports must match.
/javascripts/ajaxupload.js?1276107673:574
Uncaught TypeError: Cannot read property 'readyState' of undefined
Domain readbox.info points to 127.0.0.1. It's for development.
I had the same problem and I fix it editing the ajaxupload library, with this commit:
https://github.com/felipelalli/ajax-upload/commit/9307f5eb6ded1ec63eac828a7ef4b8187acb9617
I already sent a pull request to the author.
I had this problem when I was using the sandbox developer environment (opensocial for Orkut). I just check now if "doc" is undefined. The upload works fine, but the callback now has no answer (the answer is undefined).
I don't know exactly what is the cause, but I think it is some kind of limitation of the dev environment.
If you want to download the fix, please check it out: https://github.com/felipelalli/ajax-upload/commits/3.9.1

Resources