401 Errors with AddAContact.php Example

DaveBerard
Moderator

401 Errors with AddAContact.php Example

We have taken many reports of developers having a hard time upgrading to Basic over HTTPS using the sample PHP code.  Here is a breakdown of how to update your code.  We have updated this post with new information based on our extensive testing of curl and php versions and servers. For more detailed information on these limitations, please see the end of this documentation.


 


There are 6 changes which need to be made to our old sample script (AddAContact.php and Contact.php) in order to make it work over Basic Authentication with HTTPS.  The changes are as follows:

 




In both files,


Change: curl_setopt($session, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);


To: curl_setopt($session, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);


 


 


AddAContact.php:line 75


Change From: $request =  "http://api.constantcontact.com/ws/customers/".CC_USERNAME."/contacts";


To: $request =  "https://api.constantcontact.com/ws/customers/".CC_USERNAME."/contacts";


 


 


Contact.php:line 81


Change From: $request =  "http://api.constantcontact.com/ws/customers/".$this->user_name."/lists";


To: $request =  "https://api.constantcontact.com/ws/customers/".$this->user_name."/lists";


 


 


If you are still experiencing connectivity issues after these changes you may need to also do the following:


 


In both files,


Add the code: curl_setopt($session, CURLOPT_SSL_VERIFYPEER, 0);


Before: $response = curl_exec($session);


 




We have released a new and updated PHP example, as well as a new and udpated C#.NET example, here.  These examples have been tested on multiple hosting platforms and are a great way to get started using our most updated API techniques.


 


We have found that if a server is not configured to automatically update their CA certificate cache or is using an older version of curl, the SSL Certificate verification process will fail.  By using these additional settings, it will bypass the certificate authentication process.


 


Please note, this will only bypass certificate authentication for the Constant Contact API usage and is not a global setting on your servers.  If you are able to fix your issues by making these changes to the certificate verification, this means that your server configuration is not set to automatically update your CA certificates used by curl to verify SSL connections.  This is not something Constant Contact can assist with changing, this issue should be brought back to your web hosting service or your web admin for further trouble shooting.


 


For more information on this issue, please see this article on the curl developer site on the limitations on the default curl CA certificate verification process.  This is in no way related to the Constant Contact API but to an actual limitation of the way curl verifies SSL certificates.  We apologize for the confusion regarding this and the amount of time it took to find this limitation. 

Dave Berard
Senior Product Manager, Constant Contact
21 REPLIES 21
ronchan
Regular Participant

Made the changes you outlined and it worked once but not again. I tried the same script on two different servers (two different clients) and got back the following:


Error Encountered!

There was an error trying to connect to the server.

Please go BACK and try again later.


and on the other one:


System Error Encountered!

Error

could not find valid list with the name generalinterest


Same exact script but with different accounts, usenames, passwords, keys.


Very strange that they would have different error messages??

DaveBerard
Moderator

We have updated this post with new information based on our extensive testing of curl and php versions and servers.  We have found that if a server is not configured to automatically update their CA certificate cache or is using an older version of curl, the SSL Certificate verification process will fail.  By using these additional settings, it will bypass the certificate authentication process.


 


Please note, this will only bypass certificate authentication for the Constant Contact API usage and is not a global setting on your servers.  If you are able to fix your issues by making these changes to the certificate verification, this means that your server configuration is not set to automatically update your CA certificates used by curl to verify SSL connections.  This is not something Constant Contact can assist with changing, this issue should be brought back to your web hosting service or your web admin for further trouble shooting.


 


For more information on this issue, please see this article on the curl developer site on the limitations on the default curl CA certificate verification process.  This is in no way related to the Constant Contact API but to an actual limitation of the way curl verifies SSL certificates.  We apologize for the confusion regarding this and the amount of time it took to find this limitation.  

Dave Berard
Senior Product Manager, Constant Contact
ronchan
Regular Participant

Hi Dave,


Thanks for your hard work on this. Considering all the discrepencies (some work some don't) this makes sense. Luckily the clients that I have little control over their server configuration (ie. GoDaddy) seem to have updating the CS certificate enabled by default. My other clients are asking their hosting services about it right now - hopefully this will not be a big deal for them. I'll let you know how it goes.

ike turner
Regular Participant

These changes worked for me. I did not have to use the last one. I use godaddy.

awaterson
Regular Participant

This is the error I received.


Warning: curl_setopt(): supplied argument is not a valid cURL handle resource in /home/citysp5/public_html/instore/Contact.php on line 99


I've been in contact with my hosting company and they didn't really know what to make of changing the server configuration.  They use linux servers... inmotionhosting.com.


 

DaveBerard
Moderator

What is line 99 on your Contact.php file.  If you can give us that line, we can look in the php documentation to see what version of php/curl is required for the option to work.  There are many options that are not available in early versions of php 5.

Dave Berard
Senior Product Manager, Constant Contact
awaterson
Regular Participant

Here is the php from contact.php line 99 is in bold   line 99 = (curl_setopt($session, CURLOPT_SSL_VERIFYPEER, 0);)


// Set up Basic authentication - username and password.

        $userNamePassword = $this->api_key."%".$this->user_name.":".$this->password;

        if (empty($this->api_key) || empty($this->user_name) || empty($this->password)) {

            $this->err_message  .= '<br />Missing or invalid user name or password or api key.';

            error_log(date('Y-m-d H:i:s') .

                               ' Error invlid user name or password or api key '.

                               "\n", 3, $this->log_file_name);           

        }

        curl_setopt($session, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

        curl_setopt($session, CURLOPT_USERPWD, $userNamePassword);

        curl_setopt($session, CURLOPT_FOLLOWLOCATION  ,1);

        curl_setopt($session, CURLOPT_GET, 1);

        curl_setopt($session, CURLOPT_HTTPHEADER, Array("Content-Type:application/atom+xml"));

        curl_setopt($session, CURLOPT_HEADER, 0);   // Do not return headers

        //don't send the response to browser

                 curl_setopt($session, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($session, CURLOPT_SSL_VERIFYPEER, 0);

        $response = curl_exec($session);

        curl_close($session);

DaveBerard
Moderator

I have confirmed that that is a valid option for all versions of php 5.X.X.  The only limitation to that option is that it is not valid for any versions of curl prior to 7.10.  If you are using a version priot to 7.10 (it's worth noting that curl is now on 7.19.5), this would explain both your failure for sending information over SSL (curl 7.10 would have certificates that are over 3 years old by default) and why you can not use this option (it is not available in your version of curl).  


 


I would contact your web host to go over your version of curl, version of php and whether or not they have set up their server to run a cron job to update your CA certificates folder in curl for you.  

Dave Berard
Senior Product Manager, Constant Contact
islandwriter
Regular Participant

I had the same problem earlier, then went to the php docs and found that the variable in the statement curl_setopt($session, CURLOPT_SSL_VERIFYPEER, 0); must be the resource that was created with the curl_init call.  In a previous post, the instructions said to use $ch, not $session.  I changed to $session and that problem went away.  Now I just have a error trying to connect to the server.  I'm using Network Solutions for this client (their choice, not mine) and the curl version is libcurl/7.15.1 OpenSSL/0.9.8f zlib/1.2.3 .  Any suggestions?


Here's the code for the connection:


       $request =  "https://api.constantcontact.com/ws/customers/".CC_USERNAME."/contacts";

       $session = curl_init($request);

       // Set up Basic authentication - username and password.

       $userNamePassword = CC_APIKEY."%".CC_USERNAME.":".CC_PASSWORD;

       curl_setopt($session, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

       curl_setopt($session, CURLOPT_USERPWD, $userNamePassword);

       curl_setopt($session, CURLOPT_FOLLOWLOCATION  ,1);

       curl_setopt($session, CURLOPT_POST, 1);

       curl_setopt($session, CURLOPT_POSTFIELDS , $entry);

       curl_setopt($session, CURLOPT_HTTPHEADER, Array("Content-Type:application/atom+xml"));

       curl_setopt($session, CURLOPT_HEADER, 0);   // Do not return headers

       curl_setopt($session, CURLOPT_RETURNTRANSFER, 1);

       curl_setopt ($session, CURLOPT_SSL_VERIFYPEER, 0);

       $response = curl_exec($session);

       curl_close($session);

awaterson
Regular Participant

Dave,


Our host version of PHP version5.2.9


Curl is 7.15.5


I'm asking about the cron job to update CA certificates...


 

DaveBerard
Moderator

I apologize for the variable naming convention changing.  This was a copy/paste oversite on my part.  I've updated the text in the post and hopefully this will clear up some of the confusion.

Dave Berard
Senior Product Manager, Constant Contact
islandwriter
Regular Participant

I tried outputting the curl results with curl_getinfo and found out that I'm receiving a http_code of 409, which is indicated to be "Conflict."  Can I post or send info to help diagnose this problem?

barretr
Regular Participant

Same problem, not getting a response. Adding curl_setopt($session, CURLOPT_SSL_VERIFYPEER, FALSE) or curl_setopt($session, CURLOPT_PORT,443) didn't work either.


 


CURL_GETINFO returns a 409 with following code(PHP 5.25 & cURL 7.10.6 through GoDaddy). Not sure what I'm missing:


 


 


$request = "https://api.constantcontact.com/ws/customers/" . CC_USERNAME . "/contacts";

$session = curl_init($request);

// Set up Basic authentication - username and password.

$userNamePassword = CC_APIKEY . "%" . CC_USERNAME . ":" . CC_PASSWORD;

curl_setopt($session, CURLOPT_USERPWD, $userNamePassword);

curl_setopt($session, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

curl_setopt($session, CURLOPT_SSL_VERIFYPEER, FALSE);

curl_setopt($session, CURLOPT_SSL_VERIFYHOST, FALSE);

curl_setopt($session, CURLOPT_FOLLOWLOCATION, TRUE);

curl_setopt($session, CURLOPT_POST, TRUE);

curl_setopt($session, CURLOPT_POSTFIELDS, $entry);

curl_setopt($session, CURLOPT_HTTPHEADER, Array("Content-Type:application/atom+xml"));

curl_setopt($session, CURLOPT_HEADER, FALSE); // Do not return headers

curl_setopt($session, CURLOPT_RETURNTRANSFER, TRUE);



$response = curl_exec($session);

curl_close($session);

DaveBerard
Moderator

GoDaddy set up has the most updated CA certificates automatically pushed to PHP files, you won't need to add the CURLOPT_SSL_VERIFYPERR, FALSE setting to your request.


 


Regarding the 409 error, that means there is some type of conflict.  Either you're trying to create a contact who already exists (we define contacts by unique email address) or you are trying to change someone's information to something that doesn't logically make sense (I.E. State of MA and Country of CA, Massachusetts can't be in Canada).  


 


I would recommend checking the request type (are you doing a create when you should be doing an update?) or the data in your XML.  These are the most common causes of 409 errors.

Dave Berard
Senior Product Manager, Constant Contact
ChrisWeber
Regular Participant

I'm trying to connect using the new Basic Auth over SSL and I'm getting connection errors back in my log file:


 


"Error attempting to connect via curl to https://api.constantcontact.com/ws/customers/<myusername>/contacts"


 


currently my AddAContact.php includes this code to perform the curl connection:


 


       curl_setopt($session, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

       curl_setopt($session, CURLOPT_PORT,443);

       curl_setopt($session, CURLOPT_USERPWD, $userNamePassword);

       curl_setopt($session, CURLOPT_FOLLOWLOCATION  ,1);

       curl_setopt($session, CURLOPT_POST, 1);

       curl_setopt($session, CURLOPT_POSTFIELDS , $entry);

       curl_setopt($session, CURLOPT_HTTPHEADER, Array("Content-Type:application/atom+xml"));

       curl_setopt($session, CURLOPT_HEADER, 0);   // Do not return headers

       curl_setopt($session, CURLOPT_RETURNTRANSFER, 1);

       curl_setopt($session, CURLOPT_SSL_VERIFYPEER, FALSE);


 


Can you tell me what I'm doing wrong?


 


PS: To get his out of the way, my $request is :


 


$request =  "https://api.constantcontact.com/ws/customers/".CC_USERNAME."/contacts";


 


And my Contact.php includes:


        curl_setopt($session, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

        curl_setopt($session, CURLOPT_USERPWD, $userNamePassword);

#        curl_setopt($session, CURLOPT_GET, 1);

#        curl_setopt($session, CURLOPT_POST, 1);

        curl_setopt($session, CURLOPT_PORT,443);

        curl_setopt($session, CURLOPT_FOLLOWLOCATION  ,1);

        curl_setopt($session, CURLOPT_HTTPHEADER, Array("Content-Type:application/atom+xml"));

        curl_setopt($session, CURLOPT_HEADER, 0);   // Do not return headers

        //don't send the response to browser

                 curl_setopt($session, CURLOPT_RETURNTRANSFER, 1);

                 curl_setopt($session, CURLOPT_SSL_VERIFYPEER, FALSE);                 

        $response = curl_exec($session);


 


AND


 


$request =  "https://api.constantcontact.com/ws/customers/".$this->user_name."/lists";


 


I even redirected my new suscribers to a newly created list called General to make sure I didn't have errors caused by having a space in my mailing list destination.

DaveBerard
Moderator

Chris,


 


Do you have the error code or message or response that you are receiving?  Have you tried echoing the $response or using the curl_error option? 

Dave Berard
Senior Product Manager, Constant Contact
barretr
Regular Participant

Thanks Dave. I guess it's not so much of a connectivity issue, as curl_getinfo($session) returns the 409. After reading your note about 409 responses in this thread: http://developer.constantcontact.com/node/640, I think I see the light.

ChrisWeber
Regular Participant

Yesterday, I decided to incorporate the newest reference example of the php code.  I eventually got that work after I synced all the variable names and formats.  So I'm not sure what I was doing wrong.  However, I gained some benefit from your suggestions.  I was able to resolve the remaining problems I had with the new code by output the resultant xml to a file for analysis.  Thank you for that.


 


By the way, I like the newest reference example better than the previous one.  It's a lot cleaner and reminded me that I was doing somethings in my code the hard / complicated way.  I also like the ability to do more than just adding a contant to a list.  It only took me an hour or two to incorporate and debug, and considering it was probably going to take me that long to fix the old code, I consider it time well spent.


 


Please see my post about the syntax bug in doServerCall: "curl_setopt($ch, CURLOPT_GET, 1)" should be "curl_setopt($ch, CURLOPT_HTTPGET, 1)".  link: http://developer.constantcontact.com/node/662

DaveBerard
Moderator

Thanks Chris,


 


I'm glad you like the new sample better, we had very specific goals in mind when that was put together.  We are looking into the setopt issue you brought to our attention.  Thanks for pointing it out!

Dave Berard
Senior Product Manager, Constant Contact
thatpatguy
Participant

first off.. let me thank everyone for the hard work that was put into this fix specifically.  Back in August my client came to me reporting an error when they tried to sign up for a newsletter.  I quickly determined that it was this issue and the info in this post allowed me to be the hero and quickly resolve the error.


I just received another email today and the error is back.  I've double checked AddAContact.php and Contact.php to make sure that the files weren't over written or anything and all the changes are still there so I'm surprised this error is back.


Unforunately I'm not only a php newb, but I'm a 100% server novice, so this discussion of curl and CA certificate caches and such are completely over my head.


I'm assuming that since my post is the first one since August, that this issue hasn't come back for others here. I would appreciate it any help and/or feedback I can get to try and figure this out.


Obviously if I left any important information to help with debugging let me know and I'll post it up.  Thanks in advance everyone.

Developer Portal

View API documentation, code samples, get your API key.

Visit Page