Example #1
0
/**
 * Parse an XML string into a nested list.
 * The second parameter indicates if body text (text within XML tags)
 * should show up among the children of the tag or in its own
 * section.
 *
 * See documentation (ext-xml.README) for examples.
 */
static package 
parse_xml(const char *data, int bool_stream)
  {
  /*
   * FIXME: Feed expat smaller chunks of the string and 
   * check for task timeout between chunks
   *
   */
  int decoded_length;
  const char *decoded;
  package result; 
  XML_Parser parser = XML_ParserCreate(NULL);
  XMLdata *root = new_node(NULL, "");
  XMLdata *child = root;
  
  decoded_length = strlen(data);
  decoded = data;
  XML_SetUserData(parser, &child);
  XML_SetElementHandler(parser, xml_startElement, xml_endElement);
  if(bool_stream) {
    XML_SetCharacterDataHandler(parser, xml_streamCharacterDataHandler);
  } else {
    XML_SetCharacterDataHandler(parser, xml_characterDataHandler);
  }
  if (!XML_Parse(parser, decoded, decoded_length, 1)) {
    Var r;
    r.type = TYPE_INT;
    r.v.num = XML_GetCurrentByteIndex(parser);
    flush_nodes(child);
    result = make_raise_pack(E_INVARG, 
			     XML_ErrorString(XML_GetErrorCode(parser)),
			     r);
  } else {
    finish_node(root);
    result = make_var_pack(var_ref(root->element.v.list[4].v.list[1]));
    free_node(root);
  }
  XML_ParserFree(parser);
  return result; 
}
Example #2
0
static package bf_http_request( Var arglist, Byte next, void *vdata, Objid progr)
{
  CURL *curl_handle;
  CURLcode ok;
  package result;
  if (!is_wizard(progr))
  {
    free_var(arglist);
    return make_error_pack(E_PERM);
  }
  int nargs = arglist.v.list[0].v.num;
  const char *address = arglist.v.list[1].v.str;
  const char *agent="",*postfields="",*cookies="";
  int headers = 0;
  switch(nargs)
  {
    case 5:
        cookies = arglist.v.list[5].v.str;
    case 4:
	postfields = arglist.v.list[4].v.str;
    case 3:
	agent = arglist.v.list[3].v.str;
    case 2:
	headers = arglist.v.list[2].v.num;
  }
  if(!strlen(agent))
    agent = "MOO-http/1.0";
  const char delimiters[] = "\n";
  free_var(arglist);

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0;

  curl_global_init(CURL_GLOBAL_ALL);

  curl_handle = curl_easy_init();
  curl_easy_setopt(curl_handle, CURLOPT_URL, address);
  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, agent);
  curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 5);
  curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, 3);
  curl_easy_setopt(curl_handle, CURLOPT_FTP_RESPONSE_TIMEOUT, 3);
  curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 5);
  curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
  curl_easy_setopt(curl_handle, CURLOPT_MAXFILESIZE, 1048576);
  if(strlen(postfields))
    curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, postfields);
  if(strlen(cookies))
    curl_easy_setopt(curl_handle, CURLOPT_COOKIE, cookies);
  if(headers)
    curl_easy_setopt(curl_handle, CURLOPT_HEADER, 1);
  ok = curl_easy_perform(curl_handle);
  curl_easy_cleanup(curl_handle);

  if(ok == CURLE_OK && strlen(chunk.memory) != chunk.size)
    ok = CURLE_BAD_CONTENT_ENCODING;   // binary !!!

  if(ok == CURLE_OK)
  {
    char *token,*p=chunk.memory;
    Var r;
    r.type = TYPE_LIST;
    r = new_list(0);
    token = strsep(&p, delimiters);
    while( token != NULL )
    {
	Var line;
	line.type = TYPE_STR;
	if(token[strlen(token)-1] == '\r')
	    token[strlen(token)-1] = '\0';
	//run it through utf8_substr to get rid of invalid utf8
	line.v.str = (char *)utf8_substr(token,1,utf8_strlen(token));
	r = listappend(r, var_dup(line));
	token = strsep(&p, delimiters);
	free_var(line);
    }
    result = make_var_pack(r);
  }
  else
  {
    Var r;
    r.type = TYPE_INT;
    r.v.num = ok;
    result = make_raise_pack(E_INVARG,
			curl_easy_strerror(ok),
			r);
  }

  if(chunk.memory)
    free(chunk.memory);
    
  curl_global_cleanup();
  
  return result;
}