Example #1
0
int ZDMHttpEx::get(const QString &url, QDataStream &out) {
    CURLcode r;
    CURL *curl;
    DBG("get <%s>\n", qPrintable(url));
    _isPost = false;

    curl = curl_easy_init();
    if(curl == NULL) {
        r = CURLE_FAILED_INIT;
        emit signal_result(_arg, false, tr("HTTP GET CURLE=%1").arg(r));
        return r;
    }

    char *cstr_url = strdup(url.toLocal8Bit().data());
    curl_easy_setopt(curl, CURLOPT_URL, cstr_url);
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);

    curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
    curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, curl_prog_func);
    curl_easy_setopt(curl, CURLOPT_XFERINFODATA, this);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_func);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&out);

    r = curl_easy_perform(curl);
    DBG("curl get returns %d\n", r);
    curl_easy_cleanup(curl);
    free(cstr_url);

    emit signal_result(_arg, r == 0, tr("HTTP GET CURLE=%1").arg(r));
    return r;
}
Example #2
0
int ZDMHttpEx::postFile(const QString &url, const QString &path, QDataStream &out) {
    CURLcode r;
    CURL *curl;
    DBG("postFile <%s>\n", qPrintable(url));
    _isPost = true;

    QFileInfo info(path);
    FILE *fp = fopen(path.toLocal8Bit().data(), "rb");
    if(fp == NULL) {
        DBG("open file failed!\n");
        emit signal_result(_arg, false, tr("HTTP POST_FILE CURLE='open file failed'"));
        return -1;
    }

    curl = curl_easy_init();
    if(curl == NULL) {
        r = CURLE_FAILED_INIT;
        emit signal_result(_arg, false, tr("HTTP POST_FILE CURLE=%1").arg(r));
        return r;
    }

    char *cstr_url = strdup(url.toLocal8Bit().data());
    curl_easy_setopt(curl, CURLOPT_URL, cstr_url);
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);

    curl_slist *list = NULL;
    list = curl_slist_append(list, QString("Content-Length: %1").arg(info.size()).toLocal8Bit().data());
    list = curl_slist_append(list, "Content-Type: application/octet-stream");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);

    curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
    curl_easy_setopt(curl, CURLOPT_POST, 1);

    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
    curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, curl_prog_func);
    curl_easy_setopt(curl, CURLOPT_XFERINFODATA, this);

    curl_easy_setopt(curl, CURLOPT_READFUNCTION, curl_read_file);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_func);
    curl_easy_setopt(curl, CURLOPT_READDATA, fp);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&out);

    r = curl_easy_perform(curl);
    DBG("curl post returns %d\n", r);
    curl_easy_cleanup(curl);
    curl_slist_free_all(list);
    fclose(fp);
    free(cstr_url);

    emit signal_result(_arg, r == 0, tr("HTTP POST_FILE CURLE=%1").arg(r));
    return r;
}
/**
 * Handle STOP-message.
 *
 * @param cls closure (always NULL)
 * @param client identification of the client
 * @param message the actual message
 * @return GNUNET_OK to keep the connection open,
 *         GNUNET_SYSERR to close it (signal serious error)
 */
static void
handle_stop (void *cls, struct GNUNET_SERVER_Client *client,
	     const struct GNUNET_MessageHeader *message)
{
  struct ServiceList *sl;
  const char *servicename;
  uint16_t size;

  size = ntohs (message->size);
  size -= sizeof (struct GNUNET_MessageHeader);
  servicename = (const char *) &message[1];
  if ((size == 0) || (servicename[size - 1] != '\0'))
    {
      GNUNET_break (0);
      GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
      return;
    }
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
	      _("Preparing to stop `%s'\n"), servicename);
  sl = find_service (servicename);
  if (sl == NULL)
    {
      signal_result (client, servicename, GNUNET_ARM_PROCESS_UNKNOWN);
      return;
    }
  sl->is_default = GNUNET_NO;
  if (GNUNET_YES == in_shutdown)
    {
      /* shutdown in progress */
      signal_result (client, servicename, GNUNET_ARM_PROCESS_SHUTDOWN);
      return;
    }
  if (sl->killing_client != NULL)
    {
      /* killing already in progress */
      signal_result (client, servicename,
		     GNUNET_ARM_PROCESS_ALREADY_STOPPING);
      return;
    }
  if (sl->proc == NULL)
    {
      /* process is down */
      signal_result (client, servicename, GNUNET_ARM_PROCESS_ALREADY_DOWN);
      return;
    }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Sending kill signal to service `%s', waiting for process to die.\n",
	      servicename);
  sl->killed_at = GNUNET_TIME_absolute_get ();
  if (0 != GNUNET_OS_process_kill (sl->proc, SIGTERM))
    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
  sl->killing_client = client;
  GNUNET_SERVER_client_keep (client);
}
Example #4
0
int ZDMHttpEx::getContentLength(const QString& url, long &resp_code, qint64 &content_length) {
    CURLcode r;
    CURL *curl;
    _isPost = false;

    curl = curl_easy_init();
    if(curl == NULL) {
        r = CURLE_FAILED_INIT;
        emit signal_result(_arg, false, tr("HTTP GET CONTENT_LENGTH CURLE=%1").arg(r));
        return r;
    }

    char *cstr_url = strdup(url.toLocal8Bit().data());
    curl_easy_setopt(curl, CURLOPT_URL, cstr_url);
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
    curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
    do {
        if((r = curl_easy_perform(curl)) != CURLE_OK) {
            DBG("curl_easy_perform r=%d\n", r);
            break;
        }

        if((r = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &resp_code)) != CURLE_OK) {
            break;
        }
        DBG("http code: %ld\n", resp_code);
        if(resp_code < 200 || resp_code > 299) {
            r = CURLE_RECV_ERROR;
            break;
        }

        double d_size;
        if((r = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d_size)) != CURLE_OK) {
            r = CURLE_RECV_ERROR;
            break;
        }
        DBG("fetched remote size: %f\n", d_size);
        content_length = d_size;
    } while(0);
    curl_easy_cleanup(curl);
    free(cstr_url);

    emit signal_result(_arg, r == 0, tr("HTTP GET CONTENT_LENGTH CURLE=%1").arg(r));
    return r;
}
Example #5
0
int ZDMHttpEx::getFile(const QString &url, const QString &path) {
    int ret = -1;
    QFile f(path);
    if(!f.open(QIODevice::WriteOnly)) {
        DBG("open file failed!\n");
        emit signal_result(_arg, false, tr("HTTP GET_FILE CURLE='open file failed'"));
        return -1;
    }

    QDataStream stream(&f);
    ret = get(url, stream);
    f.close();
    return ret;
}
/**
 * Handle START-message.
 *
 * @param cls closure (always NULL)
 * @param client identification of the client
 * @param message the actual message
 * @return GNUNET_OK to keep the connection open,
 *         GNUNET_SYSERR to close it (signal serious error)
 */
static void
handle_start (void *cls, struct GNUNET_SERVER_Client *client,
	      const struct GNUNET_MessageHeader *message)
{
  const char *servicename;
  struct ServiceList *sl;
  uint16_t size;
  
  size = ntohs (message->size);
  size -= sizeof (struct GNUNET_MessageHeader);
  servicename = (const char *) &message[1];
  if ((size == 0) || (servicename[size - 1] != '\0'))
    {
      GNUNET_break (0);
      GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
      return;
    }
  if (GNUNET_YES == in_shutdown)
    {
      signal_result (client, servicename, GNUNET_ARM_PROCESS_SHUTDOWN);
      return;
    }
  sl = find_service (servicename);
  if (NULL == sl)
    {
      signal_result (client, servicename, GNUNET_ARM_PROCESS_UNKNOWN);
      return;
    }
  sl->is_default = GNUNET_YES;
  if (sl->proc != NULL)
    {
      signal_result (client, servicename, GNUNET_ARM_PROCESS_ALREADY_RUNNING);
      return;
    }
  start_process (sl);
  signal_result (client, servicename, GNUNET_ARM_PROCESS_STARTING);
}
Example #7
0
int ZDMHttpEx::postData(const QString &url, QByteArray &in, QStringList &headers, QByteArray &out) {
    QDataStream ins(&in, QIODevice::ReadOnly);
    QDataStream ous(&out, QIODevice::WriteOnly);

    CURLcode r;
    CURL *curl;
    DBG("post <%s>\n", url);
    _isPost = true;

    curl = curl_easy_init();
    if(curl == NULL) {
        r = CURLE_FAILED_INIT;
        emit signal_result(_arg, false, tr("HTTP POST_DATA CURLE=%1").arg(r));
        return r;
    }

    curl_slist *hlist = NULL;
    foreach(const QString& h, headers) {
        hlist = curl_slist_append(hlist, h.toLocal8Bit().data());
    }
/**
 * Task triggered whenever we receive a SIGCHLD (child
 * process died).
 *
 * @param cls closure, NULL if we need to self-restart
 * @param tc context
 */
static void
maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct ServiceList *pos;
  struct ServiceList *next;
  struct ServiceListeningInfo *sli;
  const char *statstr;
  int statcode;
  int ret;
  char c[16];
  enum GNUNET_OS_ProcessStatusType statusType;
  unsigned long statusCode;
  const struct GNUNET_DISK_FileHandle *pr;

  pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
  child_death_task = GNUNET_SCHEDULER_NO_TASK;
  if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
    {
      /* shutdown scheduled us, ignore! */
      child_death_task =
	GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
					pr, &maint_child_death, NULL);
      return;
    }
  /* consume the signal */
  GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c)));

  /* check for services that died (WAITPID) */
  next = running_head;
  while (NULL != (pos = next))
    {
      next = pos->next;

      if (pos->proc == NULL)
      {
	if (GNUNET_YES == in_shutdown)
	  free_service (pos);
	continue;
      }
      if ((GNUNET_SYSERR ==
	   (ret =
	    GNUNET_OS_process_status (pos->proc, &statusType, &statusCode)))
	  || ((ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED)
	      || (statusType == GNUNET_OS_PROCESS_RUNNING)))
	continue;
      if (statusType == GNUNET_OS_PROCESS_EXITED)
      {
	statstr = _( /* process termination method */ "exit");
	statcode = statusCode;
      }
      else if (statusType == GNUNET_OS_PROCESS_SIGNALED)
      {
	statstr = _( /* process termination method */ "signal");
	statcode = statusCode;
      }
      else
      {
	statstr = _( /* process termination method */ "unknown");
	statcode = 0;
      }
      if (0 != pos->killed_at.abs_value)
      {
	GNUNET_log (GNUNET_ERROR_TYPE_INFO,
		    _("Service `%s' took %llu ms to terminate\n"),
		    pos->name,
		    GNUNET_TIME_absolute_get_duration (pos->killed_at).rel_value);
      }
      GNUNET_OS_process_destroy (pos->proc);
      pos->proc = NULL;
      if (NULL != pos->killing_client)
	{
	  signal_result (pos->killing_client, pos->name,
			 GNUNET_ARM_PROCESS_DOWN);
	  GNUNET_SERVER_client_drop (pos->killing_client);
	  pos->killing_client = NULL;
	  /* process can still be re-started on-demand, ensure it is re-started if there is demand */
	  for (sli = pos->listen_head; NULL != sli; sli = sli->next)
	    {
	      GNUNET_break (GNUNET_SCHEDULER_NO_TASK == sli->accept_task);
	      sli->accept_task =
		GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
					       sli->listen_socket,
					       &accept_connection, sli);
	    }
	  continue;
	}
      if (GNUNET_YES != in_shutdown)
	{
	  if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0))
	    {
	      /* process terminated normally, allow restart at any time */
	      pos->restart_at.abs_value = 0;
	    }
          else
            {
	      if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
	        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
			    _
			    ("Service `%s' terminated with status %s/%d, will restart in %llu ms\n"),
			    pos->name, statstr, statcode, pos->backoff.rel_value);
	      /* schedule restart */
	      pos->restart_at = GNUNET_TIME_relative_to_absolute (pos->backoff);
	      pos->backoff =
	        GNUNET_TIME_relative_min (EXPONENTIAL_BACKOFF_THRESHOLD,
				          GNUNET_TIME_relative_multiply
				          (pos->backoff, 2));
            }
	  if (GNUNET_SCHEDULER_NO_TASK != child_restart_task)
	    GNUNET_SCHEDULER_cancel (child_restart_task);
	  child_restart_task =
	    GNUNET_SCHEDULER_add_with_priority
	    (GNUNET_SCHEDULER_PRIORITY_IDLE, 
	     &delayed_restart_task, NULL);
	}
      else
	{
	  free_service (pos);
	}
    }
  child_death_task =
    GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
				    pr, &maint_child_death, NULL);
  if ((NULL == running_head) && (GNUNET_YES == in_shutdown))
    do_shutdown ();
}