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; }
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); }
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; }
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); }
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 (); }