Open scripting opened 3 years ago
Good morning! ;-)
I had a few loose-ends to tie off last night when I added the change note about the http.client verb.
Since then, I've --
Fixed a problem in the implementation of the verb when we are not going through the proxy server.
Created a test app to call from scripts, to verify that POST requests work in at least a rudimentary way.
I'd like you to try it out, by adding a command to your Scripts menu. Call it Test HTTP Post.
var theRequest = {
type: "POST",
url: "http://postreceiver.scripting.com/uppercase",
data: "oh give me a home, where the buffalo roam"
};
console.log (http.client (theRequest))
You should see this in the console.
OH GIVE ME A HOME, WHERE THE BUFFALO ROAM
If you ran the script and it worked, please give a thumbs-up to this comment. If you want to share your thoughts, please leave a comment. This is very fluid right now, if you see things that are wrong, now is the time to speak up.
On the other end is an app that handles the post request. It converts the body to uppercase and returns the result.
Here is the source for that app. I have it deployed at postreceiver.scripting.com.
Tried it, yes, it works 👍
On Sat, Nov 6, 2021 at 4:38 PM Dave Winer @.***> wrote:
Good morning! ;-)
I had a few loose-ends to tie off last night when I added the change note about the http.client verb.
Since then, I've --
1.
Fixed a problem in the implementation of the verb when we are not going through the proxy server. 2.
Created a test app to call from scripts, to verify that POST requests work in at least a rudimentary way.
First experiment
I'd like you to try it out, by adding a command to your Scripts menu. Call it Test HTTP Post.
var theRequest = { type: "POST", url: "http://postreceiver.scripting.com/uppercase", data: "oh give me a home, where the buffalo roam" }; console.log (http.client (theRequest))
You should see this in the console.
OH GIVE ME A HOME, WHERE THE BUFFALO ROAM
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/scripting/drummerRFC/issues/6#issuecomment-962468957, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACCHNHNSWGQTWE4LK3SJKLDUKVKZHANCNFSM5HOJVLPQ .
-- Scott Hanson
Email: @.*** Mobile: +49-171-5529568 Johmsweg 9a, 21266 Jesteburg, Germany
Day Job: http://www.mcdonalds-nordheide.de/
@papascott -- when i saw you were calling the ajax routine yourself, i realized i needed to do this verb sooner than later. so your validation being the first is very appropriate. thanks! ;-)
I take it headers haven't been implemented yet? To trigger a GitHub action I need to set an Authorization header. This is what I am trying:
var actionURL = "https://api.github.com/repos/papascott/test-github-actions/actions/workflows/14862978/dispatches"
var theRequest = {
type: "POST",
url: actionURL,
data: JSON.stringify({ref: 'main'}),
headers: {"Authorization": "Bearer "+ root.env.githubToken}
};
console.log (http.client (theRequest))
A dialog shows this message:
Error running script: Can't read the URL, "https://api.github.com/repos/papascott/test-github-actions/actions/workflows/14862978/dispatches" because we received a status code of 403..
This script using XMLHttpRequest does work from the scripts menu: 👍
const xhr = new XMLHttpRequest();
var actionURL = "https://api.github.com/repos/papascott/test-github-actions/actions/workflows/14862978/dispatches"
xhr.open("POST", actionURL);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer '+ root.env.githubToken);
xhr.send(JSON.stringify({ref: 'main'}));
dialog.alert ('Sent hook to GitHub Actions')
@papascott -- that's correct -- headers have not been implemented yet. today is the day. stay tuned. ;-)
@papascott -- reviewing the code, actually headers should work if you're not using the proxy server.
i haven't checked the server code yet, so it might even work there.
after checking the proxy server code, it clearly won't pass the headers along to the proxy server. so for now you should only expect headers to work if you're not the boolean is false for using the proxy server.
http.client copies everything that's in your options struct into the request, so if you have a headers object that should be copied into the request object.
that said i'm having trouble getting it to work with my test case, so there may be something preventing it from working.
I also added some code to http.client to protect any headers that may be added by default in the future.
Here's the actual code.
client: function (options, flUseProxyServer=true) { //11/5/21 by DW
var request = { //defaults
type: "GET",
url: undefined,
data: undefined,
params: undefined,
headers: new Object ()
}
if (options.headers !== undefined) { //11/7/21 by DW
for (var x in options.headers) {
request.headers [x] = options.headers [x];
}
}
for (var x in options) {
if (x != "headers") {
request [x] = options [x];
}
}
if (request.data !== undefined) {
if (!$.isPlainObject (request.data) && (typeof (request.data) != "string")) { //8/2/21 by DW
request.data = request.data.toString ();
}
}
if (request.params !== undefined) {
request.url += "?" + drummerBuildParamList (request.params);
}
if (flUseProxyServer) {
return new Promise (function (resolve, reject) {
var proxyRequest = {
method: request.type,
url: request.url,
body: request.data,
headers: request.headers
};
var jsontext = jsonStringify (proxyRequest);
servercall ("httprequest", {request: jsontext}, true, function (err, data) {
if (err) {
reject (err);
}
else {
resolve (data);
}
});
});
}
else {
return new Promise (function (resolve, reject) {
$.ajax (request)
.success (function (data, status) {
resolve (data);
})
.error (function (status) {
var err = JSON.parse (status.responseText);
reject (err);
});
});
}
}
@papascott -- I just made a change to the http.client so it's now transmitting the headers to the proxy server, and checked the code in the proxy, and it should just pass it through to the Node.js request function. So at this point I think what's in http.client is correct. I will update the code above to reflect what's actually in Drummer right now.
I now believe the problem is with GitHub and not with http.client or the proxy server.
sending the POST request to GitHub non-proxied works as expected 👍
sending the POST request to GitHub proxied fails with Status 403
servercall: url == http://drummer.scripting.com/httprequest?request=%7B%0A%20%20%20%20%22method%22%3A%20%22POST%22%2C%0A%20%20%20%20%22url%22%3A%20%22https%3A%2F%2Fapi.github.com%2Frepos%2Fpapascott%2Ftest-github-actions%2Factions%2Fworkflows%2F14862978%2Fdispatches%22%2C%0A%20%20%20%20%22body%22%3A%20%22%7B%5C%22ref%5C%22%3A%20%5C%22main%5C%22%7D%22%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Authorization%22%3A%20%22Bearer%20xxxxxxxxxxxxxxxxxxxx%22%0A%20%20%20%20%7D%0A%7D&oauth_token=XXXXXXX-XXXXXXXXXXXXXXX&oauth_token_secret=XXXXXXXXXXXXXXXXXXXXX, err.message == Can't read the URL, "https://api.github.com/repos/papascott/test-github-actions/actions/workflows/14862978/dispatches" because we received a status code of 403.
However, with the HttpBin Test API. sending the same request proxied to https://httpbin.org/post, which returns the POST parameters, shows the headers are being sent as expected:
{
"args": {},
"data": "{\"ref\":\"main\"}",
"files": {},
"form": {},
"headers": {
"Authorization": "Bearer someToken",
"Content-Length": "14",
"Host": "httpbin.org",
"X-Amzn-Trace-Id": "Root=1-6188dca6-253a33fc2677d14f015552e9"
},
"json": {
"ref": "main"
},
"origin": "161.35.120.52",
"url": "https://httpbin.org/post"
}
{
"authenticated": true,
"token": "someToken"
}
I found my problem with the GitHub API. 😄 I installed my own instance of appserver and used it to proxy my request. I again got the 403 error, but I was able to see the error message returned in the data:
Request forbidden by administrative rules. Please make sure your request has a User-Agent header (http://developer.github.com/v3/#user-agent-required). Check https://developer.github.com for other possible causes.
(The request package apparently does not include a User-Agent header by default.)
I then added a User-Agent header to my request and the proxied request then succeeded! Drummer reported an error Can't read the URL, "https://api.github.com... because we received a status code of 204.
, but Status 204 is indeed a success (No Content).
@papascott -- incredible sleuthing! Thank you so much for tracking this down.
I see you've posted an issue on appServer, I think I know what it is. I'll respond over there.
@papascott -- do you think http.client should set the user-agent header if it's not already present?
I checked, in Frontier, tcp.httpClient does exactly this. A comment posted on 3/2/99:
Here's the OPML of the source of Frontier's tcp.httpClient for reference.
The change notes are in a comment at the top of the routine.
Update: I made the change adding a User-Agent header which can be overridden by the caller, in http.client.
http://scripting.com/drummer/blog/2021/11/08/142219.html?title=moreWorkOnHttpclient
I tried out the new deployed version in Drummer, my original script (not setting a User-Agent) worked , returning Status 204. No error message.
I'm unable to get this working in Drummer 2.0.19 in Safari on an iPad using the local client. It works OK when I set the Boolean to true to use the proxy server.
console.log( http.client( { url: "http://2005.opml.org/validator/test/encoding.txt" }, false ))
Here's the console output:
runScriptText: processedScriptText == (async function () {await processRunCursorScriptResult(await console.log(await http.client({ url: 'http://2005.opml.org/validator/test/encoding.txt' }, false)), 2);})()
null
when you say you can't get it working, what happens?
I get the console output provided above. It just says "null". No error message, not the contents of the file as when using the proxy server.
Here's the DocServer page for the new verb.