Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERROR: xmlReadMemory failed (src/messages.c:1905) #122

Open
rajeshPerumala opened this issue Jun 27, 2016 · 5 comments
Open

ERROR: xmlReadMemory failed (src/messages.c:1905) #122

rajeshPerumala opened this issue Jun 27, 2016 · 5 comments

Comments

@rajeshPerumala
Copy link

rajeshPerumala commented Jun 27, 2016

Hi sir,
I'm trying to use libcurl as rest API in rpc callback function to call Rest server on Tomcat server. But i get the xmlrReadMemory failed (src/message.c:1905). The error is the const char *data in nc_reply_data_ns(data, data_ns) is failing. This is my code

nc_reply* rest_ping(char* ipaddr) {
                char url[100];
                struct string s;
                CURL *curl;
                CURLcode res;
                init_string(&s);
                memset(url,0,100);
                nc_reply* reply = NULL;
                curl = curl_easy_init();
                sprintf(url,"http://192.168.1.8:8080/PingIP/webapi/ping/%s",ipaddr);
                if(curl) {
                        curl_easy_setopt(curl, CURLOPT_URL, url);
                        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L);
                        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
                        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
        res = curl_easy_perform(curl);
            if(CURLE_OK == res) {
              char *ct;
              /* ask for the content-type */
              res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
              if((CURLE_OK == res) && ct && strcmp(ct,"application/xml") == 0) {
                                                reply = nc_reply_data_ns(s.ptr,"http://com/sdn-mon/connectivity");
                                }else {
                                                reply = nc_reply_data_ns("<result>FAIL</result>","http://com/sdn-mon/connectivity");
                                }
            }else {
                                        reply = nc_reply_data_ns("<result>FAIL</result>","http://com/sdn-mon/connectivity");
                        }
        curl_easy_cleanup(curl);
  }else {
                        reply = nc_reply_data_ns("<result>FAIL</result>","http://com/sdn-mon/connectivity");
        }
        return reply;
}

The whole rpc call back function is:

struct string s{
  char *ptr;
  size_t len;
 };


void init_string(struct string *s) {
  s->len = 0;
  s->ptr = malloc(s->len+1);
  if (s->ptr == NULL) {
    fprintf(stderr, "malloc() failed\n");
    exit(EXIT_FAILURE);
  }
  s->ptr[0] = '\0';
}

static size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)
{
  size_t new_len = s->len + size * nmemb;
  s->ptr = realloc(s->ptr, new_len + 1);
  if (s->ptr == NULL) {
    fprintf(stderr, "realloc() failed\n");
    exit(EXIT_FAILURE);
  }
  memcpy(s->ptr+s->len, ptr, size * nmemb);
  s->ptr[new_len]='\0';
  s->len = new_len;

  return size*nmemb;
}

nc_reply* rest_ping(char* ipaddr) {
                char url[100];
                struct string s;
                CURL *curl;
                CURLcode res;
                init_string(&s);
       memset(url,0,100);
                nc_reply* reply = NULL;
                curl = curl_easy_init();
                sprintf(url,"http://192.168.1.8:8080/PingIP/webapi/ping/%s",ipaddr);
                if(curl) {
                        curl_easy_setopt(curl, CURLOPT_URL, url);
                        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L);
                        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
                        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
        res = curl_easy_perform(curl);
            if(CURLE_OK == res) {
              char *ct;
              /* ask for the content-type */
              res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);

              if((CURLE_OK == res) && ct && strcmp(ct,"application/xml") == 0) {
                                                reply = nc_reply_data_ns(s.ptr,"http://com/att/sdn-mon/connectivity");
                                }else {
                                                reply = nc_reply_data_ns("<result>FAIL</result>","http://com/sdn-mon/connectivity");
                                }
            }else {
                                        reply = nc_reply_data_ns("<result>FAIL</result>","http://com/sdn-mon/connectivity");
                        }
        curl_easy_cleanup(curl);
  }else {
                        reply = nc_reply_data_ns("<result>FAIL</result>","http://com/sdn-mon/connectivity");
        }
        return reply;
}

int isValidIpAddress(char *ipaddr)
{
    struct sockaddr_in sa;
    int result = inet_pton(AF_INET, ipaddr, &(sa.sin_addr));
    return result != 0;
}

nc_reply *rpc_ping_test(xmlNodePtr input) {
        int ret = -1;
        nc_reply* data = NULL;
        xmlNodePtr dip = get_rpc_node("destination-ip",input);
        char * dest_addr = (char*)xmlNodeGetContent(dip);
        if(dest_addr != NULL && isValidIpAddress(dest_addr)) {
                return rest_ping(dest_addr);
        }else {
                return nc_reply_data_ns("<result>FAIL</result>","http://com/sdn-mon/connectivity");
        }
}

Is there any way to check the contents of struct string s which is passed as the char* data to nc_reply_data_ns function. Please also guide me in finding the leak in the code.
Note: I can see the response xml back from the rest service using winshark packet capture.

@michalvasko
Copy link
Member

Hi,
I would suggest you simply add a print of s.ptr before reply = nc_reply_data_ns(s.ptr,"http://com/sdn-mon/connectivity");. That way you should see what exactly is passed to the function and why it is wrong.

Regards,
Michal

PS: If you have some leaks, just use valgrind and you should find them easily.

@rajeshPerumala
Copy link
Author

Thank you Michal. I would like to know few basic things

  1. Does the .c with transapi call back functions have an main method and from where is it called?
  2. If i use printf statement for s.ptr where does it print? because i don't see in printed on console or log file.
    Please explain me this basic things.

Thanks
Rajesh

@michalvasko
Copy link
Member

Hi Rajesh,

  1. No, it does not have any main(). There are mainly callbacks for specific schema node path changes and they are called accordingly (when that patch changes somehow).
  2. I think you should see it in the console unless you redirected stdout somewhere else. Anyway, the safest way is to use our logging functions. To see it always, just use ERROR(), it has the exact same syntax as printf().

Regards,
Michal

@rajeshPerumala
Copy link
Author

Thank you for the information. Coming to my issue of xmlreadmemory, the
nc_reply_data_ns function is not able to read the char* variable which
stores the xml response from the rest service. Any other way to pass the
data to the function?

On Jun 29, 2016 2:24 AM, "michalvasko" [email protected] wrote:

Hi Rajesh,

  1. No, it does not have any main(). There are mainly callbacks for
    specific schema node path changes and they are called accordingly (when
    that patch changes somehow).
  2. I think you should see it in the console unless you redirected
    stdout somewhere else. Anyway, the safest way is to use our logging
    functions. To see it always, just use ERROR(), it has the exact same
    syntax as printf().

Regards,
Michal


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#122 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AS4m7Q2jlQil1f_aXRFrS7lstmdrkkJGks5qQg-4gaJpZM4I_P5C
.

@michalvasko
Copy link
Member

What do you mean it is not able to read? There is no other way how to pass the data. If it requires some special kind of reading, then you must do it yourself and then pass a full string (with the data) to the function.

Regards,
Michal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants