Example #1
0
PRIVATE int parseSubOption(char* line, char **option, char **param) {
  const char *subopt_delim = "=>";
  uint32_t i = 0;

  *option = NULL;
  *param  = NULL;

  assert(line && *line);

  while(line[i] != '\0') {
    if(line[i] == subopt_delim[0] && line[i+1] == subopt_delim[1]) {
      *option = am_strndup(line, i-1);
      *param  = trim(line + i + strlen(subopt_delim));
      break;
    }

    i++;
  }
  
  return (*option && *param) ? SUCCESS : FAILURE;
}
Example #2
0
PRIVATE suboption_t* parseSubOption(char* line) {
  const char *subopt_delim = "=>";
  uint32_t i = 0;

  suboption_t* option_item = NULL;
  char *option = NULL;
  char *param  = NULL;

  assert(line && *line);

  while(line[i] != '\0') {
    if(line[i] == subopt_delim[0] && line[i+1] == subopt_delim[1]) {
      if(i >1) {
        option = am_strndup(line, i-1);
        param  = trim(line + i + strlen(subopt_delim));
      } else {
        dbg_printf(P_ERROR, "Error: Suboption '%s' is malformed!", line);
      }

      break;
    }

    i++;
  }

  if(option && param) {
    option_item = (suboption_t*)am_malloc(sizeof(suboption_t));
    option_item->option = option;
    option_item->value = param;
  }

  if(!option_item) {
    dbg_printf(P_ERROR, "Error parsing suboption from input string '%s')", line);
    am_free(option);
    am_free(param);
  }

  return option_item;
}
Example #3
0
/* http://stackoverflow.com/questions/122616/how-do-i-trim-leading-trailing-whitespace-in-a-standard-way */
PRIVATE char* trim(const char *str) {
  const char *end;

  if(!str || !*str) {
    return NULL;
  }

  // Trim leading space
  while(isspace(*str)) {
    str++;
  }

  if(*str == 0)  // All spaces?
  {
    return NULL;
  }

  /* skip single or double quote */
  if (*str == '"' || *str == '\'') {
    str++;
  }

  // Trim trailing space
  end = str + strlen(str) - 1;
  while(end > str && isspace(*end)) {
    end--;
  }

  /* skip single or double quote */
  if (*end == '"' || *end == '\'') {
    end--;
  }

  end++;

  // Return copy of trimmed string
  return am_strndup(str, end - str);
}
Example #4
0
PRIVATE size_t parse_Transmission_response(void *ptr, size_t size, size_t nmemb, void *data) {
  size_t        line_len = size * nmemb;
  const char   *line = ptr;
  WebData      *mem = data;
  const char   *session_key = "X-Transmission-Session-Id: ";
  const size_t  key_len = strlen( session_key );
  char         *tmp = NULL;
  int           content_length = 0;

  if( (line_len >= key_len) && !memcmp(line, session_key, key_len) ) {
      const char * begin = line + key_len;
      const char * end = begin;
      while( !isspace( *end ) ) {
        ++end;
      }

      am_free( gSessionID );
      gSessionID = NULL;
      gSessionID = am_strndup( begin, end-begin );
  /* parse header for Content-Length to allocate correct size for data->response->data */
  } else if(line_len >= 15 && !memcmp(line, "Content-Length:", 15)) {
    tmp = getRegExMatch("Content-Length:\\s(\\d+)", line, 1);
    if(tmp != NULL) {
      dbg_printf(P_INFO2, "Content-Length: %s", tmp);
      content_length = atoi(tmp);
      if(content_length > 0) {
        mem->content_length = content_length;
        mem->response->buffer_size = content_length + 1;
        mem->response->data = am_realloc(mem->response->data, mem->response->buffer_size);
      }

      am_free(tmp);
    }
  }

  return line_len;
}
Example #5
0
/** \brief Upload data to a specified URL.
*
* \param url Path to where data shall be uploaded
* \param auth (Optional) authentication information in the form of "user:password"
* \param data Data that shall be uploaded
* \param data_size size of the data
* \return Web server response
*/
PUBLIC HTTPResponse* sendHTTPData(const char *url, const char* auth, const void *data, uint32_t data_size) {
  CURL *curl_handle = NULL;
  CURLcode res;
  long rc, tries = 2, len;
  WebData* response_data = NULL;
  HTTPResponse* resp = NULL;
  char sessionKey[MAXLEN];

  struct curl_slist * headers = NULL;

  if( !url || !data ) {
    return NULL;
  }

  response_data = WebData_new(url);

  do {
    --tries;
    WebData_clear(response_data);

    if( curl_handle == NULL) {
      if(gbGlobalInitDone == FALSE) {
        curl_global_init(CURL_GLOBAL_ALL);
        gbGlobalInitDone = TRUE;
      }
      if( ( curl_handle = am_curl_init(auth, TRUE) ) ) {
        curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, response_data);
        curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, response_data);
        //Transmission-specific options for HTTP POST
        if(strstr(response_data->url, "transmission") != NULL) {
          curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, parse_Transmission_response );
          headers = curl_slist_append(headers, "Content-Type: application/json");

          if( gSessionID ) {
            if((len = snprintf(sessionKey, MAXLEN, "X-Transmission-Session-Id: %s", gSessionID)) > 0) {
              sessionKey[len] = '\0';
            }

            headers = curl_slist_append(headers, sessionKey);
          }
          curl_easy_setopt( curl_handle, CURLOPT_HTTPHEADER, headers );
        }
        curl_easy_setopt(curl_handle, CURLOPT_URL, response_data->url);
      } else {
        dbg_printf(P_ERROR, "am_curl_init() failed");
        break;
      }
    }

    curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, data);
    curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, data_size);

    if( ( res = curl_easy_perform(curl_handle) ) ) {
      dbg_printf(P_ERROR, "Upload to '%s' failed: %s", url, curl_easy_strerror(res));
      break;
    } else {
      curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &rc);
      dbg_printf(P_INFO2, "response code: %ld", rc);
      if(rc == 409) {
        if(gSessionID) {
          dbg_printf(P_DBG, "Error code 409, session ID: %s", gSessionID);
        } else {
          dbg_printf(P_ERROR, "Error code 409, no session ID");
        }

        closeCURLSession( curl_handle );
        curl_slist_free_all( headers );
        headers = NULL;
        curl_handle = NULL;
      } else {
        resp = HTTPResponse_new();
        curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &resp->responseCode);

        //copy data if present
        if(response_data->response->data) {
          resp->size = response_data->response->buffer_pos;
          resp->data = am_strndup(response_data->response->data, resp->size);
        }
        //copy filename if present
        if(response_data->content_filename) {
          resp->content_filename = am_strdup(response_data->content_filename);
        }
        break;
      }
    }
  } while(tries > 0);

  /* cleanup */
  closeCURLSession(curl_handle);

  if(headers) {
    curl_slist_free_all(headers);
  }

  WebData_free(response_data);

  return resp;
}
Example #6
0
PUBLIC HTTPResponse* getHTTPData(const char *url, const char *cookies, CURL ** curl_session) {
  CURLcode      res;
  CURL         *curl_handle = NULL;
  CURL         *session = *curl_session;
  char         *escaped_url = NULL;
  WebData      *data = NULL;
  HTTPResponse *resp = NULL;
  long          responseCode = -1;

  if(!url) {
    return NULL;
  }

  data = WebData_new(url);

  if(!data) {
    return NULL;
  }

  dbg_printf(P_INFO2, "[getHTTPData] url=%s, curl_session=%p", url, (void*)session);
  if(session == NULL) {
    if(gbGlobalInitDone == FALSE) {
      curl_global_init(CURL_GLOBAL_ALL);
      gbGlobalInitDone = TRUE;
    }
    session = am_curl_init(NULL, FALSE);
    *curl_session = session;
  }

  curl_handle = session;

  if(curl_handle) {
    escaped_url = url_encode_whitespace(url);
    assert(escaped_url);
    curl_easy_setopt(curl_handle, CURLOPT_URL, escaped_url);
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, data);
    curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, data);

    if(cookies && *cookies) {
      /* if there's an explicit cookie string, use it */
      curl_easy_setopt(curl_handle, CURLOPT_COOKIE, cookies);
    } else {
      /* otherwise, enable cookie-handling since there might be cookies defined within the URL */
      curl_easy_setopt(curl_handle, CURLOPT_COOKIEFILE, "");
    }

    res = curl_easy_perform(curl_handle);
    /* curl_easy_cleanup(curl_handle); */
    curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &responseCode);
    dbg_printf(P_INFO2, "[getHTTPData] response code: %d", responseCode);
    if(res != 0) {
        dbg_printf(P_ERROR, "[getHTTPData] '%s': %s (retval: %d)", url, curl_easy_strerror(res), res);
    } else {
      /* Only the very first connection attempt (where curl_session == NULL) should store the session,
      ** and only the last one should close the session.
      */
      resp = HTTPResponse_new();
      resp->responseCode = responseCode;
      //copy data if present
      if(data->response->data) {
        resp->size = data->response->buffer_pos;
        resp->data = am_strndup(data->response->data, resp->size);
      }
      //copy filename if present
      if(data->content_filename) {
        resp->content_filename = am_strdup(data->content_filename);
      }
    }
    am_free(escaped_url);
  } else {
    dbg_printf(P_ERROR, "curl_handle is uninitialized!");
    resp = NULL;
  }
  WebData_free(data);
  return resp;
}