The Community Forums

Interact with an entire community of cPanel & WHM users!
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

JSON API - Empty Pages ~50% Of The Time

Discussion in 'cPanel Developers' started by azoundria, May 24, 2011.

  1. azoundria

    azoundria Member

    Joined:
    Apr 28, 2007
    Messages:
    10
    Likes Received:
    0
    Trophy Points:
    1
    My code uses file_get_contents to access the API URLs using this format as an example:

    http://user:pass@ip.ip.ip.ip:2086/json-api/limitbw?user=xxx&bwlimit=###

    Due to the firewall blocking external IPs from directly accessing the WHM on some servers, I had to institute a proxy.

    My main code accesses a URL on the server, which in turn accesses the JSON API (both via file_get_contents). The data is then tested to see if it's empty or not, before being passed on for processing. In all cases, the requested actions seem to happen, however the output is blank approximately 50% of the time. The problem with a blank page is that I have no idea if the operation was successful, and using other commands to check statuses will also return blank pages some of the time.

    Does anyone have any idea what might cause blank pages to be returned? Is it a problem with PHP prematurely returning output before the load is complete? What can I do about this to make things more reliable?
     
    #1 azoundria, May 24, 2011
    Last edited: May 24, 2011
  2. azoundria

    azoundria Member

    Joined:
    Apr 28, 2007
    Messages:
    10
    Likes Received:
    0
    Trophy Points:
    1
    Now the most frustrating part is that it seems to work fine 99.57% of the time now (based on about 270 tests and more still underway). So I don't know what changed - maybe the server is less busy now, maybe it's because the code to do this is firmly locked in RAM making it faster. I'm really not sure.
     
  3. cPanelDavidN

    cPanelDavidN Integration Developer
    Staff Member

    Joined:
    Dec 17, 2009
    Messages:
    571
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    Hi azoundria,

    I'm not sure what to tell you about your blank page. In my experience a blank page is generally served when a) the script has a fatal error or an error that is unmanaged, and b) the error reporting is suppressed (which, in general, is what you want in a production environment). I'm not sure how that plays out in your scenario, especially if (as I understand it) there's actually two scripts that must be executed to access one cPanel API call.

    I do have one suggestion for you based on your example URL. You are passing the credentials in the URL, which technically works, but is not what we recommend...especially on an insecure port. Typically, we like to see API requests pass their credentials in the HTTP header. Which brings me to another suggestion: you should take a look at our PHP XML-API client class or the PHP PublicAPI client class [beta]. These client classes provide a handful of methods that make sending a cPanel API request a breeze. They can use cURL or fopen functions for the HTTP request. The PHP XML-API client has many examples in the forum; and YES this class can do JSON...the default is XML, just invokce set_output('json') on your object. I think you'll like it, but if it doesn't fit your needs, no sweat...you can at least glean the HTTP header logic from it.

    Sorry I couldn't provide more help -
    Best Regards,
    -DavidN
     
  4. azoundria

    azoundria Member

    Joined:
    Apr 28, 2007
    Messages:
    10
    Likes Received:
    0
    Trophy Points:
    1
    I did further testing.

    Instead of echoing the value of the file_get_contents, I store it in a variable. If file_get_contents fails, that should be false. However, I've confirmed that it is in fact not false and equivalent to '' (an empty string).

    Obviously, I will need to replace my file_get_contents with something else. I don't want to install a huge set of classes, just pass in the variables that change. What is the recommended way to access the JSON API?
     
  5. cPanelDavidN

    cPanelDavidN Integration Developer
    Staff Member

    Joined:
    Dec 17, 2009
    Messages:
    571
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    We usually recommend the cURL functions over the fopen functions because cURL seems to report error in a more definitive way. That said, a large number of hosting providers do not offer cURL in their Apache-used PHP binary. So you may be stuck with using fopen/file_get_contents and stream wrappers. With proper error handling, you should be able to avoid ambiguity in the query result (ie, checking the return value, like you mention in your last post) so long as it's a non-fatal situation.

    The PHP XML-API client class is your best option. It's a single, rather simple class. Here's how it would work for your example of the limitbw function:

    PHP:
    <?php
    include "xmlapi.php";

    // Instantiate
    $ip "10.1.1.1";
    $xmlapi = new xmlapi($ip);

    // Authenticate
    $authUser 'reseller';
    $authPass "resellerSecret";
    $xmlapi->password_auth($authUser$authPass);

    // Object Setup
    $xmlapi->set_output('json');   // query methods will now return a JSON string
    //$xmlapi->set_port(2087);     // or 2086; 2083/2082 for non-reseller/root
    //$xmlapi->set_debug(1);       // for debugging to error_log

    // Query specific variables
    $userToModify 'dave';        // "reseller" owns "dave"
    $newBwLimit '100';           // value in Megabytes

    // Make the query
    $xmlapi->limitbw($userToModify$newBwLimit);
    ?>
    Like I said before, you can rip out the important stuff (like setting authentication headers) and just use what you want or you can use the class as is.

    Regards,
    -DavidN
     
  6. azoundria

    azoundria Member

    Joined:
    Apr 28, 2007
    Messages:
    10
    Likes Received:
    0
    Trophy Points:
    1
    Part of the challenge is that I can't predict the configuration of a node in the network. So far, I've stated allow_url_fopen as a requirement. However, I do believe at least one of our servers disables CURL. So the end solution needs to be flexible. I haven't read much on how your classes handle different server configurations.

    Second, the bulk of the 'brains' need to be on the main website since this makes it easier to debug problems. If there are failure-points on the node itself, it's more difficult to track them. Alternatives for sending error reports include trying to send mail from the nodes (which sometimes get spam filtered or fail to send), or logging internally within the nodes, which then all have to be checked by some kind of automated script periodically. This is not nearly as helpful and reliable as having all the errors reported with the main website itself.

    Finally, many of the nodes block external IP access, while the majority block it on failed login attempts. Since the passwords sometimes get out of sync (largely due to this same 'empty-page' bug when changing the password) then the main server gets blocked, and that's a real pain to sort through (plus the system to access that node is down in the meantime).

    I don't really want to have a giant switch construct, because that will require updating the code on every server any time anything changes with any command, or we decide to allow a new command. Plus, it's a lot of code and that means errors are more likely to occur. I'm sure there is a way I could just pass in the API function and parameters, where it would use CURL or fallback to file_get_contents if that failed.

    For now, I think I'll just have it resend the request if the input is empty, and add that solution as an alternative if things continue to be problematic.
     
Loading...

Share This Page