Visit Our UNIX and Linux User Community


cURL and cgi


 
Thread Tools Search this Thread
Top Forums Programming cURL and cgi
# 1  
Old 08-16-2009
cURL and cgi

I have a CGI application done in c++ that communicates with PayPal. I've had an issue where the application dies when I try to perform a cURL operation. Upon further inspection it seems that I can run cURL examples from the command line.

Upon even further inspection it seems that I can run cURL in the CGI if I don't set the URL option. Any other option seems to be ok. Of course this fails with an error from cURL saying that the URL was not set. But at least I get to the point of an error.

If I set the URL option it either displays a blank white screen at perform, assuming I print the necessary headers, or it fails with premature end of script headers.

So I'm not a unix guru, and I'm kind of in over my head here, but it is what it is. I'm thinking maybe there's a port blocked that's used by the cgi for outgoing requests that isn't used for the command line. I'm thinking maybe it's a permissions thing. The examples were run as root, and I set the .cgi file to be owned by root, but maybe that doesn't count.

I could really use some direction here. And keep in mind my unix knowledge is not phenominal. I can get around alright, but I need a little help.

I'm running red hat and apache.

Thanks,
Brandon
# 2  
Old 08-16-2009
Could you please post your code?
# 3  
Old 08-17-2009
Code

The code is kind of a mess. A lot of things have been tried and commented out. I've tried it using cURLpp and using the standard cURL libraries. Same results.

Code:
//--------------------------------------------------------------------
// Includes
//--------------------------------------------------------------------
#include "verisign_io.h"
#include "file_io.h"
#include "error_lib.h"
#include "logging.h"
#include "toolkit.h"
#include "parm.h"

//using current time in seconds and credit card number for unique transaction id
#include <time.h>
#include <string>
#include <sstream>
#include <iostream>

//#include "curl/curl.h"
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <curlpp/Exception.hpp>

#ifdef CGI_VERSION
        #include "cgic.h"
#endif

//*********************************************************************
// Global Functions
//*********************************************************************

//--------------------------------------------------------------------
// GetValueFromResponseString
//--------------------------------------------------------------------
bool GetValueFromResponseString (const char* key, 
                                                                TString& value, 
                                                                TString responseString)
{
        char*           startPtr        = NULL;
        char*           endPtr          = NULL;
        size_t          offset          = 0;
        size_t          length          = 0;

        value = "";

        startPtr = responseString.Find (key);
        if (startPtr)
        {
                startPtr += strlen(key);
                offset = responseString.PointerToOffset (startPtr);
                endPtr = responseString.Find ("&", true, offset);
                if (endPtr)
                        length = endPtr - startPtr;
                else
                        length = strlen(startPtr);

                value = responseString.SubString(offset,length);
        }

        return (startPtr != NULL);
}

//--------------------------------------------------------------------
// CallVerisign
//--------------------------------------------------------------------
bool CallVerisign (const TDBSplitReport* dbObjPtr,
                                         TString creditCardNumber,
                                         TString expirationDate,
                                         float amount,
                                         TString customerZipCode,
                                         TString customerAddress,
                                         TString authorizationCode,
                                         TString transactionType,
                                         TString comment,
                                         TString& answerText,
                                         TString& referenceID)
{
        bool                    success = false;
        bool                    isTest = false;
        //int                           verisignContext;
        int                             resultCode;
        TString                 localAmount;
        TString                 verisignArgs;
        TString                 responseMessage;
        //TString                       referenceID;
        TString                 tmpString;
        TString                 responseString;
        TString                 logEntry;
        //char                  *responseBuffer;

AddLogEntry(dbObjPtr, "INFO\tVerisign.cc\tAbout to setup environment");

        // Setup the environment so it can find the certificate
        setenv("PFPRO_CERT_PATH", "/usr/local/verisign/payflowpro/linux/certs", 1);

        // Nullify the answer text
        answerText = "";
        // Adjust some arguments
        creditCardNumber.NumbersOnly();
        expirationDate.NumbersOnly();
        customerZipCode.NumbersOnly();
        if (customerZipCode.IsEmpty())
                customerZipCode = "99999";
        customerZipCode = customerZipCode.SubString(0,5);
        if (comment.IsEmpty())
                comment = "---";
        comment = comment.SubString(0,18);
        localAmount.CopyFrom(amount,2);
        // convert expiration from YYYY to MMYY format
        tmpString = expirationDate;
        expirationDate = tmpString.SubString(4,2);
        expirationDate += tmpString.SubString(2,2);

        // setup the log entry
        logEntry = "Verisign Transaction\t";
        logEntry += transactionType;
        logEntry += "\t";
        logEntry += comment;
        logEntry += "\t";
        logEntry += localAmount;
        logEntry += "\t";
        tmpString = creditCardNumber.SubString(0,1);
        tmpString += "-";
        tmpString += creditCardNumber.SubString(0,4,true);
        logEntry += tmpString;
        logEntry += "\t";
        logEntry += expirationDate;
        logEntry += "\t";

AddLogEntry(dbObjPtr, "INFO\tVerisign.cc\tEntering Try");

try{
        if (strcasecmp(creditCardNumber,kTestCreditCardNumber) == 0)
        {
                isTest = true;
                //answerText = kApprovedPrefixString;
                answerText += "987654321";
        }
        else
        {
AddLogEntry(dbObjPtr, "INFO\tVerisign.cc\tNot A Test");
                // Build up the application's piped arguments
                verisignArgs += "TRXTYPE=";
                verisignArgs += transactionType;
                verisignArgs += "&TENDER=C";
                verisignArgs += "&PARTNER=";
                verisignArgs += kVerisignPartner;
                verisignArgs += "&VENDOR=";
                verisignArgs += kVerisignVendor;
                verisignArgs += "&USER=";
                verisignArgs += kVerisignUser;
                verisignArgs += "&PWD=";
                verisignArgs += kVerisignPassword;
                verisignArgs += "&ACCT=";
                verisignArgs += creditCardNumber;
                verisignArgs += "&EXPDATE=";
                verisignArgs += expirationDate;
                verisignArgs += "&AMT=";
                verisignArgs += localAmount;
                verisignArgs += "&COMMENT1[";
                verisignArgs += comment.GetLength();
                verisignArgs += "]=";
                verisignArgs += comment;
                verisignArgs += "&STREET[";
                verisignArgs += customerAddress.GetLength();
                verisignArgs += "]=";
                verisignArgs += customerAddress;
                verisignArgs += "&ZIP=";
                verisignArgs += customerZipCode;
                verisignArgs += "\r\n";
AddLogEntry(dbObjPtr, "INFO\tVerisign.cc\tArgs Set Up");

                //Using credit card number and time in seconds to create unique id
                char uniqueID[64];
                strcpy(uniqueID, creditCardNumber);
                sprintf(uniqueID, "%s%ld", uniqueID, time(NULL));
AddLogEntry(dbObjPtr, "INFO\tVerisign.cc\tBuilt Unique ID");

                //set the headers.
                std::list<std::string> headers;
                headers.push_back("Content-Type: text/namevalue");
                headers.push_back("Content-Length: " + verisignArgs.GetLength());
                headers.push_back("X-VPS-Timeout: 45");
                headers.push_back("X-VPS-Request_ID:" + std::string(uniqueID));

AddLogEntry(dbObjPtr, "INFO\tVerisign.cc\tRest Of Headers Set");

AddLogEntry(dbObjPtr, "INFO\tVerisign.cc\tInit Curl");
                cURLpp::Cleanup myCleanup;
                cURLpp::Easy myRequest;
                myRequest.setOpt(new cURLpp::Options::Url(kVerisignHost));
                myRequest.setOpt(new cURLpp::Options::Port(kVerisignPort));
                myRequest.setOpt(new cURLpp::Options::Timeout(kVerisignTimeout));
                myRequest.setOpt(new cURLpp::Options::Header(1));
                myRequest.setOpt(new cURLpp::Options::FollowLocation(0));
                myRequest.setOpt(new cURLpp::Options::SslVerifyPeer(0));
                myRequest.setOpt(new cURLpp::Options::SslVerifyHost(2));
                myRequest.setOpt(new cURLpp::Options::ForbidReuse(true));
                myRequest.setOpt(new cURLpp::Options::Post(1));
                myRequest.setOpt(new cURLpp::Options::HttpHeader(headers));
                myRequest.setOpt(new cURLpp::Options::PostFields(std::string(verisignArgs)));
                myRequest.setOpt(new cURLpp::Options::UserAgent("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6"));
                //myRequest.setOpt(new cURLpp::Options::Verbose(true));

                std::ostringstream responseBuffer;
//AddLogEntry(dbObjPtr, "INFO\tVerisign.cc\tSet up output stream.  About to perform shorthand version");
                //responseBuffer << myRequest;
                        
                cURLpp::Options::WriteStream ws(&responseBuffer);
                myRequest.setOpt(ws);
AddLogEntry(dbObjPtr, "INFO\tVerisign.cc\tSet up output stream.  About to perform");
//                cout << "Content-type: text/plain" << endl << endl; 
                myRequest.perform();

AddLogEntry(dbObjPtr, "INFO\tVerisign.cc\tPerformed request");
                const char* temp = responseBuffer.str().c_str();
                responseString.CopyFrom(temp);
AddLogEntry(dbObjPtr, "INFO\tVerisign.cc\tSet Response String");

                                if (! responseString.IsEmpty())
                                {
                                        // get the reponse code
                                        if ( GetValueFromResponseString(kVSResponseFieldResult,tmpString, responseString) )
                                        {
                                                resultCode = tmpString.AsSInt();
                                                GetValueFromResponseString(kVSResponseFieldRespMsg,responseMessage, responseString);
                                                GetValueFromResponseString(kVSResponseFieldPnref,referenceID, responseString);

                                                if (resultCode == 0)
                                                {
                                                        // approved
                                                        GetValueFromResponseString(kVSResponseFieldAuthCode, answerText, responseString);
                                                        success = true;
                                                        logEntry += "\tAuthorized";
                                                        logEntry += "\t";
                                                        logEntry += answerText;
                                                        logEntry += "\t";
                                                        logEntry += referenceID;
                                                }
                                                else if (resultCode > 0)
                                                {
                                                        // declined
                                                        answerText += resultCode;
                                                        answerText += ": ";
                                                        answerText += responseMessage;

                                                        logEntry += "\tDeclined";
                                                        logEntry += "\t";
                                                        logEntry += resultCode;
                                                        logEntry += "\t";
                                                        logEntry += referenceID;
                                                        logEntry += "\t";
                                                        logEntry += responseMessage;
                                                }
                                                else
                                                {
                                                        // errror 
                                                        answerText += resultCode;
                                                        answerText += ": ";
                                                        answerText += responseMessage;

                                                        logEntry += "\tDeclined";
                                                        logEntry += "\t";
                                                        logEntry += resultCode;
                                                        logEntry += "\t";
                                                        logEntry += referenceID;
                                                        logEntry += "\t";
                                                        logEntry += responseMessage;
                                                }
                                        }
                                }
                                else
                                {
                                        answerText += "Received empty response from Verisign client.";

                                        logEntry += "\tError";
                                        logEntry += "\t";
                                        logEntry += answerText;
                                }
        }
}
catch( cURLpp::RuntimeError &e){
        logEntry += "\tError\t";
        logEntry += e.what();
        logEntry += "\t";
        AddLogEntry(dbObjPtr, "Runtime Error");
}
catch( cURLpp::LogicError &e ){
        logEntry += "\tError\t";
        logEntry += e.what();
        logEntry += "\t";
 AddLogEntry(dbObjPtr, "Logic Error");
}
catch(...){
        AddLogEntry(dbObjPtr, "General Error");
}

        AddLogEntry(dbObjPtr,logEntry);
        return success;
}



---------- Post updated at 09:10 PM ---------- Previous update was at 09:09 PM ----------

kverisignhost is the paypal payflow link. I've also tried google.com. Doesn't matter what the url is, if I set that option the program dies with no error and no explanation whatsoever.

---------- Post updated 08-17-09 at 10:31 AM ---------- Previous update was 08-16-09 at 09:10 PM ----------

I dumped the ldd info for both testing.cgi and example06. And here's what I got. Definitely something up with the libraries, but I don't know how to fix them.

testing.cgi

libmysqlclient.so.10 => /usr/lib/mysql/libmysqlclient.so.10 (0x4001e000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x40055000)
libpfpro.so => /usr/local/verisign/payflowpro/linux/lib/libpfpro.so (0x40082000)
libcurlpp.so.0 => /usr/lib/libcurlpp.so.0 (0x40128000)
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40152000)
libidn.so.11 => /usr/lib/libidn.so.11 (0x40205000)
libssh2.so.1 => /usr/lib/libssh2.so.1 (0x40236000)
libssl.so.0.9.7 => /usr/lib/libssl.so.0.9.7 (0x40257000)
libcrypto.so.0.9.7 => /usr/lib/libcrypto.so.0.9.7 (0x4028a000)
libldap.so.2 => /usr/lib/libldap.so.2 (0x4038f000)
libgssapi_krb5.so.2 => /usr/kerberos/lib/libgssapi_krb5.so.2 (0x403c1000)
libkrb5.so.3 => /usr/kerberos/lib/libkrb5.so.3 (0x403d4000)
libk5crypto.so.3 => /usr/kerberos/lib/libk5crypto.so.3 (0x40433000)
libz.so.1 => /usr/lib/libz.so.1 (0x40443000)
libm.so.6 => /lib/tls/libm.so.6 (0x40451000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40473000)
libc.so.6 => /lib/tls/libc.so.6 (0x42000000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x4047b000)
libcurl.so.4 => /usr/lib/libcurl.so.4 (0x4048a000)
libnsl.so.1 => /lib/libnsl.so.1 (0x4051c000)
libssl.so.4 => /lib/libssl.so.4 (0x40531000)
libcom_err.so.3 => /usr/kerberos/lib/libcom_err.so.3 (0x40566000)
libresolv.so.2 => /lib/libresolv.so.2 (0x40568000)
libdl.so.2 => /lib/libdl.so.2 (0x4057b000)
liblber.so.2 => /usr/lib/liblber.so.2 (0x4057f000)
libsasl2.so.2 => /usr/lib/libsasl2.so.2 (0x4058b000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

example06

libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x4001e000)
libcurl.so.3 => /usr/local/lib/libcurl.so.3 (0x400d1000)
libssl.so.0.9.7 => /usr/lib/libssl.so.0.9.7 (0x400fe000)
libcrypto.so.0.9.7 => /usr/lib/libcrypto.so.0.9.7 (0x40131000)
libdl.so.2 => /lib/libdl.so.2 (0x40236000)
libz.so.1 => /usr/lib/libz.so.1 (0x4023a000)
libm.so.6 => /lib/tls/libm.so.6 (0x40249000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x4026b000)
libc.so.6 => /lib/tls/libc.so.6 (0x42000000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)



Thanks
# 4  
Old 08-17-2009
Maybe it would be easier to debug if you would add some debug hooks and use a debugger to find out what line of the code is giving problems and why?
# 5  
Old 08-17-2009
I've been dumping log info and it's curl perform() that is causing it to die. Presumably from a linking error. Other than that I'm stuck in command line red hat and don't know how to apply a debugger. I'm kind of out of my element here.
# 6  
Old 08-17-2009
compile it with -ggdb and use the gdb commandline debugging tool to run it. There is some information on gdb here.
# 7  
Old 08-18-2009
I've run the application with strace, and don't see any point where it's failing. But then again, it's a large file and I'm not really sure what I'm looking for.

Previous Thread | Next Thread
Test Your Knowledge in Computers #554
Difficulty: Medium
Using printf() in C, %d formats a decimal variable or literal.
True or False?

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Cgi script please help!

ok so for the project i had to log in amazon node to submitted and create a captcha using cgi scripts its for a unix project this is my amazon node address ss. but first i have to create a .ht access to set the master password. can someone please help me??? in public_html, create a file... (1 Reply)
Discussion started by: jr44
1 Replies

2. Shell Programming and Scripting

CGI Perl : while loop in CGI perl

Hi Team, I am trying to connect to database(succeeded ) and print the records on the browser using while loop. But the elements of array are not displayed instead while loop is displayed directly. Instead of the below I can embed html statements in print but I am looking for the below style as I... (1 Reply)
Discussion started by: scriptscript
1 Replies

3. Shell Programming and Scripting

Perl CGI : unable to download the excel sheet from perl cgi page

Hi All, I have written an cgi perl script that displays an image(Excel image) and when clicked on that Image I need to download a excel sheet. I made sure that excel sheet exists in the folder with the given name but still I am not able to download the sheet. print "<center><table... (2 Replies)
Discussion started by: scriptscript
2 Replies

4. Shell Programming and Scripting

Perl cgi pages out of cgi-bin folder in WINDOWS

Hi team, I have a typical problem with cgi pages in apache webserver in WINDOWS I am able to execute(display) the pages that are saved in cgi-bin folder. But I am not able to execute the pages stored in htdocs or other folder other than cgi-bin folder. Could anyone please let me know how... (1 Reply)
Discussion started by: scriptscript
1 Replies

5. Web Development

problem with exporting vairable from one perl cgi to another perl cgi script while redirecting.

Can anyone tell me how to export a variable from one perl CGI script to another perl cgi script when using a redirect. Upon running the login.pl the user is prompted to enter user name and password. Upon entering the correct credentials (admin/admin) the user is redirected to welcome page. My... (3 Replies)
Discussion started by: Arun_Linux
3 Replies

6. Shell Programming and Scripting

CGI shell script curl reponse problem

Hi, I am running a bash shell script for some simple web server CGI, the script runs as expected from the browser except the following: curl --silent --max-time 10 --output /dev/null --write-out %{http_code} http://server:port/filename This line outputs 404 when i execute the script... (0 Replies)
Discussion started by: Moxy
0 Replies

7. Web Development

Need help with cgi and so on

Hello all, i`m new here and new in programming with cgi. But i need it for my running project. I`ve googled half a week with no success. All i need is to run an .sh-file via cgi. My file is stored in /home/bots/ but if i try #!/bin/sh echo 'Content-type: text/html' echo echo... (5 Replies)
Discussion started by: cryp0r
5 Replies

8. Solaris

apache ErrorDocument 400 /cgi-bin/400.cgi

Hi All, Sorry if the question is trivial for you but, I am new to Apache (2.0.63) and am trying to figure out how to display my 400.cgi. Here is what I have in httpd.conf servername testing DocumentRoot "/usr/local/apache2/htdocs" ErrorDocument 400 /cgi-bin/badrequest-400.cgi Here is... (0 Replies)
Discussion started by: afadaghi
0 Replies

9. Shell Programming and Scripting

CGI passing arrays/hashes to another CGI script

If I have a Perl CGI script (script01), which fills an array(s) with information and outputs a HTML page with a link to another CGI page (script02); is there anyway to pass the array(s) from "script01" to "script02" when the page visitor clicks the link? Hope that makes sense! :) (2 Replies)
Discussion started by: WIntellect
2 Replies

10. Shell Programming and Scripting

cgi

I am having trouble running my perl cgi on the Internet. After i put the cgi file into the public_html directory and try to browse it on the internet, it returns me the exact content of the cgi file. Is the file permission 755 for the cgi file correct? My path to perl is something like ... (2 Replies)
Discussion started by: vince
2 Replies

Featured Tech Videos