Skip to main content

Querying GitHub Issues from Google App Script

I'm currently exploring different integrations that can be done between Google App Script and Git. This is part of a bigger attempt to integrate Git data into my project management system. I'll post more on that later. GitHub supports a number of very nice sub-systems. One of them is the GitHub Issues ticket tracking system. It's fairly robust and comes with GitHub - which means it's highly integrated out-of-the-box. Integration with Google's App Script is done via the fetchURL command and JSON object manipulation.  After a good bit of experimentation, I've settled on querying GitHub Issues with an "on open spreadsheet event" to avoid issues with Google's quota system. Essentially, Google prevents you from calling the fetchURL command more than X times (see the quota limits ) per day. That's not great if you have people actively working and changing data in a spreadsheet. Some of my other App Script routines are running thousands of times per d

Indy and SSL

If anyone has ever tried to get the OpenSSL libraries to work with Indy, you may have experienced a lot of pain with the process. I'm in the process of trying to develop an application for DHL's ShipIT XML Api that utilizes an HTTPS POST. The actual post code from Indy is easy

response := HTTP.Post(url, file);


but getting the SSL side to work, especial on Vista, is painful. I should disclose here that I have yet to get the HTTPS to send the data correctly via Indy, but I did finally get OpenSSL playing with Indy under Vista.

Basically, the problem stems from the fact that Indy lets you make SSL assignments that will fail at run-time and then provides very little in the way of information about the failure. This is caused by IdSSLOpenSSLHeaders.pas not having any meaningful error reporting on the OpenSSL libraries failing to load. To be clear, it does basically say "Can't load library" but that's it.

To fix it, search on SafeLoadLibrary in IdSSLOpenSSLHeaders.pas. You'll find a section that basically looks like:



{$IFNDEF FPC}
{$IFDEF WIN32_OR_WIN64_OR_WINCE}
if hIdCrypto = 0 then begin
hIdCrypto := SafeLoadLibrary(SSLCLIB_DLL_name);
end;
if hIdSSL = 0 then begin
hIdSSL := SafeLoadLibrary(SSL_DLL_name);
end else begin
Exit;
end;
{$ENDIF}
{$ENDIF}


What is happening here is that hIdCrypto and hIdSSL are attempting to load the OpenSSL DLLs. If this fails, there is no trap to capture the error. I recommend changing the loading to:



{$IFNDEF FPC}
{$IFDEF WIN32_OR_WIN64_OR_WINCE}
if hIdCrypto = 0 then begin
hIdCrypto := SafeLoadLibrary(SSLCLIB_DLL_name);
if hIDCrypto<1 then
Windows.MessageBox(0, pansichar('An error occured loading '+SSLCLIB_DLL_name+#13#10+ErrorDefinition(getLastError)), 'Error',
MB_TASKMODAL+MB_SETFOREGROUND+MB_TOPMOST);
end;
if hIdSSL = 0 then begin
hIdSSL := SafeLoadLibrary(SSL_DLL_name);
if hIDSSL<1 then
Windows.MessageBox(0, pansichar('An error occured loading '+SSL_DLL_name+#13#10+ErrorDefinition(getLastError)), 'Error',
MB_TASKMODAL+MB_SETFOREGROUND+MB_TOPMOST);
end else begin
Exit;
end;
{$ENDIF}
{$ENDIF}


Oh, you'll also need my little cheat routine called ErrorDefinition. It just takes the last Windows error (which you pass, otherwise you couldn't save it if you had some type of log that kept track of the error number and the error message) and converts it to a string. For some reason, I find error #14401 not terribly useful.




function ErrorDefinition(x:longint):string;
var Buffer : array[0..255] of Char;

function TrimWhite(const S : String) : String;
var
i : Integer;
begin
Result := S;
for i := length(Result) downto 1 do
if Result[i] < ' ' then
Result[i] := ' ';
i := pos(' ',Result);
while i <> 0 do begin
delete(Result,i,1);
i := pos(' ',Result);
end;
end;

begin
result:='';
//ask for error message from OS
if FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,abs(x),0,
Buffer,255,nil) > 0 then
Result := TrimWhite(StrPas(Buffer));
end;


Some of you may want to change the MessageBox function over to a raise Exception.Create... but I'll leave that to your discretion. For my purposes, I was just trying to get something that gave more details than "Unable to load". Of course, the next problem is that the error message I got was really unhelpful. In my case, the message says that there is a problem with the SideBySide configuration and to check the event viewer for the application log. Since I have no idea what a SideBySide configuration is, I check the application log to discover this message


"Activation context generation failed for "j:\winprog\main\ssleay32.dll". Dependent Assembly Microsoft.VC90.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.21022.8" could not be found. Please use sxstrace.exe for detailed diagnosis."



Now I'm really confused. I've just installed the OpenSSL libraries via the installer. Just to make sure, I check that the SSL DLLs actually are present in the system32 directory. Just to make sure, I copy them local and still have the problem. I then download the special OpenSSL libraries that are supposed to work better with Indy and have the same results. BTW, I did use the sxstrace tool which is (remarkably) easy to use. The problem is that it points me into the SideBySide directory (c:\windows\winsxs) which doesn't look like it's designed to be edit by people. For those interested, the sxstrace tool output looks like:


"Begin Activation Context Generation.
Input Parameter:
Flags = 0
ProcessorArchitecture = x86
CultureFallBacks = en-US;en
ManifestPath = j:\winprog\main\libeay32.dll
AssemblyDirectory = j:\winprog\main\
Application Config File =
-----------------
INFO: Parsing Manifest File j:\winprog\main\libeay32.dll.
INFO: Manifest Definition Identity is (null).
INFO: Reference: Microsoft.VC90.CRT,processorArchitecture="
x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.21022.8"
INFO: Resolving reference Microsoft.VC90.CRT,processorArchitecture="
x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.21022.8".
INFO: Resolving reference for ProcessorArchitecture x86.
INFO: Resolving reference for culture Neutral.
INFO: Applying Binding Policy.
INFO: No publisher policy found.
INFO: No binding policy redirect found.
INFO: Begin assembly probing.
INFO: Did not find the assembly in WinSxS.
INFO: Attempt to probe manifest at C:\Windows\assembly\GAC_32\Microsoft.VC90.CRT\9.0.21022.8__1fc8b3b9a1e18e3b\Microsoft.VC90.CRT.DLL.
INFO: Attempt to probe manifest at j:\winprog\main\Microsoft.VC90.CRT.DLL.
INFO: Attempt to probe manifest at j:\winprog\main\Microsoft.VC90.CRT.MANIFEST.
INFO: Attempt to probe manifest at j:\winprog\main\Microsoft.VC90.CRT\Microsoft.VC90.CRT.DLL.
INFO: Attempt to probe manifest at j:\winprog\main\Microsoft.VC90.CRT\Microsoft.VC90.CRT.MANIFEST.
INFO: Did not find manifest for culture Neutral.
INFO: End assembly probing.
ERROR: Cannot resolve reference Microsoft.VC90.CRT,processorArchitecture="
x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.21022.8".
ERROR: Activation Context generation failed.
End Activation Context Generation."


At any rate, Google of course tells me that I'm missing the MS VC 9.0 RTL. This is surprising since I have MS VS 2008 installed on this machine but some digging in those folders doesn't turn up the VC90 DLLs (which, just to be fun, are actually named msvc?90.dll). At any rate, I found a link to them on Google Code, download them and put them AND the manifest file in the system32. For those of you who read the sxstrace dump better than I did, I'm sure you won't be surprised to find that this didn't do anything to fix the problem. I then copy the DLL files locally. Still nada. I finally get a clue and copy the DLLs AND the manifest file locally and voila, I can now load the OpenSSL libraries. Of course, I could have put the files and manifest in C:\Windows\assembly\GAC_32\Microsoft.VC90.CRT\9.0.21022.8__1fc8b3b9a1e18e3b\Microsoft.VC90.CRT.DLL (I think), but that folder doesn't really look like it should be adjusted via the command prompt AND I'm probably going to switch away from Indy for this project since the chances of getting this successfully deployed to hundreds of machines just went down a couple of notches.

At any rate, I still haven't figured out the HTTPS Post issue yet. I can post the XML to DHL fine via FF, but the Indy code is corrupting the XML somehow. I'll post again once I get that part figured out and provide the sample code that is so lacking from the Indy project. Don't get me wrong, Indy rocks for what it does, but they could REALLY use a huge set of "for instance" samples. This blog gets 70 hits or so every week just from people looking for hints on the Indy SMTP components that I posted a while back.

Oh, and WHEN did we decided "Unable to load DLL xyz" should be renamed "SideBySide Configuration"? I don't know about you, but the former is much more descriptive than the later.

Comments

Quantium said…
Hi, i've readed your post. Very usefull for me, but i stil have a big problem.

I'd tried to find in IdSSLOpenSSLHeaders.pas this lines:

{$IFNDEF FPC}
{$IFDEF WIN32_OR_WIN64_OR_WINCE}
if hIdCrypto = 0 then begin
hIdCrypto := SafeLoadLibrary(SSLCLIB_DLL_name);
end;
if hIdSSL = 0 then begin
hIdSSL := SafeLoadLibrary(SSL_DLL_name);
end else begin
Exit;
end;
{$ENDIF}
{$ENDIF}

But i can't find it. Im using indy 9.0.18 may be is for that.

¿Can you help me please please?
Marshall Fryman said…
Quantium-

You need to download and use Indy 10 to work with any of the samples I've posted. Make sure you pull the later versions of Indy 10 as the version that shipped even in Delphi 2007 is not up to date.

m

Popular posts from this blog

SMTP Mail and Indy (again)

Having spent a lot of time recently working on a ping scanner using Indy, I noticed that there's a lot of questions still on using SMTP with Indy. Let me first say that I am not an Indy expert. I get along with it successfully but find I still have to research things frequently. With the disclaimer out of the way, we can get to the offering. A while back I wrote a handy little unit to simply send a mail message with or without attachments and with or without providing authentication. It even has support for OpenSSL. I use this unit in a number of applications and have seen it successfully send hundreds of e-mails without issue. I recently added support for threaded message sending to take advantage of the multi-core system I'm now running on. This code has had a few additions (like the logger) that I've gleaned over time from various newsgroup postings, but I didn't record the authors so let me credit the anonymous Internet authors who support Indy. It's really amaz

Detecting a virtualized environment

CubicDesign on delphi-talk.elists.org recently asked the question: "How do I know/detect if my software is running under Windows [or a virtual environment]?" Well, it turns out that it's a lot harder to tell than you would think. Apparently, the VM (VMware, Xen, Wine, etc.) doesn't really want you to be able to do this. At least not easily. For VMware, there is a decent little C routine called jerry.c that does the trick. Jerry actually uses a simple communication channel that VMware left open. It's not 100% foolproof since the admin can change the channel, but that's not likely going to happen unless the system is specifically designed to be a honeypot. If you're running on a honeypot and still have a legitimate reason for detection, you could look at the much more complex scoopy implementation which inspects how the system is actually virtualized using the SIDT CPU instruction instead of a communication channel. Another reference (red pill) is here . F

Delphi Case with Strings

Zarko Gajic posted about this topic on his Delphi Tips recently showing how one could use a case statement with strings. His solution basically passes in an array on the stack and then iterates through it providing the index number of the matching string. I don't often want to do this, but the idea comes up occassionally enough that I thought I'd play with it a little. The first thing that struck me with this is that passing things on the stack is bound to be slow. Any time you can avoid memory allocation in your routines, do it. The way Zarko wrote his StringToCaseSelect routine created a COPY of the information on the stack. In my testing, just changing the CaseList: array of string to CaseList:const array of string improved the performance of the code by almost 30% for his example. Mind, I'm not using hyper-precise counters; however, it definitely makes a difference. Secondly, I was curious how the performance changed if I used the old stand-by: If then else. Using the

Copyright 2008-2022, Marshall Fryman